Trace Recording¶
Automatically capture all test data to .trz files with configurable scopes and HTML report integration.
Quick Start¶
# Record each test to its own file (artifacts dir required)
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts
# Record entire session to one file
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=session
Recording does not need an agent. The plugin writes every trace event the test process emits to the file.
Recording Scopes¶
Control granularity of trace files:
| Scope | Description | Use Case |
|---|---|---|
function |
One file per test (default) | Debugging individual tests |
class |
One file per test class | Related test groups |
module |
One file per .py file | Module-level analysis |
session |
One file for entire run | Full session replay |
At class scope, a test outside a class gets its own file.
For a test TestMotor::test_start in tests/test_motor.py, each scope writes:
# Examples
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=function # 20240115-143022-zelos-trace-tests-test_motor-TestMotor-test_start.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=class # 20240115-143022-zelos-trace-tests-test_motor-TestMotor.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=module # 20240115-143022-zelos-trace-tests-test_motor.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=session # 20240115-143022-zelos-trace.trz
File Naming¶
Default Naming¶
Files are named automatically using your artifact basename plus a sanitized test identifier:
{artifact_basename}-trace-{sanitized_nodeid}.trz
Examples:
20240115-143022-zelos-trace-tests-test_motor-TestMotor-test_start.trz
20240115-143022-zelos-trace-tests-test_motor-test_free.trz
20240115-143022-zelos-trace-tests-test_battery-test_charge[1].trz
artifact_basenamecomes from--zelos-artifact-basename(default is{date:%Y%m%d-%H%M%S}-zelos).sanitized_nodeidis pytest'snodeidwith.pyremoved,/and::turned into-, and characters that are unsafe in file names removed. Parametrize brackets stay.- A session-scope file has no node id:
{artifact_basename}-trace.trz. - If a filename already exists, a numeric suffix is added:
.trz,.1.trz,.2.trz, ...
Custom Naming¶
Implement the hook in conftest.py. Return the name without the .trz extension, or None to keep the default:
from datetime import datetime
def pytest_zelos_trace_file_name(request):
"""Customize trace file names."""
timestamp = datetime.now().strftime("%H%M%S")
return f"trace_{request.node.name}_{timestamp}"
Return a name without dots. The plugin adds the .trz extension, and anything after a dot in the name can be replaced by it.
See Parameterized Tests for a variant that folds test parameters into the name.
HTML Report Integration¶
Trace files are automatically linked in HTML reports (requires pytest-html):
The report includes clickable links to trace files for each test.
- Links are added only for the scopes relevant to each test (session/module/class/function) and require
pytest-html. - Links use
file://URLs pointing to your local filesystem. If you open the report on another machine or CI artifact viewer, make sure the.trzfiles are available at the same paths. - If
pytest-htmlis installed and--zelos-local-artifacts-diris set, a self-contained report is auto-generated at{artifact_basename}-report.htmlin that directory without needing--html.
Streaming + Recording¶
Stream live while recording for later analysis:
pytest --zelos-trace --zelos-trace-url=grpc://agent:2300 \
--zelos-trace-file --zelos-local-artifacts-dir=./artifacts
--zelos-trace streams to the agent; --zelos-trace-file records the same data to disk.
Directory Structure¶
Organized output:
artifacts/
├── 20240115-143022-zelos-trace-tests-test_motor-test_motor_start.trz
├── 20240115-143022-zelos-trace-tests-test_motor-test_motor_stop.trz
├── 20240115-143022-zelos-trace-tests-test_battery-test_battery_charge.trz
├── test_motor_start.checks.json # check results, for tests that request `check`
└── 20240115-143022-zelos-report.html # Links to all .trz files
Every file shares one timestamp: the plugin formats the basename once, when the run starts.
Configuration¶
pytest.ini¶
[pytest]
# Always record tests
addopts = --zelos-trace-file
--zelos-local-artifacts-dir=./test-results
--zelos-trace-file-scope=function
--zelos-artifact-basename={date:%Y%m%d-%H%M%S}-test
--zelos-local-artifacts-diris required when--zelos-trace-fileis used. It resolves against pytest's rootdir, and the plugin creates it if absent.--zelos-artifact-basenameis a Python format string with one field,date: the run's start time as adatetime. The default includes a timestamp.
Advanced Patterns¶
Parameterized Tests: Include Parameters in Filenames¶
Add parameters to filenames using the hook:
# conftest.py
def pytest_zelos_trace_file_name(request):
name = request.node.name
if hasattr(request.node, "callspec"):
params = request.node.callspec.params
parts = [f"{k}={v}".replace(".", "_") for k, v in params.items()]
name = f"{name}_{'_'.join(parts)}"
return name
Troubleshooting¶
- "Local artifacts directory is not set": pass
--zelos-local-artifacts-dir=./artifacts(or set inpytest.ini). - No links in HTML report: ensure
pytest-htmlis installed and you are generating an HTML report (e.g.,--html=artifacts/report.html). - Missing
.trzfiles on CI: the HTML links reference local paths; upload the.trzfiles as CI artifacts along with the report.