Skip to content

Commit 09041c4

Browse files
committed
Convert functional tests to pytest
1 parent e836f35 commit 09041c4

11 files changed

+99
-117
lines changed

tests/functional/docs/__init__.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616
class BaseDocsFunctionalTests(unittest.TestCase):
1717
def assert_contains_lines_in_order(self, lines, contents):
1818
for line in lines:
19-
self.assertIn(line, contents)
19+
assert line in contents
2020
beginning = contents.find(line)
2121
contents = contents[(beginning + len(line)):]
2222

2323
def get_class_document_block(self, class_name, contents):
2424
start_class_document = '.. py:class:: %s' % class_name
2525
start_index = contents.find(start_class_document)
26-
self.assertNotEqual(start_index, -1, 'Class is not found in contents')
26+
assert start_index != -1, 'Class is not found in contents'
2727
contents = contents[start_index:]
2828
end_index = contents.find(
2929
' .. py:class::', len(start_class_document))
@@ -32,7 +32,7 @@ def get_class_document_block(self, class_name, contents):
3232
def get_method_document_block(self, method_name, contents):
3333
start_method_document = ' .. py:method:: %s(' % method_name
3434
start_index = contents.find(start_method_document)
35-
self.assertNotEqual(start_index, -1, 'Method is not found in contents')
35+
assert start_index != -1, 'Method is not found in contents'
3636
contents = contents[start_index:]
3737
end_index = contents.find(
3838
' .. py:method::', len(start_method_document))
@@ -41,8 +41,7 @@ def get_method_document_block(self, method_name, contents):
4141
def get_request_syntax_document_block(self, contents):
4242
start_marker = '**Request Syntax**'
4343
start_index = contents.find(start_marker)
44-
self.assertNotEqual(
45-
start_index, -1, 'There is no request syntax section')
44+
assert start_index != -1, 'There is no request syntax section'
4645
contents = contents[start_index:]
4746
end_index = contents.find(
4847
':type', len(start_marker))
@@ -51,8 +50,7 @@ def get_request_syntax_document_block(self, contents):
5150
def get_response_syntax_document_block(self, contents):
5251
start_marker = '**Response Syntax**'
5352
start_index = contents.find(start_marker)
54-
self.assertNotEqual(
55-
start_index, -1, 'There is no response syntax section')
53+
assert start_index != -1, 'There is no response syntax section'
5654
contents = contents[start_index:]
5755
end_index = contents.find(
5856
'**Response Structure**', len(start_marker))
@@ -61,19 +59,19 @@ def get_response_syntax_document_block(self, contents):
6159
def get_request_parameter_document_block(self, param_name, contents):
6260
start_param_document = ':type %s:' % param_name
6361
start_index = contents.find(start_param_document)
64-
self.assertNotEqual(start_index, -1, 'Param is not found in contents')
62+
assert start_index != -1, 'Param is not found in contents'
6563
contents = contents[start_index:]
6664
end_index = contents.find(':type', len(start_param_document))
6765
return contents[:end_index]
6866

6967
def get_response_parameter_document_block(self, param_name, contents):
7068
start_param_document = '**Response Structure**'
7169
start_index = contents.find(start_param_document)
72-
self.assertNotEqual(start_index, -1, 'There is no response structure')
70+
assert start_index != -1, 'There is no response structure'
7371

7472
start_param_document = '- **%s**' % param_name
7573
start_index = contents.find(start_param_document)
76-
self.assertNotEqual(start_index, -1, 'Param is not found in contents')
74+
assert start_index != -1, 'Param is not found in contents'
7775
contents = contents[start_index:]
7876
end_index = contents.find('- **', len(start_param_document))
7977
return contents[:end_index]

tests/functional/dynamodb/test_stubber_conditions.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_table_query_can_be_stubbed_with_expressions(self):
4141
response = table.query(KeyConditionExpression=key_expr,
4242
FilterExpression=filter_expr)
4343

44-
self.assertEqual(list(), response['Items'])
44+
assert response['Items'] == []
4545
stubber.assert_no_pending_responses()
4646

4747
def test_table_scan_can_be_stubbed_with_expressions(self):
@@ -59,5 +59,5 @@ def test_table_scan_can_be_stubbed_with_expressions(self):
5959
with stubber:
6060
response = table.scan(FilterExpression=filter_expr)
6161

62-
self.assertEqual(list(), response['Items'])
62+
assert response['Items'] == []
6363
stubber.assert_no_pending_responses()

tests/functional/dynamodb/test_table.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def setUp(self):
2525

