What Is pytest? The Python Testing Framework Explained
pytest is the most popular Python testing framework: it finds and runs your tests, gives readable failure output, and scales from a one-line check to large suites.
pytest makes writing Python tests low-friction. A test is just a function whose name starts with "test", using plain assert statements, and pytest discovers and runs them with rich reporting. Its fixture system and plugin ecosystem make it the default choice for most Python projects.
What pytest is
pytest is a testing framework and command-line runner for Python. It auto-discovers test files and functions, rewrites assert statements to produce detailed failure messages, and supports fixtures, parametrization, and a large plugin ecosystem (coverage, parallel execution, mocking, and more).
Fixtures and assertions
Instead of setup and teardown methods, pytest uses fixtures: functions that provide test dependencies (a database connection, a temp directory) and are injected by name into tests. Assertions use the plain "assert" keyword, and pytest introspects the expression to show exactly what differed when it fails.
A test example
A test is an ordinary function with an assertion.
# test_math.py
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5Role in CI/CD
pytest is the test step in most Python pipelines. It returns a non-zero exit code on any failure, which fails the CI job. Plugins like pytest-xdist run tests in parallel to shorten the suite, and pytest can emit JUnit XML for CI dashboards. Large suites are a frequent CI bottleneck; running them on faster managed runners and splitting them across workers keeps feedback quick.
Alternatives
unittest is the standard-library framework with a class-based, xUnit style. nose2 is a successor to the older nose. pytest dominates because of its concise syntax, powerful fixtures, and the breadth of its plugin ecosystem.
Key takeaways
- pytest discovers and runs Python tests with plain assert statements.
- Fixtures inject test dependencies; plugins add coverage and parallelism.
- It exits non-zero on failure, which fails the CI job.