Skip to content

Test Python code with pytest

I can write pytest tests that state what a function should do, cover the edge cases that actually break it, and fail with a message that shows what went wrong.

Domain
Python Programming
Level
intermediate
Status
draft · v0.1.0
Also called
pytest, Unit testing Python, Writing tests, Test-driven development
License
CC BY-SA 4.0

Learn first

Learn it

Scope

Writing the tests a reviewer expects to see, and reading what they say when they fail.

In scope: test functions and assert, choosing cases, parametrize, fixtures, testing that something raises, and running the suite. Out of scope: mocking, coverage targets and continuous integration.

A test is a written claim

assert result == 7 is a sentence: given this input, this function produces seven. A suite is the set of claims you are prepared to defend, and the reason to have one is not correctness today but the freedom to change the code tomorrow without reading all of it again.

pytest keeps this cheap. A file named test_*.py, functions named test_*, and a plain assert — no class, no boilerplate. When the assert fails, pytest shows both sides of the comparison, which is why the plain assert is enough.

Choosing cases, which is the actual skill

Anyone can test that add(2, 2) == 4. The cases that catch bugs are the awkward ones:

  • Empty — no items, empty string, zero.
  • One — the case that distinguishes “handles a collection” from “handles a loop”.
  • Boundary — the first and last valid values, and one either side.
  • Wrong — what should it do with input it cannot accept? If it raises, assert that with pytest.raises.

If a case is hard to write a test for, that is usually the function’s design talking, not the test framework’s.

Parametrize and fixtures

@pytest.mark.parametrize runs one test body over many inputs, each reported separately, so a failing case is named rather than hidden inside a loop. A fixture builds what several tests need — a temporary file, a sample record — and pytest hands it to any test that asks for it by name. Prefer tmp_path over writing into the repository.

Common misconceptions

  • “Tests prove the code is correct.” They show the claims you made still hold. Untested behaviour is unclaimed, not proven.
  • “Test everything.” Test the behaviour someone depends on. Tests of implementation detail break on every refactor and teach the team to ignore them.
  • “A passing suite means done.” A suite that never failed has not yet shown it can. Make a test fail on purpose before trusting it.
  • “Writing tests slows me down.” It slows down the first hour and speeds up every hour after the code outgrows what you can hold in your head.

Notes for teachers

Hand out a function with a known bug at a boundary and a suite that passes. Ask for one test that fails. Finding it is the whole skill, and it lands better than any explanation of why coverage is not the point.

For assessment practice: take any problem a learner has already solved and require tests for it before it counts as finished. That is the habit a take-home is actually grading.

Resources

ResourceKindCostProvider
pytest: getting startedreadingfreepytest
pytest: how to use fixturesreferencefreepytest
pytest: how to parametrize testsreferencefreepytest
CS50P problem setspracticefreeHarvard University

Courses that include it

draft

Python for a Coding Assessment

A refresher path through the Python graph for someone who has written Python before and has an assessment coming: run and read, rebuild the core, then work the way an assessment expects.

Prove it

Evidence of mastery

  • Writes tests for a function that cover the ordinary case, an empty input, a boundary value, and the error it is supposed to raise.
  • Runs the suite, reads a failure, and says from the output alone what the code did and what was expected.
  • Uses parametrize to test many inputs without repeating the test body.
  • Uses a fixture to build what several tests share, and says why that beats setting it up in each test.
  • Writes a test that fails first, then makes it pass.

Assessments that measure it

project

Python Take-Home Task

A timed take-home in the shape real hiring uses: read messy data, compute a result, test it, and hand over a repository someone else can run.

Credentials that include it

draft

Python Problem Solving

The holder can take an unfamiliar problem, write a tested Python solution someone else can run, and explain what it costs.

What learners show

Nothing to show yet. The publisher last published on 2026-09-20, and no aggregate for this outcome has reached the 50 learners a number needs. Open Degree does not track learners. About learner evidence.

What comes next