pytest is the most widely used Python testing framework. It requires no boilerplate classes — just write functions starting with test_ and run pytest.
Installation
pip install pytestVerify:
pytest --versionYour First Tests
# test_math.py
def add(a, b):
return a + b
def test_add_positive():
assert add(2, 3) == 5
def test_add_negative():
assert add(-1, -1) == -2
def test_add_zero():
assert add(0, 10) == 10Run:
pytest test_math.py -vOutput:
test_math.py::test_add_positive PASSED
test_math.py::test_add_negative PASSED
test_math.py::test_add_zero PASSEDTest Discovery Rules
pytest automatically finds tests that match:
| Rule | Example |
|---|---|
Files named test_*.py or *_test.py | test_auth.py, auth_test.py |
Functions starting with test_ | def test_login(): |
Methods starting with test_ in Test* classes | class TestAuth: def test_login(self): |
Run pytest in a directory to discover all matching tests recursively.
Assertion Introspection
pytest rewrites assert statements to show detailed failure messages:
def test_greeting():
result = "Hello, World"
assert result == "Hello, World!"AssertionError: assert 'Hello, World' == 'Hello, World!'
- Hello, World!
? ^
+ Hello, WorldNo assertEqual, assertTrue, or custom matchers needed — plain assert is enough.
Test Lifecycle Visualiser
pytest discovery and execution
Ctrl+Enter
HTML
CSS
JS
Preview
Organising Tests in Classes
class TestStringMethods:
def test_upper(self):
assert "hello".upper() == "HELLO"
def test_strip(self):
assert " hello ".strip() == "hello"
def test_split(self):
s = "hello world"
assert s.split() == ["hello", "world"]Classes don't need to inherit from anything — just prefix them with Test.
Running Specific Tests
pytest test_math.py::test_add_positive # single test
pytest -k "add" # tests matching "add" in name
pytest -k "not slow" # exclude by name
pytest -x # stop on first failure
pytest -v # verbose output