Skip to content

Testing

  • Start here: Call recorder
  • Common recipes: record(backend) instruments a backend and returns a CallLog. Assert with log.count(method, **kwargs).

grelmicro.testing

Test helpers for asserting on protocol-level interactions.

record(backend) instruments a backend's public async methods in place and returns a CallLog. The backend keeps its real type and behavior, so it drops into a component exactly as before, while the log captures every call for assertions, in the spirit of pytest-mock's mocker.spy.

from grelmicro.coordination.memory import MemoryLockAdapter
from grelmicro.testing import record

backend = MemoryLockAdapter()
log = record(backend)
micro = Grelmicro(uses=[Coordination(lock=backend)])

async with micro:
    await login("u1")

assert log.count("acquire", name="user:u1") == 1

CallLog dataclass

CallLog(calls: list[Call] = list())

Records calls made to an instrumented backend.

Returned by record(...). Exposes the raw calls list plus helpers to assert on what was called.

calls class-attribute instance-attribute

calls: list[Call] = field(default_factory=list)

Every recorded call, in order.

count

count(
    method: str | None = None,
    args: tuple | None = None,
    **kwargs: Any,
) -> int

Return how many recorded calls match method, args, and kwargs.

A call matches when its method equals method (when given), its positional arguments equal args (when given), and every item in kwargs equals the recorded keyword argument of the same name.

PARAMETER DESCRIPTION
method

Method name to match, or None to count every call.

TYPE: str | None DEFAULT: None

args

Positional arguments to match, or None to skip the check.

TYPE: tuple | None DEFAULT: None

methods

methods() -> list[str]

Return the method names of every recorded call, in order.

reset

reset() -> None

Drop every recorded call.

Call dataclass

Call(
    method: str,
    args: tuple = tuple(),
    kwargs: Mapping[str, Any] = dict(),
)

One recorded protocol call.

method instance-attribute

method: str

Name of the method that was called.

args class-attribute instance-attribute

args: tuple = field(default_factory=tuple)

Positional arguments the method was called with.

kwargs class-attribute instance-attribute

kwargs: Mapping[str, Any] = field(default_factory=dict)

Keyword arguments the method was called with.

record

record(backend: object) -> CallLog

Instrument backend's public async methods and return their CallLog.

Each public coroutine method (one whose name does not start with _) is replaced on the instance with a wrapper that records the call and forwards to the original. The class and other instances are untouched.

PARAMETER DESCRIPTION
backend

The backend instance to instrument. Its public async methods are wrapped in place, so the same instance keeps its type and behavior.

TYPE: object