2626
def test_resource_has_batch_writer_added(self):
2727
table = self.resource.Table('mytable')
28-
self.assertTrue(hasattr(table, 'batch_writer'))
28+
assert hasattr(table, 'batch_writer')
2929

3030
def test_operation_without_output(self):
3131
table = self.resource.Table('mytable')

tests/functional/test_collection.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ def setUp(self):
2525
self.ec2_resource = self.session.resource('ec2')
2626

2727
def test_can_use_collection_methods(self):
28-
self.assertIsInstance(
29-
self.ec2_resource.instances.all(), ResourceCollection)
28+
assert isinstance(self.ec2_resource.instances.all(), ResourceCollection)
3029

3130
def test_can_chain_methods(self):
32-
self.assertIsInstance(
31+
assert isinstance(
3332
self.ec2_resource.instances.all().page_size(5), ResourceCollection)

tests/functional/test_dynamodb.py

+12-14
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,12 @@ def test_resource(self):
4343
table.scan(FilterExpression=Attr('mykey').eq('myvalue'))
4444
request = self.make_request_mock.call_args_list[0][0][1]
4545
request_params = json.loads(request['body'].decode('utf-8'))
46-
self.assertEqual(
47-
request_params,
48-
{'TableName': 'MyTable',
49-
'FilterExpression': '#n0 = :v0',
50-
'ExpressionAttributeNames': {'#n0': 'mykey'},
51-
'ExpressionAttributeValues': {':v0': {'S': 'myvalue'}}}
52-
)
46+
assert request_params == {
47+
'TableName': 'MyTable',
48+
'FilterExpression': '#n0 = :v0',
49+
'ExpressionAttributeNames': {'#n0': 'mykey'},
50+
'ExpressionAttributeValues': {':v0': {'S': 'myvalue'}}
51+
}
5352

5453
def test_client(self):
5554
dynamodb = self.session.client('dynamodb')
@@ -62,10 +61,9 @@ def test_client(self):
6261
)
6362
request = self.make_request_mock.call_args_list[0][0][1]
6463
request_params = json.loads(request['body'].decode('utf-8'))
65-
self.assertEqual(
66-
request_params,
67-
{'TableName': 'MyTable',
68-
'FilterExpression': '#n0 = :v0',
69-
'ExpressionAttributeNames': {'#n0': 'mykey'},
70-
'ExpressionAttributeValues': {':v0': {'S': 'myvalue'}}}
71-
)
64+
assert request_params == {
65+
'TableName': 'MyTable',
66+
'FilterExpression': '#n0 = :v0',
67+
'ExpressionAttributeNames': {'#n0': 'mykey'},
68+
'ExpressionAttributeValues': {':v0': {'S': 'myvalue'}}
69+
}

tests/functional/test_ec2.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,15 @@ def setUp(self):
2323
self.instance_resource = self.service_resource.Instance('i-abc123')
2424

2525
def test_delete_tags_injected(self):
26-
self.assertTrue(hasattr(self.instance_resource, 'delete_tags'),
27-
'delete_tags was not injected onto Instance resource.')
26+
assert hasattr(self.instance_resource, 'delete_tags')
2827

2928
def test_delete_tags(self):
3029
stubber = Stubber(self.instance_resource.meta.client)
3130
stubber.add_response('delete_tags', {})
3231
stubber.activate()
3332
response = self.instance_resource.delete_tags(Tags=[{'Key': 'foo'}])
3433
stubber.assert_no_pending_responses()
35-
self.assertEqual(response, {})
34+
assert response == {}
3635
stubber.deactivate()
3736

3837
def test_mutating_filters(self):

tests/functional/test_resource.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13+
import pytest
14+
1315
import boto3
1416
from boto3.exceptions import ResourceNotExistsError
1517

@@ -35,21 +37,19 @@ def test_can_inject_method_onto_resource(self):
3537
self.botocore_session.register('creating-resource-class.s3',
3638
self.add_new_method(name='my_method'))
3739
resource = session.resource('s3')
38-
self.assertTrue(hasattr(resource, 'my_method'))
39-
self.assertEqual(resource.my_method('anything'), 'anything')
40+
assert hasattr(resource, 'my_method')
41+
assert resource.my_method('anything') == 'anything'
4042

4143

4244
class TestSessionErrorMessages(unittest.TestCase):
4345
def test_has_good_error_message_when_no_resource(self):
4446
bad_resource_name = 'doesnotexist'
45-
err_regex = (
46-
'%s.*resource does not exist.' % bad_resource_name
47-
)
48-
with self.assertRaisesRegex(ResourceNotExistsError, err_regex):
47+
err_regex = f'{bad_resource_name}.*resource does not exist.'
48+
with pytest.raises(ResourceNotExistsError, match=err_regex):
4949
boto3.resource(bad_resource_name)
5050

