Integration tests are essential for catching bugs that unit tests miss—but they come with a notorious problem: shared state. When tests share a database, they become flaky, order-dependent, and painful to debug.

What if each test could start with a clean slate, with exactly the data it needs, without manual cleanup or complex fixtures?

That's what pytest-scenarios does.

The Problem

Consider testing an e-commerce checkout system. You need to verify that:

  • Active customers can complete orders
  • Suspended customers are rejected
  • Out-of-stock items fail gracefully

Each scenario requires different data. With traditional approaches, you either share fixtures (tests interfere), manually clean up (boilerplate hell), or use transaction rollbacks (complex and misses commit-time bugs).

The Solution: Declarative Test Scenarios

With pytest-scenarios, you declare what state you need, and the plugin handles the rest:

def test_checkout_rejects_suspended_customer(scenario_builder, db):
    # Arrange: Declare the scenario
    scenario_builder.create({
        "customers": [{"customer_id": "user_1", "status": "suspended"}],
        "products": [{"product_id": "item_1", "in_stock": True}],
        "orders": [{"id": "order_1", "customer_id": "user_1", ...}],
    })

    # Act: Run your business logic
    checkout = Checkout(db)
    result = checkout.process(order_id="order_1")

    # Assert: Verify the outcome
    assert result.success is False
    assert "not active" in result.error

No manual cleanup. No fixture dependencies. Each test is completely isolated.

Key Concepts

Templates Define Defaults

Define templates with sensible defaults—tests only override what matters:

# tests/templates/customers.py
TEMPLATE = {
    "name": "John Doe",
    "email": "john.doe@example.test",
    "status": "active",
}

Automatic Cleanup

The plugin clears all managed collections before each test. Even if a test fails, the next test starts fresh.

Real Database Testing

Tests run against a real MongoDB instance, catching issues that mocks would miss: query errors, index problems, schema mismatches.

Try It Yourself

I've created a complete runnable example that demonstrates pytest-scenarios with a simple e-commerce checkout system.

👉 View the example on GitHub

The example includes:

Quick Start

git clone https://github.com/carlosvin/pytest-scenarios.git
cd pytest-scenarios/examples

Then follow the instructions in the example README to run the tests.

Installation

pip install pytest-scenarios
# or
uv add pytest-scenarios

Configure in pyproject.toml:

[tool.pytest.ini_options]
db-url = "mongodb://127.0.0.1:27017"
db-name = "my_test_db"
templates-path = "tests/templates"

Learn More


Stop fighting flaky integration tests. Let pytest-scenarios handle the isolation while you focus on what matters: testing your business logic.