This document describes the core testing infrastructure that underpins all openpilot tests. It covers the pytest-based framework, test isolation mechanisms using OpenpilotPrefix, fixture configurations in conftest.py, and the test environment setup used in both local development and CI/CD pipelines.
For specific testing subsystems, see:
The openpilot testing architecture is designed for strict isolation to support parallel execution and deterministic results. It leverages pytest fixtures to manage a unique environment for every test case.
| System Concept | Code Entity | File Path |
|---|---|---|
| Test Orchestrator | pytest | N/A (External) |
| Global Hooks | pytest_runtest_call | conftest.py25-33 |
| IPC Isolation | OpenpilotPrefix | openpilot/common/prefix.py12-62 |
| Environment Reset | clean_env | conftest.py36-41 |
| Process Cleanup | manager_cleanup | openpilot/system/manager/manager.py |
| Hardware Init | initialize_hardware | openpilot/common/hardware/__init__.py |
Sources: conftest.py44-96 openpilot/common/prefix.py12-62
The testing framework is built on pytest with custom configurations and fixtures defined in conftest.py. The framework provides:
Test collection filters exclude certain paths from automatic discovery, such as heavy CI-only process replay tests and simulation tools:
The pytest_runtest_call hook ensures that tests marked with nocapture disable global output capture, allowing real-time logging to the console:
Sources: conftest.py11-33
The OpenpilotPrefix class is the cornerstone of test isolation, providing unique namespaces for inter-process communication (IPC) and data storage.
OpenpilotPrefix is a context manager that ensures every test has a private sandbox for its processes.
Key behaviors:
msgq IPC sockets to /dev/shm/msgq_{prefix} (Linux) or /tmp/msgq_{prefix} (macOS) openpilot/common/prefix.py15-16OPENPILOT_PREFIX which is inherited by any processes spawned during the test openpilot/common/prefix.py23shared_download_cache is enabled, it points the download cache to the default root instead of a per-test directory openpilot/common/prefix.py28-29The cleanup process removes all created resources upon exit, including shared memory segments and log directories:
openpilot/common/prefix.py51-62
Sources: openpilot/common/prefix.py12-62
The conftest.py defines several autouse fixtures that run automatically for all tests:
Applied to every test function, this fixture orchestrates the lifecycle:
clean_env() conftest.py46OpenpilotPrefix conftest.py48manager.manager_cleanup() conftest.py57Automatically injected for tests marked with tici. It prepares the Comma Three (TICI) hardware:
HARDWARE.initialize_hardware() conftest.py77athena conftest.py79Sources: conftest.py44-80
| Marker | Purpose | Effect |
|---|---|---|
tici | Mark test as device-only | Automatically skipped on PC, adds tici_setup_fixture on device conftest.py86-90 |
nocapture | Disable output capture | Allows real-time output during test conftest.py28-31 |
shared_download_cache | Share download cache | Allows OpenpilotPrefix to reuse existing data conftest.py48 |
xdist_group_class_property | Group tests for parallel execution | Groups tests by a specific class property value for pytest-xdist conftest.py92-95 |
Sources: conftest.py25-95
Testing on actual hardware is orchestrated by Jenkins. The Jenkinsfile defines how tests are deployed to a pool of devices.
Key Execution Parameters:
PYTEST_ADDOPTS="-n0 -s" to ensure single-threaded execution for Hardware-In-The-Loop (HIL) stability Jenkinsfile34/dev/shm/* and /dev/tmp/tmp* before each stage Jenkinsfile45-46git diff to determine which tests to run based on changed file paths Jenkinsfile90-116Sources: Jenkinsfile12-75 Jenkinsfile78-121
The testing framework is used to validate complex state machines like DriverMonitoring.
Key Implementation:
make_msg creates log.DriverStateV2 Cap'n Proto messages with specific probabilities for face detection and distraction openpilot/selfdrive/monitoring/test_monitoring.py14-27_run_seq iterates through these messages, updating the DriverMonitoring state and verifying alert levels openpilot/selfdrive/monitoring/test_monitoring.py50-61Sources: openpilot/selfdrive/monitoring/test_monitoring.py14-61 openpilot/selfdrive/monitoring/policy.py130-170
Refresh this wiki