Testing with pytest
Python's stdlib has unittest, but nobody uses it if pytest is an option. pytest is:
- Zero ceremony — a function named
test_*in a file namedtest_*.pyis a test. - Plain
assert— noself.assertEqualverbosity. - Rich failure output — shows the actual value that broke.
The whole API
assert expected == actual— pytest rewrites this to show both sides on failure.with pytest.raises(SomeError, match="..."):— assert exception + optional message.@pytest.mark.parametrize("a,b,expected", [...])— one test, many inputs.@pytest.fixture— reusable setup (next lesson).pytest -vverbose,pytest -k slugifyfilter by name,pytest -xstop on first failure.
Test organization
myapp/
__init__.py
slugify.py
tests/
test_slugify.py
Then just run pytest. It discovers everything.
Coverage
pip install pytest-cov
pytest --cov=myapp --cov-report=term-missing
Shows which lines your tests miss. Aim for 80%+ on business logic; don't chase 100% on plumbing.
Try it
- Add a test that
slugify("Python 🐍")behaves how you'd want. - Add a parametrize case where
bis negative.
3 graded exercises
Write the code, click Check. We’ll tell you exactly what to fix.
- Exercise 1
Write a pytest-style test function named 'test_add' that asserts 1 + 1 equals 2. Then call test_add() so it runs. Pytest is auto-installed for you.
- Exercise 2
Use pytest.raises to assert that int('abc') raises a ValueError. Put it inside a function named 'test_raises' and call it.
- Exercise 3
Parametrize a test with @pytest.mark.parametrize. Decorate 'test_add(a, b, expected)' with cases (2, 3, 5) and (10, 20, 30), asserting a + b == expected. Then invoke it once with (2, 3, 5) so it runs.