Skip to content

Commit ad22c1c

Browse files
authored
Use TestCase.subTest in tests that test multiple values (#523)
1 parent e740280 commit ad22c1c

File tree

6 files changed

+118
-86
lines changed

6 files changed

+118
-86
lines changed

tests/test_bg.py

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,29 @@ class BGLocalFlavorValidatorsTests(TestCase):
6565

6666
def test_egn_validator_with_valid_egns(self):
6767
for egn in VALID_EGNS:
68-
try:
69-
egn_validator(egn)
70-
except ValidationError:
71-
self.fail('egn_validator said that valid EGN %s is invalid' % egn)
68+
with self.subTest(egn=egn):
69+
try:
70+
egn_validator(egn)
71+
except ValidationError:
72+
self.fail('egn_validator said that valid EGN %s is invalid' % egn)
7273

7374
def test_egn_validator_with_invalid_egns(self):
7475
for egn in INVALID_EGNS:
75-
self.assertRaises(ValidationError, egn_validator, egn)
76+
with self.subTest(egn=egn):
77+
self.assertRaises(ValidationError, egn_validator, egn)
7678

7779
def test_eik_validator_with_valid_eiks(self):
7880
for eik in VALID_EIKS:
79-
try:
80-
eik_validator(eik)
81-
except ValidationError:
82-
self.fail('eik_validator fails for %s' % eik)
81+
with self.subTest(eik=eik):
82+
try:
83+
eik_validator(eik)
84+
except ValidationError:
85+
self.fail('eik_validator fails for %s' % eik)
8386

8487
def test_eik_validator_with_invalid_eiks(self):
8588
for eik in INVALID_EIKS:
86-
self.assertRaises(ValidationError, eik_validator, eik)
89+
with self.subTest(eik=eik):
90+
self.assertRaises(ValidationError, eik_validator, eik)
8791

8892

8993
class BGLocalFlavorEGNFieldTests(TestCase):
@@ -105,13 +109,15 @@ class Meta:
105109

106110
def test_egn_form_with_valid_egns(self):
107111
for egn in VALID_EGNS:
108-
form = self.EGNForm({'egn': egn})
109-
self.assertTrue(form.is_valid())
112+
with self.subTest(egn=egn):
113+
form = self.EGNForm({'egn': egn})
114+
self.assertTrue(form.is_valid())
110115

111116
def test_egn_form_with_invalid_egns(self):
112117
for egn in INVALID_EGNS:
113-
form = self.EGNForm({'egn': egn})
114-
self.assertFalse(form.is_valid())
118+
with self.subTest(egn=egn):
119+
form = self.EGNForm({'egn': egn})
120+
self.assertFalse(form.is_valid())
115121

116122

117123
class BGLocalFlavorEIKFieldTest(TestCase):
@@ -133,13 +139,15 @@ class Meta:
133139

134140
def test_eik_form_with_valid_eiks(self):
135141
for eik in VALID_EIKS:
136-
form = self.EIKForm({'eik': eik})
137-
self.assertTrue(form.is_valid())
142+
with self.subTest(eik=eik):
143+
form = self.EIKForm({'eik': eik})
144+
self.assertTrue(form.is_valid())
138145

139146
def test_eik_form_with_invalid_eiks(self):
140147
for eik in INVALID_EIKS:
141-
form = self.EIKForm({'eik': eik})
142-
self.assertFalse(form.is_valid())
148+
with self.subTest(eik=eik):
149+
form = self.EIKForm({'eik': eik})
150+
self.assertFalse(form.is_valid())
143151

144152

145153
class BGLocaFlavorUtilsTest(TestCase):

tests/test_br/test_br.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@ def test_BRZipCodeField(self):
2222
self.assertFieldOutput(BRZipCodeField, valid, invalid)
2323

2424
for postal_code, error in invalid.items():
25-
form = BRPersonProfileForm({
26-
'postal_code': postal_code
27-
})
25+
with self.subTest(postal_code=postal_code, error=error):
26+
form = BRPersonProfileForm({
27+
'postal_code': postal_code
28+
})
2829

29-
self.assertFalse(form.is_valid())
30-
self.assertEqual(form.errors['postal_code'], error)
30+
self.assertFalse(form.is_valid())
31+
self.assertEqual(form.errors['postal_code'], error)
3132

3233
def test_BRCNPJField(self):
3334
error_format = {
@@ -67,12 +68,13 @@ def test_BRCNPJField(self):
6768
self.assertFieldOutput(BRCNPJField, short_version_valid, invalid_long, field_kwargs={'max_length': 14})
6869

6970
for cnpj, invalid_msg in invalid.items():
70-
form = BRPersonProfileForm({
71-
'cnpj': cnpj
72-
})
71+
with self.subTest(cnpj=cnpj, invalid_msg=invalid_msg):
72+
form = BRPersonProfileForm({
73+
'cnpj': cnpj
74+
})
7375

74-
self.assertFalse(form.is_valid())
75-
self.assertEqual(form.errors['cnpj'], invalid_msg)
76+
self.assertFalse(form.is_valid())
77+
self.assertEqual(form.errors['cnpj'], invalid_msg)
7678

7779
def test_BRCPFField(self):
7880
error_format = ['Invalid CPF number.']
@@ -102,12 +104,13 @@ def test_BRCPFField(self):
102104
self.assertFieldOutput(BRCPFField, valid, invalid)
103105

104106
for cpf, invalid_msg in invalid.items():
105-
form = BRPersonProfileForm({
106-
'cpf': cpf
107-
})
107+
with self.subTest(cpf=cpf, invalid_msg=invalid_msg):
108+
form = BRPersonProfileForm({
109+
'cpf': cpf
110+
})
108111

109-
self.assertFalse(form.is_valid())
110-
self.assertIn(form.errors['cpf'][0], invalid_msg)
112+
self.assertFalse(form.is_valid())
113+
self.assertIn(form.errors['cpf'][0], invalid_msg)
111114

112115
def test_BRProcessoField(self):
113116
error_format = ['Invalid Process number.']
@@ -221,8 +224,9 @@ def test_model_form_valid(self):
221224
]
222225

223226
for case in data_to_test:
224-
form = BRPersonProfileForm(case)
225-
self.assertTrue(form.is_valid())
227+
with self.subTest(case=case):
228+
form = BRPersonProfileForm(case)
229+
self.assertTrue(form.is_valid())
226230

227231
class BRLocalFlavorModelFormTests (TestCase):
228232
def setUp(self):

tests/test_general.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,29 +39,31 @@ def test_model_field_deconstruct_methods_with_default_options(self):
3939
self.assertTrue(len(model_classes) > 0, 'No localflavor models.Field classes were found.')
4040

4141
for cls in model_classes:
42-
test_instance = cls()
43-
name, path, args, kwargs = test_instance.deconstruct()
42+
with self.subTest(cls=cls):
43+
test_instance = cls()
44+
name, path, args, kwargs = test_instance.deconstruct()
4445

45-
# 'choices' should not be in the kwargs output of deconstruct because storing choices changes to the
46-
# migrations doesn't add value to the migration. Any data changes will use a data migration management
47-
# command.
48-
self.assertNotIn('choices', kwargs,
49-
'\'choices\' should not be returned by {}.deconstruct().'.format(cls.__name__))
46+
# 'choices' should not be in the kwargs output of deconstruct because storing choices changes to the
47+
# migrations doesn't add value to the migration. Any data changes will use a data migration management
48+
# command.
49+
self.assertNotIn('choices', kwargs,
50+
'\'choices\' should not be returned by {}.deconstruct().'.format(cls.__name__))
5051

51-
# 'max_length' should be in the kwargs output of deconstruct so that a schema migration will be generated if
52-
# the max_length field changes.
53-
self.assertIn('max_length', kwargs, '\'max_length\' not returned by {}.deconstruct().'.format(cls.__name__))
52+
# 'max_length' should be in the kwargs output of deconstruct so that a schema migration will be generated if
53+
# the max_length field changes.
54+
self.assertIn('max_length', kwargs, '\'max_length\' not returned by {}.deconstruct().'.format(cls.__name__))
5455

55-
# The attribute values should match an instance created with the args and kwargs output of deconstruct.
56-
new_instance = cls(*args, **kwargs)
57-
for attr in ('choices', 'max_length'):
58-
self.assertEqual(getattr(test_instance, attr), getattr(new_instance, attr))
56+
# The attribute values should match an instance created with the args and kwargs output of deconstruct.
57+
new_instance = cls(*args, **kwargs)
58+
for attr in ('choices', 'max_length'):
59+
self.assertEqual(getattr(test_instance, attr), getattr(new_instance, attr))
5960

6061
def test_forms_char_field_empty_value_allows_none(self):
6162
form_classes = self._find_localflavor_subclasses(forms.CharField)
6263
self.assertTrue(len(form_classes) > 0, 'No localflavor forms.CharField classes were found.')
6364

6465
for cls in form_classes:
65-
failure_message = '{} does not handle does not properly handle values that are None.'.format(cls.__name__)
66-
field = cls(required=False, empty_value=None)
67-
self.assertIsNone(field.clean(None), failure_message)
66+
with self.subTest(cls=cls):
67+
failure_message = '{} does not handle does not properly handle values that are None.'.format(cls.__name__)
68+
field = cls(required=False, empty_value=None)
69+
self.assertIsNone(field.clean(None), failure_message)

tests/test_generic/tests.py

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,12 @@ def test_iban_validator(self):
127127

128128
iban_validator = IBANValidator()
129129
for iban in valid:
130-
iban_validator(iban)
130+
with self.subTest(iban=iban):
131+
iban_validator(iban)
131132

132133
for iban in invalid:
133-
self.assertRaisesMessage(ValidationError, invalid[iban], IBANValidator(), iban)
134+
with self.subTest(iban=iban):
135+
self.assertRaisesMessage(ValidationError, invalid[iban], IBANValidator(), iban)
134136

135137
def test_iban_validator_deconstruct(self):
136138
# Call to the required deconstruct method to see if it exists and
@@ -145,9 +147,10 @@ def test_iban_validator_deconstruct(self):
145147
]
146148

