Skip to content

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_path and monkeypatch come 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.

python
# 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:

markdown
myplugin/
    __init__.py
    hooks.py
pyproject.toml

The key step is to register your plugin as an entry point inside pyproject.toml:

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:

shell
pip install pytest-myplugin

Testing 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.

python
# 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:
shell
python -m build
  • Upload it to PyPI:
shell
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:
toml
classifiers = ["Framework :: pytest"]
  • Users can then install your plugin with pip.