Database rollback fixtures help keep tests clean by undoing database changes after each test. This stops tests from affecting each other.
Database rollback fixtures in PyTest
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
PyTest
import pytest @pytest.fixture def db_rollback_fixture(db_session): transaction = db_session.begin_nested() yield db_session transaction.rollback()
The fixture starts a nested transaction before the test.
After the test, it rolls back all changes made during the test.
Examples
PyTest
import pytest @pytest.fixture def rollback(db): trans = db.begin() yield db trans.rollback()
PyTest
import pytest @pytest.fixture def rollback_fixture(session): session.begin_nested() yield session session.rollback()
Sample Program
This example shows a fake database session with a rollback fixture. The first test adds data, which is rolled back after the test. The second test confirms the data is empty, showing rollback worked.
PyTest
import pytest class FakeDBSession: def __init__(self): self.data = [] self.transaction_active = False def begin_nested(self): self.transaction_active = True print('Transaction started') def rollback(self): if self.transaction_active: self.data.clear() self.transaction_active = False print('Transaction rolled back') @pytest.fixture def db_session(): return FakeDBSession() @pytest.fixture def db_rollback_fixture(db_session): db_session.begin_nested() yield db_session db_session.rollback() def test_add_data(db_rollback_fixture): db_rollback_fixture.data.append('test item') assert 'test item' in db_rollback_fixture.data def test_data_is_clean(db_rollback_fixture): assert db_rollback_fixture.data == []
Important Notes
Use rollback fixtures to keep tests independent and reliable.
Nested transactions are common for rollback in tests.
Make sure your database supports transactions for rollback to work.
Summary
Rollback fixtures undo database changes after each test.
This keeps tests isolated and repeatable.
They make tests faster and easier to maintain.
Practice
1. What is the main purpose of a database rollback fixture in pytest?
easy
Solution
Step 1: Understand the role of rollback fixtures
Rollback fixtures undo any changes made to the database during a test to keep tests isolated.Step 2: Compare options with rollback purpose
Only To undo database changes after each test to keep tests independent describes undoing changes after tests, which matches rollback behavior.Final Answer:
To undo database changes after each test to keep tests independent -> Option DQuick Check:
Rollback fixture purpose = undo changes [OK]
Hint: Rollback means undo changes after test [OK]
Common Mistakes:
- Confusing rollback with speeding up queries
- Thinking rollback creates tables
- Assuming rollback saves data permanently
2. Which of the following is the correct way to define a pytest fixture that rolls back database changes after a test?
easy
Solution
Step 1: Understand yield usage in fixtures
Yield separates setup (before yield) and teardown (after yield) in pytest fixtures.Step 2: Identify correct order for rollback
Setup happens before yield, rollback (cleanup) after yield. @pytest.fixture def db_fixture(): setup_db() yield rollback_db() follows this order.Final Answer:
@pytest.fixture\ndef db_fixture():\n setup_db()\n yield\n rollback_db() -> Option AQuick Check:
Setup before yield, rollback after yield [OK]
Hint: Setup before yield, cleanup after yield [OK]
Common Mistakes:
- Placing rollback before yield
- Calling setup after yield
- Not using yield at all
3. Given this pytest fixture and test, what will be the final count of records in the database after the test runs?
@pytest.fixture
def db_fixture():
connect_db()
yield
rollback_db()
def test_add_record(db_fixture):
add_record_to_db('test')
assert count_records() == 1
medium
Solution
Step 1: Understand fixture behavior with yield
The fixture sets up connection, yields control to test, then rolls back changes after test finishes.Step 2: Analyze test effect on database
The test adds one record and asserts count is 1 during test, but rollback removes it after test.Final Answer:
0 -> Option AQuick Check:
Rollback clears changes after test [OK]
Hint: Rollback clears test changes after test ends [OK]
Common Mistakes:
- Assuming record stays after test
- Confusing assert inside test with final state
- Thinking rollback happens before test
4. You wrote this fixture but your database changes are not rolling back after tests:
@pytest.fixture
def db_fixture():
setup_db()
rollback_db()
yield
What is the main problem?medium
Solution
Step 1: Check order of setup, yield, and rollback
Rollback must happen after yield to undo changes after test runs.Step 2: Identify error in fixture code
Rollback is called before yield, so changes are undone before test, not after.Final Answer:
Rollback is called before yield, so changes are undone before test runs -> Option CQuick Check:
Rollback after yield for cleanup [OK]
Hint: Rollback must be after yield to undo test changes [OK]
Common Mistakes:
- Calling rollback before yield
- Forgetting yield entirely
- Calling setup after yield
5. You want to write a pytest fixture that starts a database transaction before each test and rolls it back after, ensuring tests run fast and isolated. Which fixture code correctly achieves this behavior?
hard
Solution
Step 1: Understand transaction lifecycle in fixtures
Start transaction before yield to begin test with transaction active.Step 2: Rollback after yield to undo changes after test
Rollback must happen after yield to clean up changes made during test.Final Answer:
@pytest.fixture\ndef db_transaction():\n start_transaction()\n yield\n rollback_transaction() -> Option BQuick Check:
Start before yield, rollback after yield [OK]
Hint: Start transaction before yield, rollback after yield [OK]
Common Mistakes:
- Calling rollback before yield
- Calling start_transaction after yield
- Not using yield to separate setup and cleanup
