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 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 |
# Examples
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=function # test_motor_start.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=class # TestMotor.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=module # test_hardware.trz
pytest --zelos-trace-file --zelos-local-artifacts-dir=./artifacts --zelos-trace-file-scope=session # session.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-test_motor_start.trz
20240115-143022-zelos-trace-TestBattery.trz
20240115-143022-zelos-trace-test_sensors.trz
artifact_basename
comes from--zelos-artifact-basename
(default is{date:%Y%m%d-%H%M%S}-zelos
).sanitized_nodeid
is derived from pytest’snodeid
(module::class::function) with unsafe characters removed.- If a filename already exists, a numeric suffix is added:
.trz
,.1.trz
,.2.trz
, ...
Custom Naming¶
Implement the hook in conftest.py
:
def pytest_zelos_trace_file_name(request):
"""Customize trace file names."""
# Simple custom name
return f"trace_{request.node.name}"
# Include parameters for parameterized tests
if hasattr(request.node, 'callspec'):
params = request.node.callspec.params
param_str = "_".join(f"{k}={v}" for k, v in params.items())
return f"{request.node.name}_{param_str}"
# Include timestamp
from datetime import datetime
timestamp = datetime.now().strftime("%H%M%S")
return f"{request.node.name}_{timestamp}"
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.trz
files are available at the same paths. - If
pytest-html
is installed and--zelos-local-artifacts-dir
is set, a self-contained report is auto-generated at{artifact_basename}-report.html
without needing--html
.
Streaming + Recording¶
Stream live while recording for later analysis:
pytest --zelos-trace \ # Stream to Agent
--zelos-trace-file \ # Also record
--zelos-trace-url=grpc://agent:2300
Directory Structure¶
Organized output:
artifacts/
├── 20240115-143022-zelos-trace-test_motor_start.trz
├── 20240115-143022-zelos-trace-test_motor_stop.trz
├── 20240115-143025-zelos-trace-test_battery_charge.trz
└── 20240115-143022-zelos-report.html # Links to all .trz files
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-dir
is required when--zelos-trace-file
is used; the directory will be created if absent.--zelos-artifact-basename
supports Python format-like fields. The default includes a timestamp.
Advanced Patterns¶
Conditional Recording¶
Only record on failure using hooks:
# conftest.py
import pytest
import os
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
report = outcome.get_result()
if report.when == "call" and report.failed:
# Enable recording for failed tests
item.config.option.zelos_trace_file = True
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}" for k, v in params.items()]
return f"{name}_{'_'.join(parts)}"
return f"{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-html
is installed and you are generating an HTML report (e.g.,--html=artifacts/report.html
). - Missing
.trz
files on CI: the HTML links reference local paths; upload the.trz
files as CI artifacts along with the report.