ZCore LogoZCore
Api reference

ZTestClient & BaseZTest

API reference for ZTestClient and BaseZTest providing zero-boilerplate async integration testing and transaction isolation.

ZTestClient is an asynchronous test orchestrator wrapping httpx.AsyncClient. It coordinates the entire ZCore runtime lifecycle (IoC container sandboxing, event subscriber snapshots, savepoint database rollbacks, and request context mocking) for seamless, zero-boilerplate integration testing.

Class Definition

from collections.abc import Sequence
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncEngine
from zcore.testing import ZTestClient

class ZTestClient:
    def __init__(
        self,
        app: FastAPI,
        user_id: Any | None = None,
        scopes: list[str] | None = None,
        is_superuser: bool = False,
        use_db: bool = True,
        engine: AsyncEngine | None = None,
        db_dependency: Any | Sequence[Any] | None = None,
        user_dependency: Any | Sequence[Any] | None = None,
        user_model: type[BaseModel] | None = None,
        extra_context: dict[str, Any] | None = None,
        extra_user_attrs: dict[str, Any] | None = None,
    ) -> None:
        ...

Initialization Parameters

Prop

Type


Context Manager Protocol

ZTestClient implements the asynchronous context manager protocol (__aenter__ and __aexit__), returning a fully configured httpx.AsyncClient bound to the application:

import pytest
import uuid
from zcore.testing import ZTestClient
from main import app

@pytest.mark.asyncio
async def test_create_task_endpoint():
    user_id = uuid.uuid4()
    
    async with ZTestClient(
        app=app, 
        user_id=user_id, 
        scopes=["tasks:create", "tasks:view"],
        use_db=True
    ) as client:
        # Executes HTTP requests against the application transport
        response = await client.post("/tasks/", json={"title": "Write Unit Tests"})
        assert response.status_code == 201
        
    # Database changes are automatically rolled back and IoC sandboxes are restored here!

Class-Based Testing: BaseZTest

An abstract base class for structuring declarative test suites sharing identical user attributes and application setups:

from collections.abc import Sequence
from typing import Any
from fastapi import FastAPI
from pydantic import BaseModel
from sqlalchemy.ext.asyncio import AsyncEngine
from zcore.testing import BaseZTest

class BaseZTest(ABC):
    app: FastAPI = None
    user_id: Any = None
    is_active: bool = True
    is_superuser: bool = False
    scopes: list[str] | None = None
    engine: AsyncEngine | None = None
    db_dependency: Any | Sequence[Any] | None = None
    user_dependency: Any | Sequence[Any] | None = None
    user_model: type[BaseModel] | None = None
    extra_user_attrs: dict[str, Any] | None = None
    extra_context: dict[str, Any] | None = None

Prop

Type

run Method

An asynchronous context manager method on BaseZTest that instantiates ZTestClient using the class-level attributes and yields the httpx.AsyncClient:

import pytest
from zcore.testing import BaseZTest
from main import app

class TestTaskSuite(BaseZTest):
    app = app
    scopes = ["tasks:view", "tasks:create"]

    @pytest.mark.asyncio
    async def test_get_tasks_list(self):
        async with self.run() as client:
            res = await client.get("/tasks/")
            assert res.status_code == 200

Orchestrated Internal Fixtures: ZTestClient automatically coordinates ContainerSandbox (IoC isolation), EventDispatcherSandbox (event subscriber isolation), AppLifespan (plugin startup/shutdown lifespans), DatabaseRollback (savepoint transactions), UserContext (ContextVar store injection), and DependencyOverride (get_current_user_stub, get_optional_user_stub, and any custom targets) on every test run.

On this page