Bird
Raised Fist0
PyTesttesting~10 mins

Database rollback fixtures in PyTest - Interactive Code Practice

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to define a pytest fixture that rolls back database changes after each test.

PyTest
import pytest

@pytest.fixture
 def db_session():
     session = create_session()
     yield session
     session.[1]()
Drag options to blanks, or click blank then click option'
Acommit
Bflush
Cclose
Drollback
Attempts:
3 left
💡 Hint
Common Mistakes
Using commit instead of rollback causes changes to persist.
Using close does not undo changes.
Using flush only sends changes but does not rollback.
2fill in blank
medium

Complete the code to use the fixture in a test function that queries the database.

PyTest
def test_user_count(db_session):
     count = db_session.query(User).count()
     assert count [1] 0
Drag options to blanks, or click blank then click option'
A==
B>=
C<
D!=
Attempts:
3 left
💡 Hint
Common Mistakes
Using > or >= may pass if users exist, but test expects empty.
Using != may allow unexpected counts.
Using < is incorrect for count checks.
3fill in blank
hard

Fix the error in the fixture to ensure the session is properly closed after rollback.

PyTest
@pytest.fixture
def db_session():
    session = create_session()
    yield session
    session.rollback()
    session.[1]
Drag options to blanks, or click blank then click option'
Acommit()
Bflush()
Cclose()
Drefresh()
Attempts:
3 left
💡 Hint
Common Mistakes
Calling commit after rollback is contradictory.
Flush does not close the session.
Refresh reloads objects but does not close session.
4fill in blank
hard

Fill both blanks to create a fixture that starts a transaction and rolls it back after the test.

PyTest
@pytest.fixture
def transactional_db():
    connection = engine.connect()
    transaction = connection.[1]()
    session = Session(bind=connection)
    yield session
    session.[2]()
    transaction.rollback()
    connection.close()
Drag options to blanks, or click blank then click option'
Abegin
Bcommit
Crollback
Dclose
Attempts:
3 left
💡 Hint
Common Mistakes
Using rollback to start transaction is incorrect.
Not committing session before rollback can cause errors.
Closing connection before rollback causes errors.
5fill in blank
hard

Fill all three blanks to implement a fixture that uses savepoint for nested rollback.

PyTest
@pytest.fixture
def savepoint_db():
    connection = engine.connect()
    transaction = connection.begin()
    savepoint = connection.[1]()
    session = Session(bind=connection)
    yield session
    session.[2]()
    savepoint.[3]()
    transaction.rollback()
    connection.close()
Drag options to blanks, or click blank then click option'
Abegin_nested
Bcommit
Crollback
Dclose
Attempts:
3 left
💡 Hint
Common Mistakes
Using rollback to create savepoint is wrong.
Not rolling back savepoint causes changes to persist.
Closing connection before rollback causes errors.

Practice

(1/5)
1. What is the main purpose of a database rollback fixture in pytest?
easy
A. To permanently save test data for later use
B. To speed up database queries during tests
C. To create new database tables before tests
D. To undo database changes after each test to keep tests independent

Solution

  1. Step 1: Understand the role of rollback fixtures

    Rollback fixtures undo any changes made to the database during a test to keep tests isolated.
  2. 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.
  3. Final Answer:

    To undo database changes after each test to keep tests independent -> Option D
  4. Quick 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
A. @pytest.fixture def db_fixture(): setup_db() yield rollback_db()
B. @pytest.fixture def db_fixture(): rollback_db() yield setup_db()
C. @pytest.fixture def db_fixture(): yield setup_db() rollback_db()
D. @pytest.fixture def db_fixture(): setup_db() rollback_db() yield

Solution

  1. Step 1: Understand yield usage in fixtures

    Yield separates setup (before yield) and teardown (after yield) in pytest fixtures.
  2. 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.
  3. Final Answer:

    @pytest.fixture\ndef db_fixture():\n setup_db()\n yield\n rollback_db() -> Option A
  4. Quick 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
A. 0
B. Raises an error
C. 1
D. Depends on previous tests

Solution

  1. Step 1: Understand fixture behavior with yield

    The fixture sets up connection, yields control to test, then rolls back changes after test finishes.
  2. 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.
  3. Final Answer:

    0 -> Option A
  4. Quick 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
A. Yield is missing, so fixture never runs
B. Setup_db should be called after yield
C. Rollback is called before yield, so changes are undone before test runs
D. Rollback_db should be called twice for safety

Solution

  1. Step 1: Check order of setup, yield, and rollback

    Rollback must happen after yield to undo changes after test runs.
  2. Step 2: Identify error in fixture code

    Rollback is called before yield, so changes are undone before test, not after.
  3. Final Answer:

    Rollback is called before yield, so changes are undone before test runs -> Option C
  4. Quick 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
A. @pytest.fixture def db_transaction(): yield start_transaction() rollback_transaction()
B. @pytest.fixture def db_transaction(): start_transaction() yield rollback_transaction()
C. @pytest.fixture def db_transaction(): start_transaction() rollback_transaction() yield
D. @pytest.fixture def db_transaction(): rollback_transaction() start_transaction() yield

Solution

  1. Step 1: Understand transaction lifecycle in fixtures

    Start transaction before yield to begin test with transaction active.
  2. Step 2: Rollback after yield to undo changes after test

    Rollback must happen after yield to clean up changes made during test.
  3. Final Answer:

    @pytest.fixture\ndef db_transaction():\n start_transaction()\n yield\n rollback_transaction() -> Option B
  4. Quick 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