147149
for test_case in test_cases:
148-
iban1 = IBANValidator(**test_case)
149-
iban2 = IBANValidator(**test_case)
150-
self.assertEqual(iban1, iban2, msg="IBAN validators with equal parameters are not equal.")
150+
with self.subTest(test_case=test_case):
151+
iban1 = IBANValidator(**test_case)
152+
iban2 = IBANValidator(**test_case)
153+
self.assertEqual(iban1, iban2, msg="IBAN validators with equal parameters are not equal.")
151154

152155
def test_iban_fields(self):
153156
"""Test the IBAN model and form field."""
@@ -194,17 +197,19 @@ def test_iban_fields(self):
194197
# Test valid inputs for model field.
195198
iban_model_field = IBANField()
196199
for input, output in valid.items():
197-
self.assertEqual(iban_model_field.clean(input, None), output)
200+
with self.subTest(input=input, output=output):
201+
self.assertEqual(iban_model_field.clean(input, None), output)
198202

199203
self.assertIsNone(iban_model_field.to_python(None))
200204

201205
# Invalid inputs for model field.
202206
for input, errors in invalid.items():
203-
with self.assertRaises(ValidationError) as context_manager:
204-
iban_model_field.clean(input, None)
205-
# The error messages for models are in a different order.
206-
errors.reverse()
207-
self.assertEqual(context_manager.exception.messages, errors)
207+
with self.subTest(input=input, errors=errors):
208+
with self.assertRaises(ValidationError) as context_manager:
209+
iban_model_field.clean(input, None)
210+
# The error messages for models are in a different order.
211+
errors.reverse()
212+
self.assertEqual(context_manager.exception.messages, errors)
208213

