The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| Create a test case | class ParserTests(unittest.TestCase): ... | View examples |
| Declare a test | def test_rejects_empty_input(self): ... | View examples |
| Compare values | self.assertEqual(actual, expected) | View examples |
| Assert an exception | with self.assertRaises(ValueError): parse('') | View examples |
| Assert message text | with self.assertRaisesRegex(ValueError, 'positive'): validate(0) | View examples |
| Prepare each test | def setUp(self): self.client = Client() | View examples |
| Register cleanup | self.addCleanup(resource.close) | View examples |
| Name table cases | with self.subTest(value=value): self.assertTrue(valid(value)) | View examples |
| Create a specified mock | client = Mock(spec=ApiClient) | View examples |
| Patch with signature checks | @patch('module.ApiClient', autospec=True) | View examples |
| Configure a return | client.fetch.return_value = {'status': 'ok'} | View examples |
| Raise or vary calls | client.fetch.side_effect = TimeoutError('slow') | View examples |
| Verify one call | client.fetch.assert_called_once_with('/status') | View examples |
| Use a temporary directory | with tempfile.TemporaryDirectory() as directory: ... | View examples |
Tests should make behavior and failure conditions obvious while remaining independent of order, clock, network, and machine state. Use real values for pure logic, temporary resources for filesystem boundaries, and mocks only at narrow external seams—patched where the dependency is looked up, with specifications that catch API drift.
Step by step
Detailed examples
Name tests after externally observable behavior
unittest discovers TestCase methods beginning with test. Each method runs on a new instance, so tests must not depend on order or state from earlier tests. Keep one coherent behavior per test and use descriptive names that make failures understandable without reading implementation code.
import unittest
def normalize(text: str) -> str:
if not text.strip():
raise ValueError('text cannot be empty')
return text.strip().casefold()
class NormalizeTests(unittest.TestCase):
def test_strips_and_casefolds(self):
self.assertEqual(normalize(' READY '), 'ready')
suite = unittest.defaultTestLoader.loadTestsFromTestCase(NormalizeTests)
result = unittest.TestResult()
suite.run(result)
print(result.wasSuccessful(), result.testsRun) True 1Use the assertion that explains the contract
Specialized assertions provide better diagnostics than a bare assert. assertRaises must wrap only the operation expected to fail or a different statement can satisfy it accidentally. Validate meaningful exception properties without coupling to incidental full messages.
import unittest
class ValidationTests(unittest.TestCase):
def test_positive_value(self):
self.assertGreater(3, 0)
def test_zero_is_rejected(self):
with self.assertRaisesRegex(ValueError, 'positive'):
raise ValueError('value must be positive')
result = unittest.TestResult()
unittest.defaultTestLoader.loadTestsFromTestCase(ValidationTests).run(result)
print(result.wasSuccessful()) TrueMake resource ownership independent of fixture success
setUp and tearDown run around each test, but tearDown does not run if setUp itself fails. addCleanup callbacks registered before failure still run and unwind last-in-first-out. Prefer TemporaryDirectory and context managers over fixed paths or manual cleanup.
import tempfile
from pathlib import Path
with tempfile.TemporaryDirectory() as directory:
path = Path(directory, 'result.txt')
path.write_text('ready', encoding='utf-8')
print(path.read_text(encoding='utf-8'))
print(path.exists()) ready
FalseUse subtests for small tables, separate tests for separate behavior
subTest attaches parameters to a failure and continues remaining iterations. It is useful when setup and assertion shape are identical. Large case matrices can hide intent and make failure diagnosis harder; split them when scenarios have different meaning.
import unittest
class EvenTests(unittest.TestCase):
def test_examples(self):
for value, expected in [(2, True), (3, False), (0, True)]:
with self.subTest(value=value):
self.assertEqual(value % 2 == 0, expected)
result = unittest.TestResult()
unittest.defaultTestLoader.loadTestsFromTestCase(EvenTests).run(result)
print(result.wasSuccessful()) TrueMock the boundary, not the logic under test
Mock records calls and provides configurable return_value or side_effect. spec rejects unknown reads; spec_set also prevents unknown writes. Verify important collaboration, but avoid asserting every internal call because that freezes implementation rather than behavior.
from unittest.mock import Mock
class ApiClient:
def fetch(self, path: str) -> dict: ...
client = Mock(spec_set=ApiClient)
client.fetch.return_value = {'status': 'ok'}
print(client.fetch('/status'))
client.fetch.assert_called_once_with('/status') {'status': 'ok'}Patch the name used by the system under test
patch replaces an attribute for the duration of a test and restores it afterward. Patch where code looks up the dependency, not necessarily where the object was originally defined. autospec constrains signatures and attributes, reducing false-positive tests caused by misspelled mock APIs.
from unittest.mock import patch
import time
with patch.object(time, 'time', autospec=True, return_value=123.5) as clock:
print(time.time())
clock.assert_called_once_with()
print(callable(time.time)) 123.5
TrueLocal code tester
Run a focused unit test
Edit behavior, assertions, subtests, and a specified mock, then run the suite.
Press Run to load Python locally.
Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



