Plugins
pytest is designed to be highly extensible. While the core framework is powerful, its plugin system allows you to add new features or modify existing behavior to suit your specific testing needs.
A plugin is essentially Python code that implements one or more pytest "hooks" (functions named pytest_*) or provides additional fixtures, markers, or behavior. Plugins allow you to customize pytest without modifying its source code. They can:
- Add new fixtures (many built-in fixtures such as
tmp_pathandmonkeypatchcome from plugins). - Add new command-line options and modify test execution behavior.
- Modify test collection or filtering.
- Add custom reports or logging.
- Integrate with external tools (e.g., coverage, asyncio, benchmarking, Docker, Flask)
pytest maintains a rich ecosystem of community plugins. The complete list can be browsed at pytest plugin index.
Writing your own plugin
The simplest way to create your own plugin is to define a pytest "hook" function in your project's conftest.py file. Such plugins are known as local plugins, and they are ideal for project-specific customization.
# conftest.py
import pytest
# A simple hook implementation (plugin)
def pytest_addoption(parser):
parser.addoption("--env", action="store", default="dev", help="env to run tests against")
@pytest.fixture
def env_config(request):
return request.config.getoption("--env")This plugin adds a custom CLI option (--env) and exposes a fixture (env_config) that any test can consume.
Creating an installable plugin
If you want to reuse a plugin across multiple projects or publish it for others, you can package it as a standalone installable plugin. A standalone plugin is typically a single Python module or package, such as:
myplugin/
__init__.py
hooks.py
pyproject.tomlThe key step is to register your plugin as an entry point inside pyproject.toml:
[project]
name = "pytest-myplugin"
version = "0.1.0"
[project.entry-points."pytest11"]
myplugin = "myplugin.hooks"The pytest11 entry point group tells pytest to automatically load your plugin when installed.
Once packaged, users can enable it simply by installing it:
pip install pytest-mypluginTesting your plugin
pytest provides the pytester (or testdir) fixture to help you test plugins in isolation. It lets you create temporary test files, run pytest with your plugin active, and inspect results.
# conftest.py (in your plugin's test folder)
pytest_plugins = ["pytester"]
# test_myplugin.py
def test_custom_option(pytester):
# Create a test file that uses the plugin
pytester.makepyfile("""
def test_example(env_config):
assert env_config in ("dev", "prod")
""")
# Run pytest with a custom CLI option
result = pytester.runpytest("--env=prod")
result.assert_outcomes(passed=1)Distributing your plugin
To publish your plugin:
- Build your package:
python -m build- Upload it to PyPI:
twine upload dist/*- Include documentation:
- Installation instructions.
- Usage examples.
- List of provided hooks, fixtures, or options.
- Add the appropriate PyPI classifier so your plugin appears in the official pytest plugin index:
classifiers = ["Framework :: pytest"]- Users can then install your plugin with
pip.
