ZCore LogoZCore
Api reference

Testing Fixtures & Orchestrator

API reference for ZCore's composable testing fixtures managing IoC sandboxing, database rollbacks, context mocking, and lifespans.

ZCore provides a suite of composable test fixtures (ZTestFixture subclasses) that isolate your tests by managing state setup and teardown. ZTestClient orchestrates these internally, but you can compose them directly for bespoke test setups.

Base Class: ZTestFixture

Abstract base class for all testing fixtures:

from abc import ABC, abstractmethod

class ZTestFixture(ABC):
    @abstractmethod
    async def setUp(self) -> None: ...

    @abstractmethod
    async def tearDown(self) -> None: ...

Built-in Fixtures

ContainerSandbox

Takes a snapshot of container._singletons, _scoped_definitions, and _factories during setUp and restores them during tearDown. Guarantees that mock services registered during a test do not leak into subsequent tests.

from zcore.testing import ContainerSandbox

sandbox = ContainerSandbox()

EventDispatcherSandbox

Snapshots all registered subscribers on EventDispatcher during setUp and restores them during tearDown. Prevents event listeners or handlers registered dynamically in one test from leaking into subsequent test suites.

from zcore.testing import EventDispatcherSandbox

# Resolves EventDispatcher automatically from IoC container if dispatcher is None
event_sandbox = EventDispatcherSandbox(dispatcher=None)

Prop

Type


DatabaseRollback

Provides a lightning-fast database testing strategy using nested savepoints without dropping tables or running migrations. Supports both native DatabaseManager configurations and custom engines with dependency overrides.

from zcore.testing import DatabaseRollback

db_rollback = DatabaseRollback(
    engine=None,           # Custom AsyncEngine (defaults to db_manager._engine)
    db_dependency=None,    # Target dependency callable(s) to override
    app=None               # FastAPI application requiring dependency overrides
)

Prop

Type

The Savepoint Pipeline:

  1. Opens an asynchronous connection on the target engine (db_manager._engine or explicit engine).
  2. Begins a root transaction on that connection.
  3. Instantiates an AsyncSession with join_transaction_mode="create_savepoint".
  4. Registers this session as the active scoped instance in the IoCContainer, mocks db_manager.session, and overrides any configured db_dependency on app.
  5. On tearDown, it rolls back the root transaction, closes the connection, and restores original session providers.

UserContext

Injects mock user metadata into the request-scoped _request_context_store during setUp and resets the contextvars.Token on tearDown.

import uuid
from zcore.testing import UserContext

user_fixture = UserContext(
    user_id=uuid.uuid4(),
    scopes=["tasks:view", "tasks:create"],
    is_superuser=False,
    extra_context={"restricted_fields": ["tasks.view.salary"]}
)

Prop

Type


DependencyOverride

Wraps FastAPI's app.dependency_overrides dictionary. Applies the override during setUp and safely removes it during tearDown.

from zcore.testing import DependencyOverride
from zcore.security import get_current_user_stub

override_fixture = DependencyOverride(
    app=app,
    stub=get_current_user_stub,
    override_func=mock_user_callable
)

Prop

Type


AppLifespan

Manages the FastAPI application lifespan context during testing. Enters app.router.lifespan_context during setUp (triggering plugin startup hooks) and exits it during tearDown (triggering shutdown hooks).

from zcore.testing import AppLifespan

lifespan_fixture = AppLifespan(app=app)

Prop

Type


The ZTest Meta-Orchestrator

A composite fixture that chains multiple ZTestFixture instances, executing setUp in sequential order and tearDown in reversed dependency order:

from zcore.testing import (
    AppLifespan,
    ContainerSandbox,
    DatabaseRollback,
    EventDispatcherSandbox,
    UserContext,
    ZTest,
)

orchestrator = ZTest(
    ContainerSandbox(),
    EventDispatcherSandbox(),
    AppLifespan(app),
    DatabaseRollback(),
    UserContext(user_id=mock_id, scopes=["admin"])
)

# In your custom test runner:
await orchestrator.setUp()
try:
    # Run assertions
    pass
finally:
    # Tears down in reverse order cleanly
    await orchestrator.tearDown()

On this page