Skip to content

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’s nodeid (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):

pytest --zelos-trace-file \
       --zelos-local-artifacts-dir=./artifacts \
       --html=artifacts/report.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 in pytest.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.