Fixture scope with parallel tests in PyTest - Build an Automation Script
import pytest setup_counter = 0 teardown_counter = 0 @pytest.fixture(scope='module') def resource(): global setup_counter setup_counter += 1 print(f'Setup called {setup_counter} time(s)') yield global teardown_counter teardown_counter += 1 print(f'Teardown called {teardown_counter} time(s)') def test_one(resource): assert True def test_two(resource): assert True if __name__ == '__main__': import subprocess # Run pytest with 2 parallel workers result = subprocess.run(['pytest', '-n', '2', '--capture=no'], capture_output=True, text=True) print(result.stdout) # Check output for setup/teardown counts setup_runs = result.stdout.count('Setup called') teardown_runs = result.stdout.count('Teardown called') assert setup_runs == 2, f'Expected 2 setup calls, got {setup_runs}' assert teardown_runs == 2, f'Expected 2 teardown calls, got {teardown_runs}' assert 'failed' not in result.stdout.lower(), 'Some tests failed'
This code defines a pytest fixture resource with module scope. It increments counters and prints messages when setup and teardown run.
Two test functions use this fixture. When running with pytest-xdist using 2 workers (-n 2), the fixture setup and teardown run once per worker, so twice total.
The __main__ block runs pytest programmatically with parallel workers and captures output. It counts how many times the setup and teardown messages appear to verify the fixture scope behavior.
Assertions check that both tests pass and the fixture setup/teardown run exactly twice, matching the expected behavior for module scope with parallel workers.
This approach helps beginners see how fixture scope affects parallel test runs and how to verify it.
Now add data-driven testing with 3 different inputs using the same fixture and verify fixture setup runs only twice total