Testing API
The Testing API provides utilities for testing Ascender Framework applications with pytest integration.
Core Components
Ascender Test Lifecycle
Manages the lifecycle of Ascender applications in test environments.
Key Methods:
- before_all(): Initialize application before test suite
- after_all(): Cleanup after all tests complete
- before_each(): Setup before each test
- after_each(): Cleanup after each test
Usage:
import pytest
from ascender.testing import AscenderTestLifecycle
@pytest.fixture(scope="session")
async def app():
    app = await create_application()
    lifecycle = AscenderTestLifecycle(app)
    await lifecycle.before_all()
    yield app
    await lifecycle.after_all()
AscenderTestLifecycle
__init__
__init__(app_module: type[AscModuleRef] | None = None, providers: list[Provider] | None = None) -> None
Ascender Testing Lifecycle Manager, it's mandatory to define it in conftests. Manages lifecycles from beginning of the tests and to end, initializes ascender framework's features and DI.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| app_module | AppModule | None | The application module to use. Defaults to None. | None | 
| providers | list[Provider] | None | The list of providers to use. Defaults to None. | None | 
Raises:
| Type | Description | 
|---|---|
| ValueError | If neither app_module nor providers is provided. | 
TestClient
HTTP test client for loading controllers, dependencies, guards and many other declarations and providers. Universal mock testing client.
__new__
Create a new instance of the test client.
A new instance with injected mocks for the specified dependencies on the framework dependency injection requirements.
from ascender.testing import TestClient, MockDependency
my_controller = TestClient(
    MyController,
    mocks={
        MyService: MockDependency(
            get_data=lambda self: "mocked data"
        )
    }
)
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| _framework_dep | type[T] | The framework dependency to instantiate. | required | 
| mocks | Mapping[str | type, object | MockDependency | type] | A mapping of dependencies to their mock implementations. | required | 
Returns:
| Name | Type | Description | 
|---|---|---|
| T | T | An instance of the framework dependency with mocks applied. | 
            create_testing_module
  
      staticmethod
  
create_testing_module(imports: Sequence[type[AscModuleRef | ControllerRef]], declarations: Sequence[type[Any]], providers: MutableSequence[Provider], exports: Sequence[type[Any] | str], name: str | None = None) -> type[AscModuleRef]
Create a testing AscModule with the given imports, declarations, providers, and exports.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| imports | Sequence[type[AscModuleRef | ControllerRef]] | The modules or controllers to import. | required | 
| declarations | Sequence[type[Any]] | The declarations for the module. | required | 
| providers | MutableSequence[Provider] | The providers for the module. | required | 
| exports | Sequence[type[Any] | str] | The exports for the module. | required | 
| name | str | None | The name of the testing module (used as object name). Defaults to None. | None | 
Returns:
| Type | Description | 
|---|---|
| type[AscModuleRef] | type[AscModuleRef]: The created testing module reference. | 
Mixer
Pydantic model data generator with optional Faker integration and auto-inference by field name.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| extra_generators | dict[Any, Callable[..., Any]] | None | Mapping of custom generators (type → callable). | None | 
| enable_auto_faker | bool | if True, guesses faker generator from field name. | False | 
| extra_faker_map | dict[str, str] | None | additional field name→faker method mapping. | None | 
gen_by_type
FakerField
MockDependency
__init__
A lightweight mock utility for simulating dependencies in Ascender Framework tests.
MockDependency lets you create simple mock objects with dynamic attributes or methods, 
without requiring external mocking libraries.
These mocks can be used in Ascender's dependency injection system (via TestClient or TestInjector),
or as standalone mock objects.
Example:
mock_dep = MockDependency(
    method=lambda self: "mocked method",
    value=42
)
mock_obj = mock_dep._as_object("MyMock")
print(mock_obj.method())  # -> "mocked method"
print(mock_obj.value)     # -> 42
Attributes:
| Name | Type | Description | 
|---|---|---|
| values | dict[str, Any] | A mapping of attribute names to their mocked values or callables. | 
Use Case
- Designed for mocking Ascender Framework services or injectables in testing scenarios.
- Can also be used for lightweight mocking in any Python context.
Example Usage
Basic Test Setup
# src/tests/conftest.py
import pytest
from ascender.testing import AscenderTestLifecycle
lifecycle = AscenderTestLifecycle(providers=[])
def pytest_sessionstart(session: pytest.Session):
    """
    Initialize Ascender Framework testing lifecycle at the start of the pytest session.
    """
    lifecycle.begin_session(session)
@pytest.fixture(scope="function", autouse=True)
def ascender_app():
    """
    Lifecycle-managed Ascender Framework test fixture.
    Automatically runs before and after each test function.
    """
    lifecycle.before_test()
    yield lifecycle.application
    lifecycle.after_test()
def pytest_sessionfinish(session: pytest.Session, exitstatus: int):
    """
    Finalize Ascender Framework testing lifecycle at the end of the pytest session.
    """
    lifecycle.end_session()
Testing Controllers
# tests/test_user_controller.py
import pytest
from ascender.testing import TestClient, MockDependency, Mixer
from controllers.user_controller import UserController
from controllers.user_service import UserService
from dtos.users import UserDTO
from responses.users import UserResponse
@pytest.fixture
def client():
    client = TestClient(UserController, {
        UserService: MockDependency(
            find_by_id=lambda self, user_id: UserResponse(id=user_id, name="Test User"),
            create=lambda self, data: UserResponse(id=1, **data.model_dump())
        )
    })
    yield client
@pytest.mark.asyncio
async def test_get_user(client: UserController):
    """Test getting a user by ID."""
    response = await client.get_user(id=223)
    assert isinstance(response, UserResponse)
    assert response.id == 223
@pytest.mark.asyncio
async def test_create_user(client: UserController):
    """Test creating a new user."""
    response = await client.create_user(data=Mixer(enable_auto_faker=True).blend(UserDTO))
    assert response.status_code == 201
    assert "id" in response.json()
Using Mixer for Data Generation
from ascender.testing import Mixer, FakerField
from pydantic import BaseModel
class User(BaseModel):
    name: str
    email: str
    age: int
# Generate random user data
user_data = Mixer().blend(User)
print(user_data)  # User(name='John Doe', email='john@example.com', age=25)
# Generate with specific fields
user = Mixer().blend(User, name="Alice", age=30)
print(user)  # User(name='Alice', email='alice@example.com', age=30)
# Use Faker for specific patterns
class Product(BaseModel):
    name: str = FakerField("company")
    price: float = FakerField("pydecimal", left_digits=3, right_digits=2)
product = Mixer().blend(Product)
products = Mixer().blend_many(Product, 5)
print(len(products))  # 5
mixed = Mixer().blend_multiple([User, Product], count=3)
print(mixed)  # List of mixed User and Product instances
print(len(mixed)) # 3
Running Tests
# Run all tests
ascender run tests run
# Run specific test file
ascender run tests run --path src/tests/test_user_controller.py
# Run specific mark
ascender run tests run -m asyncio
# Run with coverage
pytest --cov=src --cov-report=html
# Run specific test
pytest src/tests/test_user_controller.py::test_get_user
You can use either ascender run tests run or pytest directly to execute your tests.
See Also
- Testing Guide - Comprehensive testing guide
- Test Client Documentation - Detailed TestClient usage
- Dependency Injection - DI system for testing