Pytest (tracing)
Pytest (tracing)
Pytest is a Python testing framework with fixtures, parametrization, plugins, and rich outcome reporting. respan-instrumentation-pytest is an installable Pytest plugin that emits one Respan workflow span for each test session and one task span for every test protocol.
The test span remains current across setup, synchronous or asynchronous execution, and teardown. Any Respan spans created by the application under test are therefore nested beneath the correct test.
Set up Respan
Create an account at platform.respan.ai and grab an API key.
Run npx @respan/cli setup to set up with your coding agent.
Example projects
Tracing
Setup
Install the plugin
Pytest discovers the package through its pytest11 entry point. Tracing remains opt-in after installation, so a globally installed plugin does not unexpectedly export every test run.
Set the Respan API key
Set RESPAN_BASE_URL as well when exporting to a self-hosted or non-default Respan endpoint.
Run Pytest with tracing
The plugin creates a session workflow automatically and flushes it when the session finishes, including when tests fail.
View your trace
Open the Traces page. The default workflow name is derived from the test root; configure a stable name for CI as shown below.
Configure Pytest
Enable tracing for a repository in pytest.ini:
Or enable it through environment variables, which is convenient in CI:
Captured test lifecycle
Fixture names may be captured, but fixture return values are never recorded.
Nested application spans
No decorator is required to trace the test itself. Respan decorators and auto-instrumented library calls made inside a test automatically become children of its pytest.test task span.
Asynchronous tests are traced by the same protocol hook. Continue using your normal async plugin, such as pytest-asyncio:
Content capture
By default, parameter values, marker names, fixture names, and failure text are attached to the test span. Disable them for suites that use secrets or production-like data:
With capture disabled, normalized node IDs, outcomes, phase durations, status codes, and exception types remain visible. Parameter values, fixture and marker lists, raw failure messages, and exception events are omitted.
Failure behavior
The plugin observes Pytest’s result without changing it. A failed setup, assertion, or teardown still produces the normal Pytest exit code, while its span records:
- OpenTelemetry
ERRORstatus; - backend-visible
status_code=500; - backend-visible
error.message; - the phase that failed and the durations collected so far.
Skipped and expected-failure tests remain non-error outcomes. Session shutdown flushes completed spans even when Pytest exits with a failure.
Verify plugin discovery
Use Pytest’s built-in trace output to confirm that the respan entry point is installed:
The runnable example suite includes successful, asynchronous, skipped, expected-failure, content-control, and deterministic failure runs.