Testing principles and techniques: unittest and pytest
Testing principles and techniques
This domain checks that you can isolate units of code with both xUnit-style unittest and fixture-driven pytest, and that you know where a mocking boundary belongs.
unittest lifecycle. setUp/tearDown run around every test method; setUpClass/tearDownClass are @classmethods run once per class. assertEqual compares values, assertIs compares identity, plus assertIsInstance, assertIn, assertAlmostEqual (places), assertCountEqual (order-insensitive). assertRaises works as a callable form or as a context manager when you need to inspect the exception object.
pytest discovery and fixtures. Files test_*.py or *_test.py; functions test_*; classes Test* with no __init__. Plain assert suffices because pytest rewrites assertions to show intermediate values. A fixture (@pytest.fixture) is injected by naming it in the test signature; scope is function (default), class, module, package, or session. conftest.py makes fixtures visible without imports. @pytest.mark.parametrize supplies inputs; stacked decorators multiply into a Cartesian product.
Mocking rule. mock.patch("pkg.mod.name") must target the attribute as the consuming module sees it.
Worked example
report.py contains import time and def stamp(m): return f"{time.time():.0f}:{m}". Patch report.time, set mocked.time.return_value = 1000, assert stamp("ok") == "1000:ok". Patching time.time globally would not affect the reference report already bound, so the test would read the real clock and be silently flaky.
Traps
setUpClasswritten without@classmethodfails at call time.assertEqualon two equal-but-distinct objects is not an identity check; useassertIs.- Wrapping
assertRaisesaround the result of a call instead of the call itself. autouse=Truefixtures run without being named, which hides ordering dependencies.MagicMockauto-creates any attribute, so a typo'd method name never raises.