A subTest gives each iteration of one test method its own reported case context.
Python unittest subTest: label several cases without aborting the method
Operation contract
The owned parser accepts a short ASCII minor-unit amount and rejects negative or non-ASCII text. One test method checks three accepted values under named subTest contexts. The runner reports one method and no failures, while the observed case list confirms all three contexts executed. If one subtest failed, unittest would record that failure and continue the later contexts in the same method.
Failure and ownership boundary
Subtests improve failure reporting, but they do not isolate shared mutable state between iterations. If a case changes a database or module global, reset it per case or use separate tests. Python unittest: test rejected input and preserve state after failure, Pytest fixtures: isolated files and parameterized rejection tests and Python refactoring: preserve rejected inputs as well as accepted results provide the surrounding structure.
Working program
import io
import unittest
def parse_minor(text):
if type(text) is not str or not 1 <= len(text) <= 4 or any(char not in "0123456789" for char in text):
raise ValueError("ASCII amount")
return int(text)
visited = []
class AmountCases(unittest.TestCase):
def test_accepted_amounts(self):
for raw, expected in (("0", 0), ("125", 125), ("0012", 12)):
with self.subTest(raw=raw):
visited.append(raw)
self.assertEqual(parse_minor(raw), expected)
result = unittest.TextTestRunner(stream=io.StringIO()).run(
unittest.defaultTestLoader.loadTestsFromTestCase(AmountCases))
print("method:", result.testsRun, "failures:", len(result.failures))
print("cases:", visited)
try:
parse_minor("12")
except ValueError:
print("non-ASCII amount rejected")Output
method: 1 failures: 0
cases: ['0', '125', '0012']
non-ASCII amount rejectedCosts and limits
Three tiny cases have bounded cost. A single test method still counts as one executed method; subtest events are additional reporting context, not independent process or transaction isolation.
Common Mistakes
- Do not assume subTest resets changed state between iterations.
- The runner method count is not the number of subtest cases.
Connected lessons
Python unittest: test rejected input and preserve state after failure, Pytest fixtures: isolated files and parameterized rejection tests, Python refactoring: preserve rejected inputs as well as accepted results.