5151

5252
class TestGetAvailableSubresources(unittest.TestCase):
5353
def test_s3_available_subresources_exists(self):
5454
s3 = boto3.resource('s3')
55-
self.assertTrue(hasattr(s3, 'get_available_subresources'))
55+
assert hasattr(s3, 'get_available_subresources')

tests/functional/test_s3.py

+31-41
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13+
import pytest
14+
1315
from tests import unittest
1416

1517
import botocore
@@ -26,36 +28,26 @@ class TestS3MethodInjection(unittest.TestCase):
2628
def test_transfer_methods_injected_to_client(self):
2729
session = boto3.session.Session(region_name='us-west-2')
2830
client = session.client('s3')
29-
self.assertTrue(hasattr(client, 'upload_file'),
30-
'upload_file was not injected onto S3 client')
31-
self.assertTrue(hasattr(client, 'download_file'),
32-
'download_file was not injected onto S3 client')
33-
self.assertTrue(hasattr(client, 'copy'),
34-
'copy was not injected onto S3 client')
31+
assert hasattr(client, 'upload_file')
32+
assert hasattr(client, 'download_file')
33+
assert hasattr(client, 'copy')
3534

3635
def test_bucket_resource_has_load_method(self):
3736
session = boto3.session.Session(region_name='us-west-2')
3837
bucket = session.resource('s3').Bucket('fakebucket')
39-
self.assertTrue(hasattr(bucket, 'load'),
40-
'load() was not injected onto S3 Bucket resource.')
38+
assert hasattr(bucket, 'load')
4139

4240
def test_transfer_methods_injected_to_bucket(self):
4341
bucket = boto3.resource('s3').Bucket('my_bucket')
44-
self.assertTrue(hasattr(bucket, 'upload_file'),
45-
'upload_file was not injected onto S3 bucket')
46-
self.assertTrue(hasattr(bucket, 'download_file'),
47-
'download_file was not injected onto S3 bucket')
48-
self.assertTrue(hasattr(bucket, 'copy'),
49-
'copy was not injected onto S3 bucket')
42+
assert hasattr(bucket, 'upload_file')
43+
assert hasattr(bucket, 'download_file')
44+
assert hasattr(bucket, 'copy')
5045

5146
def test_transfer_methods_injected_to_object(self):
5247
obj = boto3.resource('s3').Object('my_bucket', 'my_key')
53-
self.assertTrue(hasattr(obj, 'upload_file'),
54-
'upload_file was not injected onto S3 object')
55-
self.assertTrue(hasattr(obj, 'download_file'),
56-
'download_file was not injected onto S3 object')
57-
self.assertTrue(hasattr(obj, 'copy'),
58-
'copy was not injected onto S3 object')
48+
assert hasattr(obj, 'upload_file')
49+
assert hasattr(obj, 'download_file')
50+
assert hasattr(obj, 'copy')
5951

6052

6153
class BaseTransferTest(unittest.TestCase):
@@ -208,22 +200,22 @@ def test_client_copy(self):
208200
response = self.s3.meta.client.copy(
209201
self.copy_source, self.bucket, self.key)
210202
# The response will be none on a successful transfer.
211-
self.assertIsNone(response)
203+
assert response is None
212204

213205
def test_bucket_copy(self):
214206
self.stub_single_part_copy()
215207
bucket = self.s3.Bucket(self.bucket)
216208
with self.stubber:
217209
response = bucket.copy(self.copy_source, self.key)
218210
# The response will be none on a successful transfer.
219-
self.assertIsNone(response)
211+
assert response is None
220212

221213
def test_object_copy(self):
222214
self.stub_single_part_copy()
223215
obj = self.s3.Object(self.bucket, self.key)
224216
with self.stubber:
225217
response = obj.copy(self.copy_source)
226-
self.assertIsNone(response)
218+
assert response is None
227219

228220
def test_copy_progress(self):
229221
chunksize = 8 * (1024 ** 2)
@@ -243,8 +235,8 @@ def progress_callback(amount):
243235

244236
# Assert that the progress callback was called the correct number of
245237
# times with the correct amounts.
246-
self.assertEqual(self.progress_times_called, 3)
247-
self.assertEqual(self.progress, chunksize * 3)
238+
assert self.progress_times_called == 3
239+
assert self.progress == chunksize * 3
248240

249241

