Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

Writing a test for a function

After this lesson: I can write a test that checks a function.

50 min lessonNo commands

Free delivery stopped working

A customer spends exactly 50 pounds. The site promised free delivery at 50 pounds. It charged her 3.99 anyway.

Somebody changed one character last week. Nobody noticed, because nothing checked it. A test is a small piece of code that would have noticed.

By the end of this lesson

Note

I can write a test that checks a function.

Key words

WordWhat it meansExample
Testcode that checks other code gives the right answer
Asserta line that stops with an error if something is falseassert fee == 0
Expectedthe answer the function should give
Actualthe answer the function really gives
Edge casea value at a limit, where bugs often hide5000

The cells students fill in are left blank in this preview.

A test compares expected and actual

Every test asks one question: does the function give the answer it should?

You write down the expected answer. You run the function to get the actual answer. Then assert compares them.

If they match, nothing happens and the test passes. If they differ, Python stops with an AssertionError.

Try it: a first test

Code: python
def delivery_fee(total):
    # Prices are in pence. Orders of 5000 pence (50 pounds) or more go free.
    if total >= 5000:
        return 0
    return 399


expected = 399
actual = delivery_fee(1200)
print("Expected:", expected, "Actual:", actual)
assert actual == expected
print("Test passed")

Test the edges, not only the middle

A test with 1200 pence and a test with 9000 pence both pass, even with a bug. Bugs hide at the edge: the exact value where the rule changes.

For "free at 50 pounds", test just under, exactly on, and just over the limit.

Worked example: tests for free delivery

Order (pence)Why this valueExpected feeWith the > bug
1200An ordinary small order399399, passes
4999One penny under the limit399399, passes
5000Exactly on the limit0399, fails
9000An ordinary large order00, passes

The cells students fill in are left blank in this preview.

A common mistake

Warning

Many people think a passing test proves the code is right. A test only checks the values you chose. If you never try the edge, a bug at the edge passes every test.

Practise: catch the bug at the edge

Code: python
def delivery_fee(total):
    # Somebody changed >= to > by mistake.
    if total > 5000:
        return 0
    return 399


assert delivery_fee(1200) == 399
print("Small order: passed")
assert delivery_fee(9000) == 0
print("Large order: passed")

# Add one more assert for an order of exactly 5000 pence.
# What should the fee be? Press Run and read what happens.

Tests live in functions named test_

At work, each test is its own function whose name starts with test_. A test runner such as pytest finds them all and runs them.

One function checks one idea. Its name says the idea: test_exactly_five. When it fails, the name tells you what broke.

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.