Skip to content

Pytest Plugin

The pytest extension is organized under several subpackages:

Checker

zelos_sdk.pytest.checker

Checker pytest plugin.

Use via:

pytest_plugins = ["zelos_sdk.pytest.checker"]

The per-test :class:Checker board / artifact context is opened by the :func:agent fixture (see :mod:zelos_sdk.pytest.agent) — any test that requests agent (directly or transitively through check) gets capture activated for its body. Tests that don't request agent get no Checker context: zero side effects on unrelated suites.

The :data:check fixture is a thin convenience alias — it returns agent.check (the :class:zelos_sdk.agent.checks.Checks proxy) so test bodies can read check.that(...) instead of the longer agent.check.that(...). Capture is identical either way.

Checker(title=None, *, fail_fast=True, artifact_path=None)

Bases: ContextBase

Capture agent-mediated check results for board + artifact emission.

Args: title: Optional subtitle on the board header. Pytest fixture uses request.node.name for per-test labeling. fail_fast: When True (default) and any check fails, raise pytest.fail immediately. Implicitly disabled by the fixture when an artifact path is configured — truncated artifacts make poor diff inputs. artifact_path: Optional file path to emit the JSON artifact on close. None skips emission (board-only mode).

record(spec, result, *, address=None, display_lhs=None, display_rhs=None, from_background=False)

Capture one check result.

Called from :func:zelos_sdk.agent.checks._post_to_active_checker for every agent.check.that(...) / Checks.run(...) invocation that lands while this checker is active. spec is the canonical :class:CheckSpec (frozen pyclass with the typed lhs/rhs operand pair); address is the producer on multi-producer fan-out.