250242
class TestUploadFileobj(BaseTransferTest):
@@ -310,7 +302,7 @@ def test_client_upload(self):
310302

311303
def test_raises_value_error_on_invalid_fileobj(self):
312304
with self.stubber:
313-
with self.assertRaises(ValueError):
305+
with pytest.raises(ValueError):
314306
self.s3.meta.client.upload_fileobj(
315307
Fileobj='foo', Bucket=self.bucket, Key=self.key)
316308

@@ -427,12 +419,12 @@ def test_client_download(self):
427419
self.s3.meta.client.download_fileobj(
428420
Bucket=self.bucket, Key=self.key, Fileobj=self.fileobj)
429421

430-
self.assertEqual(self.fileobj.getvalue(), self.contents)
422+
assert self.fileobj.getvalue() == self.contents
431423
self.stubber.assert_no_pending_responses()
432424

433425
def test_raises_value_error_on_invalid_fileobj(self):
434426
with self.stubber:
435-
with self.assertRaises(ValueError):
427+
with pytest.raises(ValueError):
436428
self.s3.meta.client.download_fileobj(
437429
Bucket=self.bucket, Key=self.key, Fileobj='foo')
438430

@@ -442,7 +434,7 @@ def test_bucket_download(self):
442434
with self.stubber:
443435
bucket.download_fileobj(Key=self.key, Fileobj=self.fileobj)
444436

445-
self.assertEqual(self.fileobj.getvalue(), self.contents)
437+
assert self.fileobj.getvalue() == self.contents
446438
self.stubber.assert_no_pending_responses()
447439

448440
def test_object_download(self):
@@ -451,7 +443,7 @@ def test_object_download(self):
451443
with self.stubber:
452444
obj.download_fileobj(Fileobj=self.fileobj)
453445

454-
self.assertEqual(self.fileobj.getvalue(), self.contents)
446+
assert self.fileobj.getvalue() == self.contents
455447
self.stubber.assert_no_pending_responses()
456448

457449
def test_multipart_download(self):
@@ -467,7 +459,7 @@ def test_multipart_download(self):
467459
Bucket=self.bucket, Key=self.key, Fileobj=self.fileobj,
468460
Config=transfer_config)
469461

470-
self.assertEqual(self.fileobj.getvalue(), self.contents)
462+
assert self.fileobj.getvalue() == self.contents
471463
self.stubber.assert_no_pending_responses()
472464

473465
def test_download_progress(self):
@@ -489,8 +481,8 @@ def progress_callback(amount):
489481

490482
# Assert that the progress callback was called the correct number of
491483
# times with the correct amounts.
492-
self.assertEqual(self.progress_times_called, 11)
493-
self.assertEqual(self.progress, 55)
484+
assert self.progress_times_called == 11
485+
assert self.progress == 55
494486
self.stubber.assert_no_pending_responses()
495487

496488

@@ -520,19 +512,19 @@ def tearDown(self):
520512
self.stubber.deactivate()
521513

522514
def test_has_load(self):
523-
self.assertTrue(hasattr(self.obj_summary, 'load'),
524-
'load() was not injected onto ObjectSummary resource.')
515+
# Validate load was injected onto ObjectSummary.
516+
assert hasattr(self.obj_summary, 'load')
525517

526518
def test_autoloads_correctly(self):
527519
# In HeadObject the parameter returned is ContentLength, this
528520
# should get mapped to Size of ListObject since the resource uses
529521
# the shape returned to by ListObjects.
530-
self.assertEqual(self.obj_summary.size, self.obj_summary_size)
522+
assert self.obj_summary.size == self.obj_summary_size
531523

532524
def test_cannot_access_other_non_related_parameters(self):
533525
# Even though an HeadObject was used to load this, it should
534526
# only expose the attributes from its shape defined in ListObjects.
535-
self.assertFalse(hasattr(self.obj_summary, 'content_length'))
527+
assert not hasattr(self.obj_summary, 'content_length')
536528

537529

538530
class TestServiceResource(unittest.TestCase):
@@ -542,7 +534,5 @@ def setUp(self):
542534
def test_unsigned_signature_version_is_not_corrupted(self):
543535
config = Config(signature_version=botocore.UNSIGNED)
544536
resource = self.session.resource('s3', config=config)
545-
self.assertIs(
546-
resource.meta.client.meta.config.signature_version,
547-
botocore.UNSIGNED
548-
)
537+
sig_version = resource.meta.client.meta.config.signature_version
538+
assert sig_version is botocore.UNSIGNED

0 commit comments

Comments
 (0)