Write tests
Lines 1 and 2 define area(w, h), which should give width times height. It has a typo nobody has noticed: line 2 says w * w. A test is code that checks other code.
A test is a function whose name starts with test. test_square and test_rect each call area() and use assert to state the answer it must give. A false assert raises an error.
pytest runs them
pytest is a test runner: a tool that finds your tests, runs each one and reports what happened. Install it with pip, then type pytest in the folder that holds your code.
First pytest collects. It looks for files named test_*.py or *_test.py, and in them for functions whose names start with test. In test_area.py it finds two: collected 2 items.
pytest calls test_square() for you. Line 4 runs area(3, 3), and line 2 works out w * w = 3 * 3 = 9. That is right, but only by luck: in a square, w equals h.
assert 9 == 9 is True, so nothing happens and test_square ends normally. A test passes when it finishes without raising an error. pytest records PASSED and prints a dot.
Next pytest calls test_rect(). Line 6 runs area(2, 5). Because of the typo, line 2 works out w * w = 2 * 2 = 4, not the 10 the test expects.
assert 4 == 10 is False, so assert raises AssertionError. pytest catches it, records FAILED, prints an F and carries on: one failing test never stops the others from running.
Fail, fix, rerun
At the end pytest explains each failure. It rewrites assert so it can show the values: assert 4 == 10, where 4 = area(2, 5). The last line sums up: 1 failed, 1 passed.
The report points straight at the bug. Change line 2 to w * h and save. test_square alone could never catch this typo: when w equals h, w * w and w * h agree.
Run pytest again. Both tests pass, so the terminal shows two dots and 2 passed. Keep your tests and rerun them after every change: they check that old answers still hold.
Try it yourself
;; step 1/11 · The code to test
# area.py, or the top of test_area.py
def area(w, h):
return w * w # typo: should be w * h
>>> area(3, 3)
9
>>> area(2, 5) # should be 10
4
pytest is not part of the standard library: install it with python -m pip install pytest, ideally inside a virtual environment. python -m pytest runs it too. Python's built-in framework is unittest, and pytest runs unittest-style tests as well. The figure shortens the terminal: real pytest output also shows the platform and folder, a progress percentage, a short summary of failures and the run time, framed by full-width lines of = signs.