Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python unittest subTest: label several cases without aborting the method

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A subTest gives each iteration of one test method its own reported case context.

Download Python source kit

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

python
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

Output
method: 1 failures: 0
cases: ['0', '125', '0012']
non-ASCII amount rejected

Costs 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.

python
unittest-subtests
Storage details