display_lhs / display_rhs are the human-readable operand names captured at spec-build time (for TraceSourceCacheLastField: the field's .name like "system_status.mode"). The wire spec only carries the captured literal value; these strings let the board render field.name (value) for cache-field asserts, matching the deprecated checker's layout. Both default to None when replaying suite-loaded or pre-built specs that lost the original operand reference.

track_background(thread)

Register a daemon polling thread to be joined at _close.

Spawned by agent.check.that(..., nonblocking=True) so the background duration loop has somewhere to flush its result — the fixture teardown waits for every tracked thread, so a failing background check still flips the pytest delayed-fail hook even though the test body returned non-blockingly.

check(agent)

Convenience alias: check.that(...) reads as agent.check.that(...).

The per-test :class:Checker board / artifact context is opened by the agent fixture itself — requesting check pulls in agent and so inherits the same capture lifecycle. Tests can pick whichever spelling reads better; both post to the same board / artifact.

Configuration knobs (consumed by the agent fixture):

  • @pytest.mark.check_config(fail_fast=False) — delay failure to end-of-test instead of raising on first failed check. The default is True: a failed predicate raises pytest.fail immediately so the test fails on the first violation.
  • --zelos-local-artifacts-dir DIR — artifact emission target; implicitly disables fail_fast (truncated artifacts make poor diff inputs).

pytest_runtest_call(item)

Delayed-fail hook for fail_fast=False checker sessions.

The agent fixture wraps the test body in a :class:Checker context, registering itself on :data:active_checker_var. After the test body returns we read that ContextVar (still bound at this point — the fixture's yield hasn't returned yet) to inspect the accumulated rows. Tests that didn't request agent leave the ContextVar at its default None and this hook is a no-op for them.

Trace

zelos_sdk.pytest.trace

Zelos Cloud trace plugin

Use via:

pytest_plugins = ["zelos_sdk.pytest.trace"]

pytest_addhooks(pluginmanager)

This example assumes the hooks are grouped in the 'hooks' module.

pytest_addoption(parser)

Parses flags that can enable/disable specific event handlers.

Parameters:

Name Type Description Default
parser Parser

A pytest Parser object to add the command-line options.

required

pytest_configure(config)

Initialize trace file tracking when pytest starts

zelos_session(request)

Initialize Zelos session-level fixtures.

Report

zelos_sdk.pytest.report

Report plugin for pytest.

Use via:

pytest_plugins = ["zelos_sdk.pytest.report"]

pytest_zelos_configure(config)

configure zelos report plugin

Plugins

zelos_sdk.pytest.plugins

agent(request, _agent_session)

Per-test :class:Agent handle with Checker capture activated.

Yields the session-scoped agent (one connection per pytest run — no per-test reconnect) wrapped in a function-scoped :class:zelos_sdk.pytest.checker.Checker context. Every agent.check.that(...) / check.that(...) call inside the test body posts its result to the rich-table board and (when --zelos-local-artifacts-dir is set) to the per-test JSON artifact at {dir}/{test_name}.checks.json.

Tests that don't request agent (or check, which depends on it) get no Checker context: no ContextVar binding, no board object, no artifact write, no behavior change. Capture is opt-in via fixture dependency — there is no autouse layer.

Configuration knobs:

  • --zelos-agent-url flag → ZELOS_AGENT_URL env → http://localhost:2300 (resolved once at session start).
  • @pytest.mark.check_config(fail_fast=False) — delay failure to end-of-test instead of raising on first failed check.
  • --zelos-local-artifacts-dir DIR — artifact emission target; implicitly disables fail_fast so truncated artifacts don't ruin downstream diffs.

Agent reachability: the session :class:Agent is lazy — no health check at fixture setup. Local-eval checks (check.that(literal | cache_field, op, literal)) work without a reachable agent. Operations that need the agent (signal-bearing checks, agent.signals(), agent.latest(), traces) raise :class:AgentUnavailable at the call site. Suites that want startup validation can call _agent_session.connect(timeout=...) in their own conftest fixture.

check(agent)

Convenience alias: check.that(...) reads as agent.check.that(...).

The per-test :class:Checker board / artifact context is opened by the agent fixture itself — requesting check pulls in agent and so inherits the same capture lifecycle. Tests can pick whichever spelling reads better; both post to the same board / artifact.

Configuration knobs (consumed by the agent fixture):

  • @pytest.mark.check_config(fail_fast=False) — delay failure to end-of-test instead of raising on first failed check. The default is True: a failed predicate raises pytest.fail immediately so the test fails on the first violation.
  • --zelos-local-artifacts-dir DIR — artifact emission target; implicitly disables fail_fast (truncated artifacts make poor diff inputs).

pytest_addhooks(pluginmanager)

Add hooks from enabled plugins

pytest_addoption(parser)

Add options for plugin selection and delegate to enabled plugins

pytest_configure(config)

Configure enabled plugins

pytest_runtest_call(item)

Delayed-fail hook for fail_fast=False checker sessions.

The agent fixture wraps the test body in a :class:Checker context, registering itself on :data:active_checker_var. After the test body returns we read that ContextVar (still bound at this point — the fixture's yield hasn't returned yet) to inspect the accumulated rows. Tests that didn't request agent leave the ContextVar at its default None and this hook is a no-op for them.

pytest_runtest_makereport(item, call)

Hook to inject trace file links into HTML reports.

This hook runs after each test phase and adds trace file links to the HTML report if pytest-html is available.

pytest_zelos_configure(config)

Delegate pytest_zelos_configure to enabled plugins

trace_file_class(request)

Initialize and manage trace handlers for each test class.

:yield: Manages the lifecycle of trace handlers without returning a value.

Parameters:

Name Type Description Default
request

The pytest request object.

required

trace_file_function(request)

Initialize and manage trace handlers for each test function.

:yield: Manages the lifecycle of trace handlers without returning a value.

Parameters:

Name Type Description Default
request

The pytest request object.

required

trace_file_module(request)

Initialize and manage trace handlers for each module.

:yield: Manages the lifecycle of trace handlers without returning a value.

Parameters:

Name Type Description Default
request

The pytest request object.

required

trace_file_session(request)

Initialize and manage trace handlers for the entire test session.

:yield: Manages the lifecycle of trace handlers without returning a value.

Parameters:

Name Type Description Default
request

The pytest request object.

required

trace_logging(request)

Initialize logging for the entire test session.

trace_stdout(request)

Initialize logging for the entire test session.

zelos_session(request)

Initialize Zelos session-level fixtures.

Config

zelos_sdk.pytest.config

Config plugin for pytest.

Use via:

pytest_plugins = ["zelos_sdk.pytest.config"]

pytest_addhooks(pluginmanager)

This example assumes the hooks are grouped in the 'hooks' module.

pytest_addoption(parser)

Add options for the pytest invocation

pytest_configure(config)

Configurations for the pytest invocation