In pytest, what is the use of conftest.py files?
The file conftest.py
acts like an orchestration tool in the pytest
framework. Its key role is to define 'fixtures' that can be used across multiple test files to keep the code DRY (Don't Repeat Yourself) and maintain cleanliness. It also provides scope-based accessibility by allowing fixtures to behave differently based on where they are being called from.
Example:
What can conftest.py do for you?
Granularity via fixture scopes
conftest.py
shines when it comes to test environment setup. Roots fixtures — defined in the 'highest' conftest.py
— cascade down to all subdirectories. However, by having multiple conftest.py
files, you can define behavior at a directory level, providing scoped fixtures to the required tests.
Plugin loading
conftest.py
can serve as a plugin loader. This gives you an easy way to extend the functionality of pytest by importing external plugins, aiding you in creating a truly customizable test suite.
Manipulating test behaviors via hooks
pytest
provides a way to access and modify its internal operations using hook functions. conftest.py
is where you can define these hooks to modify pytest's default behaviors, endowing you with control of the test setup, management, and teardown.
Make it work for you
Custom test manipulations
The hook functions in conftest.py
are not mere spectators, they participate in the action. You can use them to manipulate how and when tests run — such as altering the test selection process, modifying test items pre-execution, or even skipping certain tests under specific conditions.
Visualizing fixture scopes
Understanding conftest.py
can be made easier by visualizing tests with fixture scopes mapped out like a network diagram. Specially if you are using pytest
with a larger project structure, such a view can give an overview of the interconnections and make managing fixtures easier.
Conftest.py and pytest.ini
The use of conftest.py
and pytest.ini
in tandem results in total control over your test environment. Defining the root directory in pytest.ini
guarantees consistent fixture discovery, keeping your test environment disciplined and ordered.
Lesser-known yet impactful aspects
Project structure based on test scope
Placing conftest.py
files strategically throughout your directory structure, mirroring fixture scopes, allows for a more manageable test suite. This way, the tests that need specific fixtures have access to them, while others remain unaffected.
Test clarity vs. import hassles
While the use of conftest.py
obviates the need for import clutter in test files, ensuring visibility into which tests use what fixtures is key for maintainability. Always look for the sweet spot!
Power and peril of hook functions
While hook functions allow unprecedented control over test execution, misuse can lead to unexpected side effects, reminiscent of those frustrating Heisenbugs
.
Overriding fixtures: Friend or foe?
Creating fixtures at different scopes in conftest.py
files can cause "fixture shadowing" where a local fixture overrides a parent fixture. It's a master of disguise, so keep an eye out!
Was this article helpful?