issue_519.py
Overview
This file contains pytest test fixtures and tests designed to demonstrate and verify the order and scoping behavior of parameterized fixtures in pytest. It specifically tests how fixtures with different scopes (`session`, `module`, and `function`) interact when parameterized and combined in tests. The tests and fixtures track the invocation order and parameter values used, asserting that pytest’s parameterized fixture expansion and scoping behave as expected.
The core functionality centers around:
Parameterizing tests with multiple values.
Using fixtures with different scopes that depend on each other.
Collecting and asserting the order in which fixtures and tests are executed.
Outputting the collected execution order for inspection.
Detailed Explanation of Components
Functions
pytest_generate_tests(metafunc)
Purpose:
A pytest hook function that dynamically generates parameter sets to be used in test functions.Parameters:
metafunc(pytest.Metafunc): Provided by pytest, contains information about the requesting test function.
Behavior:
If the test function requires a fixture or parameter named
"arg1", it parametrizes"arg1"with the values ["arg1v1", "arg1v2"] at the module scope (shared across tests in a module).If the test requires
"arg2", it parametrizes"arg2"with ["arg2v1", "arg2v2"] at the function scope (separately for each test function call).
Returns:
None (modifiesmetafuncin place).Usage Example:
This function is called automatically by pytest during test collection and parameterization.
Fixtures
checked_order
Scope:
sessionPurpose:
Collects tuples representing the order of fixture and test execution, along with the parameters involved, to verify pytest’s execution order.Type: Yields a list of 3-tuples:
(str, str, str)
Each tuple consists of:The name of the test or fixture node currently executing.
The name of the fixture being recorded (
"fix1"or"fix2"or the file name"issue_519.py").The parameter value associated with that fixture or test.
Behavior:
Initially yields an empty list.
After all tests complete, pretty-prints the collected list and asserts the exact expected order of execution.
Example Value After Test Run:
[ ("issue_519.py", "fix1", "arg1v1"), ("test_one[arg1v1-arg2v1]", "fix2", "arg2v1"), ("test_two[arg1v1-arg2v1]", "fix2", "arg2v1"), ("test_one[arg1v1-arg2v2]", "fix2", "arg2v2"), ("test_two[arg1v1-arg2v2]", "fix2", "arg2v2"), ("issue_519.py", "fix1", "arg1v2"), ("test_one[arg1v2-arg2v1]", "fix2", "arg2v1"), ("test_two[arg1v2-arg2v1]", "fix2", "arg2v1"), ("test_one[arg1v2-arg2v2]", "fix2", "arg2v2"), ("test_two[arg1v2-arg2v2]", "fix2", "arg2v2"), ]
fix1(request, arg1, checked_order)
Scope:
modulePurpose:
A module-scoped fixture that depends on the parameterarg1and records its invocation order.Parameters:
request(pytest.FixtureRequest): Provides information about the requesting test function/fixture.arg1(str): The parameter value generated bypytest_generate_tests.checked_order(list): The shared list to record order of execution.
Behavior:
Appends a tuple with the current node name,
"fix1"label, and thearg1parameter value tochecked_order.Yields a string
"fix1-"concatenated with thearg1value.
Returns:
Yields astrof the form"fix1-<arg1>".Usage Example:
def test_example(fix1): assert fix1.startswith("fix1-")
fix2(request, fix1, arg2, checked_order)
Scope:
functionPurpose:
A function-scoped fixture that depends onfix1and the parameterarg2, recording invocation order and combining parameter values.Parameters:
request(pytest.FixtureRequest): Context of the requesting test.fix1(str): Value yielded by thefix1fixture.arg2(str): Parameter value generated bypytest_generate_tests.checked_order(list): Shared list for recording execution order.
Behavior:
Appends a tuple with the current node name,
"fix2"label, and thearg2parameter value tochecked_order.Yields a string
"fix2-"concatenated with thearg2value and the string returned byfix1.
Returns:
Yields astrof the form"fix2-<arg2>fix1-<arg1>".Usage Example:
def test_example(fix2): assert fix2.startswith("fix2-")
Test Functions
test_one(fix2)
Purpose:
A test function depending onfix2fixture, used to verify the fixture setup and parameterization.Behavior:
Does nothing (
pass), since the test focus is on fixture behavior and invocation order.
Parameters:
fix2(str): The output of thefix2fixture.
test_two(fix2)
Same as
test_one, but a separate test function to exercise multiple test cases with different parameter combinations.
Implementation Details and Algorithms
Parameterized Fixture Expansion:
Thepytest_generate_testshook manually provides parameters for"arg1"and"arg2". The combination of these parameters and fixture scopes causes pytest to generate multiple tests:"arg1"is parameterized at module scope — so for each value ofarg1, the module-scoped fixtures run once."arg2"is parameterized at function scope — so for each test function, and for eacharg2parameter, the function-scoped fixtures run.
Execution Order Tracking:
Thechecked_orderfixture is a session-scoped mutable list shared across all tests. Fixtures append tuples recording their execution context (test or fixture name, fixture label, parameter value) to this list. After all tests run, the list is printed and asserted against the expected order, verifying that pytest expands and executes parameterized fixtures as expected.Fixture Interdependencies:
fix2depends onfix1andarg2, showing how fixtures can build on each other, combining multiple parameters from different scopes.
Interaction with Other System Components
This file is a standalone pytest test module intended to be run with pytest.
It interacts primarily with the pytest testing framework, especially:
pytest_generate_testshook for dynamic parameterization.Fixtures with different scopes (
session,module,function).The test runner that executes the tests and manages fixture lifecycles and parametrization.
No external modules or application logic are invoked; this file serves as a test and demonstration of pytest’s fixture and parameterization behavior, possibly as part of a larger test suite validating pytest itself or complex test scenarios.
Usage Example
From the command line, run tests with:
pytest issue_519.py -v
This will execute `test_one` and `test_two` with all combinations of `arg1` and `arg2`. After tests complete, the `checked_order` fixture prints the recorded execution order and asserts the expected order.
Visual Diagram
classDiagram
class pytest_generate_tests {
+metafunc
+parametrize(arg1 or arg2)
}
class checked_order {
+list[tuple(str,str,str)] order
+yield order
+assert order
}
class fix1 {
+request
+arg1
+checked_order
+yield "fix1-" + arg1
}
class fix2 {
+request
+fix1
+arg2
+checked_order
+yield "fix2-" + arg2 + fix1
}
class test_one {
+fix2
}
class test_two {
+fix2
}
pytest_generate_tests --> fix1 : parametrize "arg1"
pytest_generate_tests --> fix2 : parametrize "arg2"
fix1 --> checked_order : append (node, fix1, arg1)
fix2 --> checked_order : append (node, fix2, arg2)
fix2 --> fix1 : depends on
test_one --> fix2 : uses
test_two --> fix2 : uses
checked_order : shared session fixture
Summary
This file demonstrates advanced pytest fixture usage with parameterization and scoping. Through careful tracking of fixture invocation order and parameters, it validates pytest’s execution model when combining module- and function-scoped fixtures with parameter sets. It serves as a useful reference or test case for pytest behavior verification.