209214
def test_nordea_extensions(self):
210215
"""Test a valid IBAN in the Nordea extensions."""
@@ -249,15 +254,17 @@ def test_include_countries(self):
249254
# Test valid inputs for model field.
250255
iban_model_field = IBANField(include_countries=include_countries)
251256
for input, output in valid.items():
252-
self.assertEqual(iban_model_field.clean(input, None), output)
257+
with self.subTest(input=input, output=output):
258+
self.assertEqual(iban_model_field.clean(input, None), output)
253259

254260
# Invalid inputs for model field.
255261
for input, errors in invalid.items():
256-
with self.assertRaises(ValidationError) as context_manager:
257-
iban_model_field.clean(input, None)
258-
# The error messages for models are in a different order.
259-
errors.reverse()
260-
self.assertEqual(context_manager.exception.messages, errors)
262+
with self.subTest(input=input, errors=errors):
263+
with self.assertRaises(ValidationError) as context_manager:
264+
iban_model_field.clean(input, None)
265+
# The error messages for models are in a different order.
266+
errors.reverse()
267+
self.assertEqual(context_manager.exception.messages, errors)
261268

262269
def test_misconfigured_include_countries(self):
263270
"""Test that an IBAN field or model raises an error when asked to validate a country not part of IBAN."""
@@ -297,7 +304,8 @@ def test_model_field_deconstruct(self):
297304
name, path, args, kwargs = test_instance.deconstruct()
298305
new_instance = IBANField(*args, **kwargs)
299306
for attr in ('include_countries', 'use_nordea_extensions'):
300-
self.assertEqual(getattr(test_instance, attr), getattr(new_instance, attr))
307+
with self.subTest(attr=attr):
308+
self.assertEqual(getattr(test_instance, attr), getattr(new_instance, attr))
301309

