project-root/
├── tests/
│ ├── test_login.py
│ ├── test_cart.py
│ ├── test_checkout.py
│ └── conftest.py
├── src/
│ └── app_code.py
├── utils/
│ └── helpers.py
├── pytest.ini
└── requirements.txt
Test independence in PyTest - Framework Patterns
- Tests: Individual test files in
tests/folder. Each test is independent and does not rely on others. - Fixtures: Setup and teardown code in
conftest.pyto prepare test data or environment fresh for each test. - Utilities: Helper functions in
utils/helpers.pyto avoid repeating code inside tests. - Application Code: The main code under test in
src/app_code.py. - Configuration: pytest.ini for pytest settings and options.
Use pytest.ini to configure pytest options like markers and test paths.
Use conftest.py to define fixtures that provide fresh setup for each test, ensuring no shared state.
Example fixture for fresh user data:
import pytest
@pytest.fixture
def new_user():
return {"username": "testuser", "password": "pass123"}
Each test uses fixtures to get clean data and environment, avoiding dependencies between tests.
Use pytest built-in reporting with --junitxml=report.xml to generate XML reports.
Integrate with CI/CD tools (like GitHub Actions, Jenkins) to run tests on every code push.
Test independence ensures that failures are isolated and easy to diagnose in reports.
- Isolate Tests: Each test should run alone without relying on others.
- Use Fixtures: Setup fresh data and environment for each test using pytest fixtures.
- No Shared State: Avoid global variables or shared data that can cause side effects.
- Clear Setup and Teardown: Clean up after tests to avoid leftover data affecting others.
- Idempotent Tests: Running tests multiple times should produce the same result.
Where in this framework structure would you add a fixture that provides a fresh database connection for each test?
Practice
Solution
Step 1: Understand test independence concept
Test independence means each test runs alone without relying on others.Step 2: Identify why independence matters
This prevents tests from failing due to side effects or order, making results reliable.Final Answer:
It ensures tests do not affect each other and run reliably alone. -> Option CQuick Check:
Test independence = tests run alone [OK]
- Thinking tests must share data to be efficient
- Believing tests run only if previous tests pass
- Assuming test order controls correctness
Solution
Step 1: Identify setup features in pytest
Pytest runs setup code before each test usingsetup_methodorsetup_function.Step 2: Understand their role in test independence
Setup prepares fresh state for each test, avoiding shared state and keeping tests independent.Final Answer:
Usingsetup_methodorsetup_function-> Option AQuick Check:
Setup before each test =setup_method/setup_function[OK]
- Confusing parameterize with setup
- Using yield_fixture to share state incorrectly
- Skipping tests does not setup state
counter = 0
def test_first():
global counter
counter += 1
assert counter == 1
def test_second():
global counter
counter += 1
assert counter == 1Solution
Step 1: Analyze test_first behavior
Initially, counter=0. test_first increments to 1 and asserts counter == 1, so it passes.Step 2: Analyze test_second behavior
counter is now 1 from previous test. test_second increments to 2 and asserts counter == 1, which fails.Final Answer:
First test passes, second test fails -> Option AQuick Check:
Shared state causes second test failure [OK]
- Assuming counter resets automatically
- Thinking both tests run with fresh state
- Ignoring global variable effects
shared_list = []
def test_add_one():
shared_list.append(1)
assert len(shared_list) == 1
def test_add_two():
shared_list.append(2)
assert len(shared_list) == 1Solution
Step 1: Understand shared_list usage
shared_list is defined outside tests and not reset, so it keeps growing with each test.Step 2: Identify why independence breaks
Because shared_list is not cleared, test_add_two sees length 2, but asserts length 1, causing failure.Final Answer:
shared_list is not cleared between tests causing length to grow -> Option DQuick Check:
Shared mutable state without reset breaks independence [OK]
- Assuming pytest resets global variables automatically
- Changing assertions instead of fixing state
- Confusing parallel runs with shared state issues
Solution
Step 1: Understand database state isolation
To keep tests independent, each test should not affect others' database state.Step 2: Choose best isolation method
Using a fixture that creates a transaction and rolls back after each test resets database state, ensuring independence.Final Answer:
Use a fixture to create and rollback a transaction for each test -> Option BQuick Check:
Transaction rollback per test = independence [OK]
- Relying on test order for correctness
- Sharing global DB connection without isolation
- Skipping tests instead of fixing independence
Ready to prove it?
Pass the test and this pattern moves unknown
