pytest1def area(w, h):2 return w * w3def test_square():4 assert area(3, 3) == 95def test_rect():6 assert area(2, 5) == 10test_squaretest_rectpytesttest_area.pytest_square()9 == 9test_rect()4 == 101 failed, 1 passedpytest
Code card: test_area.py; the highlighted lines are the ones runningpytest: finds the tests, runs them and reportsTerminal: where you type pytest and read its reportResult boxes: PASSED or FAILED for each testpytest finds the test functions in test_area.py, calls each one and records whether its assert held. Each step lights the parts it is about. A token hops along the step's arrow: from the terminal to pytest, from pytest to a test's assert line, from the assert to that test's result box, and from pytest back to the terminal with the report. test_square passes by luck (in a square w equals h); test_rect fails with assert 4 == 10 and points at line 2. After the fix, w * w becomes w * h and the rerun passes both tests.

Write tests

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

pytest runs them

Fail, fix, rerun

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.