Python tutorials > Testing > pytest > What are pytest plugins?
What are pytest plugins?
pytest plugins are Python packages that extend and modify pytest's functionality. They allow you to customize test discovery, add new command-line options, modify test execution, and report results in custom formats. Think of them as building blocks that allow you to tailor pytest to fit the specific needs of your project or organization.
Understanding pytest Plugins
At its core, pytest operates through a plugin architecture. Almost everything pytest does - from collecting tests to running them and reporting results - is implemented through plugins. This makes pytest highly extensible. Plugins can be installed as regular Python packages and pytest will automatically discover and load them. Plugins interact with pytest via hooks. Hooks are functions that pytest calls at specific points during the test process. Plugin developers can implement these hook functions to modify pytest's behavior.
Types of pytest Plugins
There are three main types of pytest plugins:
conftest.py
file.
How pytest Finds Plugins
pytest discovers plugins in the following order:
setuptools
entry points.conftest.py
files: pytest automatically loads plugins defined in conftest.py
files in the test directory and its parent directories. This is how you would typically define local plugins for your project.
Creating a Simple Local Plugin (conftest.py)
This example shows how to create a simple local plugin in a conftest.py
file. It defines:
my_fixture
, which prints setup and teardown messages.--env
, which allows you to specify the environment to run tests against. The pytest_addoption
hook is used to add this option.
import pytest
@pytest.fixture
def my_fixture():
print("Setting up my_fixture")
yield "fixture_value"
print("Tearing down my_fixture")
def pytest_addoption(parser):
parser.addoption(
"--env", action="store", default="dev", help="environment to run tests against"
)
Using the Plugin in a Test
This test function uses the my_fixture
defined in the plugin and accesses the --env
command-line option through the request
object.
def test_my_plugin(my_fixture, request):
env = request.config.getoption("--env")
print(f"Running tests in {env} environment")
assert my_fixture == "fixture_value"
Real-Life Use Case: Database Connection Management
This example shows how to use a pytest plugin to manage database connections for testing. It defines two fixtures: This provides a clean and consistent way to manage database connections in your tests.
db_engine
: Creates a database engine (in this case, an in-memory SQLite database) for the entire test session.db_connection
: Creates a database connection for each test function and rolls back any changes made during the test to ensure isolation.
import pytest
import sqlalchemy
@pytest.fixture(scope="session")
def db_engine():
engine = sqlalchemy.create_engine("sqlite:///:memory:") # In-memory database for testing
yield engine
engine.dispose()
@pytest.fixture(scope="function")
def db_connection(db_engine):
connection = db_engine.connect()
transaction = connection.begin()
yield connection
transaction.rollback()
connection.close()
Best Practices
myproject_my_fixture
).
When to use them
Use pytest plugins when:
Alternatives
Alternatives to using pytest plugins include:
unittest
or nose
. However, pytest's plugin architecture is generally considered to be more flexible and powerful.
Pros
Cons
Interview Tip
When discussing pytest plugins in an interview, be prepared to talk about the different types of plugins (built-in, external, local), how pytest discovers plugins, and how you can use plugins to customize pytest's behavior. Give specific examples of plugins you have used or created in your projects. Being able to describe the pytest_addoption
hook and conftest.py
usage is very valuable.
FAQ
-
How do I install a pytest plugin?
You can install a pytest plugin using pip, just like any other Python package. For example:
pip install pytest-cov
-
How do I list all installed pytest plugins?
You can use the
pytest --version
command to list all installed pytest plugins. -
Where do I put my local pytest plugins?
You typically put your local pytest plugins in a
conftest.py
file in your test directory or its parent directories. -
Can I disable a plugin?
Yes, you can disable a plugin using the
-p no:plugin_name
command-line option or by addingpytest_plugins = ['-plugin_name']
to yourconftest.py
file.