Testing in Python with pytest (Version ≥ 8.2)¶
Overview¶
Testing in Python with pytest refers to using the pytest framework to design, execute, and manage automated tests with clear scope definition, coverage measurement, and CI/CD integration. Pytest is a mature, extensible testing framework that emphasizes simple syntax, powerful fixtures, and rich plugin support. It is widely adopted for unit testing, integration testing, and regression testing across Python packages and applications.
Testing Scope and Strategy¶
Test Scope Definition¶
Tests should be categorized by scope to ensure clarity, maintainability, and predictable execution.
| Scope Type | Purpose | Typical Location |
|---|---|---|
| Unit Tests | Validate isolated functions or methods | tests/unit/ |
| Integration Tests | Validate interactions between components | tests/integration/ |
| End-to-End Tests | Validate full application workflows | tests/e2e/ |
| Regression Tests | Prevent reintroduction of known defects | tests/regression/ |
Note
Scope discipline Clearly separating test scopes allows selective execution and faster feedback during development and CI runs.
Package-Oriented Test Layout¶
Pytest discovers tests based on file and function naming conventions.
Recommended structure:
(1) Test files prefixed with test_ or suffixed with _test.py
(2) Test functions prefixed with test_
(3) Tests colocated in a top-level tests/ directory
Introduction to pytest¶
Core Features¶
Pytest provides the following core capabilities:
(1) Automatic test discovery
(2) Rich assertion introspection
(3) Fixture-based dependency injection
(4) Plugin ecosystem for coverage, mocking, and reporting
Minimal example:
No explicit test runner or boilerplate is required.
Test Execution Flow¶
Pytest Runtime Lifecycle¶
When pytest executes tests, it follows a deterministic process.
(1) Load configuration from pytest.ini, pyproject.toml, or setup.cfg
(2) Discover test files and test functions
(3) Collect fixtures and resolve dependencies
(4) Execute tests in collection order
(5) Capture results, failures, and errors
(6) Generate reports and exit with a status code
Warning
Exit code dependency CI systems rely on pytest exit codes. Any test failure causes a non-zero exit code and should block deployments.
Test Coverage¶
Coverage Measurement¶
Coverage is commonly measured using the pytest-cov plugin, which integrates with coverage.py.
Typical coverage dimensions:
(1) Line coverage
(2) Branch coverage
(3) Module-level coverage
Example command:
Tip
Coverage thresholds Define minimum coverage thresholds to prevent untested code from being merged.
Coverage Scope Control¶
Coverage should be scoped intentionally:
(1) Include only application packages
(2) Exclude test utilities and generated code
(3) Avoid inflating coverage with trivial paths
pytest.ini Configuration¶
Purpose of pytest.ini¶
The pytest.ini file centralizes pytest behavior and ensures consistent execution across environments.
Example pytest.ini (pytest ≥ 8.2)¶
[pytest]
minversion = 8.2
addopts = -ra --strict-markers
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
markers =
unit: unit-level tests
integration: integration-level tests
e2e: end-to-end tests
Configuration responsibilities:
(1) Enforce minimum pytest version
(2) Define test discovery rules
(3) Register markers to avoid runtime warnings
(4) Standardize default CLI options
Note
Marker registration is mandatory Pytest ≥ 8.x enforces strict marker usage when --strict-markers is enabled.
Test Selection and Markers¶
Using Markers¶
Markers allow selective test execution by scope or purpose.
Selective execution:
Markers are essential for CI pipelines and large test suites.
CI/CD Integration¶
CI Test Pipeline Flow¶
In CI/CD systems, pytest is typically integrated as a mandatory quality gate.
(1) Install dependencies in an isolated environment
(2) Install test-only dependencies such as pytest and pytest-cov
(3) Execute pytest with coverage enabled
(4) Publish test and coverage reports
(5) Fail the pipeline on test or coverage violations
Example CI command:
Warning
Pipeline stability requirement
Tests must be deterministic. Flaky tests undermine CI reliability and should be fixed or quarantined immediately.
Artifacts and Reporting¶
Common CI artifacts include:
(1) JUnit XML reports
(2) Coverage XML or HTML reports
(3) Logs from failed test cases
These artifacts support debugging and quality tracking.
Limitations and Constraints¶
Known Constraints¶
(1) Pytest does not enforce test isolation automatically
(2) Poor fixture design can lead to hidden coupling
(3) Excessive test runtime impacts CI feedback loops
Tip
Operational best practices
(1) Keep unit tests fast and isolated
(2) Push slow or external-dependency tests to integration scope
(3) Run the full test suite before release tagging