302310

303311
class BICTests(TestCase):
@@ -370,15 +378,17 @@ def test_bic_model_field(self):
370378

371379
# Test valid inputs for model field.
372380
for input, output in valid.items():
373-
self.assertEqual(bic_model_field.clean(input, None), output)
381+
with self.subTest(input=input, output=output):
382+
self.assertEqual(bic_model_field.clean(input, None), output)
374383

375384
self.assertIsNone(bic_model_field.to_python(None))
376385

377386
# Invalid inputs for model field.
378387
for input, errors in invalid.items():
379-
with self.assertRaises(ValidationError) as context_manager:
380-
bic_model_field.clean(input, None)
381-
self.assertEqual(errors, context_manager.exception.messages)
388+
with self.subTest(input=input, errors=errors):
389+
with self.assertRaises(ValidationError) as context_manager:
390+
bic_model_field.clean(input, None)
391+
self.assertEqual(errors, context_manager.exception.messages)
382392

383393
def test_default_form(self):
384394
bic_model_field = BICField()
@@ -408,10 +418,12 @@ def test_ean_validator(self):
408418

409419
validator = EANValidator()
410420
for value in valid:
411-
validator(value)
421+
with self.subTest(value=value):
422+
validator(value)
412423

413424
for value in invalid:
414-
self.assertRaisesMessage(ValidationError, error_message, validator, value)
425+
with self.subTest(value=value):
426+
self.assertRaisesMessage(ValidationError, error_message, validator, value)
415427

416428
def test_ean_validator_deconstruct(self):
417429
# Call to the required deconstruct method to see if it exists and
@@ -426,9 +438,10 @@ def test_ean_validator_deconstruct(self):
426438
]
427439

428440
for test_case in test_cases:
429-
ean1 = EANValidator(**test_case)
430-
ean2 = EANValidator(**test_case)
431-
self.assertEqual(ean1, ean2, msg="EAN validators with equal parameters are not equal.")
441+
with self.subTest(test_case=test_case):
442+
ean1 = EANValidator(**test_case)
443+
ean2 = EANValidator(**test_case)
444+
self.assertEqual(ean1, ean2, msg="EAN validators with equal parameters are not equal.")
432445

433446
def test_ean_validator_strip_nondigits(self):
434447
valid = [
@@ -456,7 +469,9 @@ def test_ean_validator_strip_nondigits(self):
456469

457470
validator = EANValidator(strip_nondigits=True)
458471
for value in valid:
459-
validator(value)
472+
with self.subTest(value=value):
473+
validator(value)
460474

461475
for value in invalid:
462-
self.assertRaisesMessage(ValidationError, error_message, validator, value)
476+
with self.subTest(value=value):
477+
self.assertRaisesMessage(ValidationError, error_message, validator, value)

tests/test_nl/tests.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
class NLLocalFlavorValidatorTests(SimpleTestCase):
1111
def assert_validator(self, validator, valid=(), invalid=()):
1212
for item in valid:
13-
validator(item)
13+
with self.subTest(item=item):
14+
validator(item)
1415

1516
for item in invalid:
16-
self.assertRaises(ValidationError, lambda: validator(item))
17+
with self.subTest(item=item):
18+
self.assertRaises(ValidationError, lambda: validator(item))
1719

1820
def test_NLZipCodeValidator(self):
1921
valid = [

tests/test_si.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ def test_SIEMSOField_info_dict(self):
5151
'1010985505402': {'nationality': 50, 'gender': 'female', 'birthdate': date(1985, 10, 10)},
5252
}
5353
for input, info in valid.items():
54-
f = SIEMSOField()
55-
f.clean(input)
56-
self.assertEqual(f.info, info)
54+
with self.subTest(input=input, info=info):
55+
f = SIEMSOField()
56+
f.clean(input)
57+
self.assertEqual(f.info, info)
5758

5859
def test_SIPostalCodeField(self):
5960
valid = {

0 commit comments

Comments
 (0)