test_extend_fixture_module_class.py
Overview
This file contains a minimal pytest test module demonstrating how fixtures can be defined and extended within the same test file, particularly showcasing the interaction between module-level and class-level fixtures sharing the same name. The primary focus is to illustrate pytest's fixture resolution and overriding behavior when a class-level fixture shadows a module-level fixture.
The module defines:
A module-level fixture
spamreturning a string"spam".A test class
TestSpamwith:A class-level fixture also named
spamthat depends on the module-levelspamfixture and returns its doubled value.A test method
test_spamthat verifies the class-level fixture's output.
This setup is useful for understanding fixture scoping, overriding, and dependency injection in pytest.
Detailed Explanation
Module-level Fixture
@pytest.fixture
def spam():
return "spam"
Purpose: Provides a base fixture named
spamreturning the string"spam".Parameters: None.
Returns:
str— the string"spam".Usage: Can be injected into any test or fixture within the module.
Class: TestSpam
This test class contains a class-level fixture and a test method.
Class-level Fixture: spam
@pytest.fixture
def spam(self, spam):
return spam * 2
Purpose: Overrides the module-level
spamfixture within the scope of this test class.Parameters:
self: Standard instance reference for test classes.spam: The module-level fixture injected by pytest.
Returns:
str— the doubled string of the module-level fixture value (i.e.,"spamspam").Details: This fixture demonstrates fixture overriding; the class-level
spamfixture depends on the module-levelspamfixture and transforms its output.Usage: Injected into test methods within the class, replacing the module-level fixture value.
Test Method: test_spam
def test_spam(self, spam):
assert spam == "spamspam"
Purpose: Validates that the class-level fixture
spamcorrectly returns the doubled string.Parameters:
self: Instance reference.spam: The class-level fixture injected by pytest.
Assertions: Checks that
spam == "spamspam".Outcome: Passes if the fixture overriding and value transformation work as expected.
Implementation Details and Algorithms
Fixture Overriding Mechanism: Pytest allows fixtures to be overridden in narrower scopes. Here, the module-level fixture
spamis overridden by the class-level fixture with the same name insideTestSpam. The class-level fixture depends on the module-level fixture by requesting it as a parameter, allowing reuse and modification of the original fixture's return value.Fixture Injection: Pytest automatically injects fixtures into test methods or other fixtures based on their parameter names.
Test Execution Flow:
The module-level
spamfixture returns"spam".When
TestSpam.spamfixture is requested, pytest injects the module-levelspamfixture.The class-level fixture returns
"spamspam"by doubling the injected string.The test method asserts that this doubled string is as expected.
Interaction with Other Parts of the System
Pytest Test Runner: This file is designed to be run with the pytest framework. It relies on pytest's fixture discovery, dependency injection, and test execution mechanisms.
Fixture Scope and Resolution:
The module-level
spamfixture is available to all tests in this module.The class-level
spamfixture shadows the module-level one insideTestSpam.
Extensibility: Additional tests or fixtures can consume either the module-level or class-level fixture depending on their location and naming.
Usage Example
Running the tests in this file using:
pytest test_extend_fixture_module_class.py
Would yield:
collected 1 item
test_extend_fixture_module_class.py . [100%]
============================== 1 passed in 0.01s ==============================
This confirms that the fixture overriding works as intended.
Mermaid Class Diagram
classDiagram
class TestSpam {
+spam(self, spam): str
+test_spam(self, spam): None
}
class spam_fixture_module {
+spam(): str
}
TestSpam ..> spam_fixture_module : depends on
Explanation:
spam_fixture_modulerepresents the module-level fixturespam.TestSpam.spamfixture depends on the module-levelspam.TestSpam.test_spam uses the class-level
spamfixture.The arrow shows dependency from class-level fixture to module-level fixture.
Summary
This file serves as a concise example illustrating pytest's fixture overriding and scope resolution. It shows how a class-level fixture can reuse and extend a module-level fixture by injecting it as a parameter and modifying its return value. This pattern is useful for organizing tests with hierarchical fixture dependencies, enabling flexible and maintainable test code.