Docs menu

Tests by package

Each package's test files: what kind of test each one is, what it checks, whether it needs ROS, and the command that runs it.

This page lists every test file in the workspaces’ own packages and what it checks. The overview explains the kinds of test. A file marked ROS imports rclpy or the launch system, so it needs both setup files sourced and an isolated ROS domain, as described on Run the tests. Every other file runs with plain pytest.

The counts are test functions in each file at the commits above. A parametrized test runs several times, so pytest reports more. Both cars have the same files, except where a table says otherwise.

Every command below runs from ~/racerbot-ws. For a package with ROS files, set up the terminal first:

source /opt/ros/jazzy/setup.bash
source ~/racerbot-ws/install/setup.bash
export ROS_DOMAIN_ID=79 ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST

gap_follow

python3 -m pytest src/gap_follow/test/ -v

The largest suite after pure_pursuit’s. The unit tests call gap_logic.py directly; the node tests start a real gap_follow_node, publish scans, odometry and /joy, and check the command it publishes on /test_only/drive.

File Tests Kind Checks
test_gap_logic.py 93 Unit Every step of the pipeline: scan cleaning, edge extension, the bubble, gap choice, steering and every speed cap, each against a closed form or invariant
test_gap_logic_corners.py 39 Unit The swept-path clearance, the arc guard and corner set-up
test_gap_follow_node.py 54 Node, ROS The real node: the four LB cases, stale inputs, the decision log, and that no test ever drives the real /drive
test_gap_follow_corners_node.py 15 Node, ROS The arc guard and corner logic wired into the node
test_gap_follow_speed_shaping_node.py 14 Node, ROS The speed changes from the October 20, 2026 floor runs
test_gap_follow_intent.py 25 Node, ROS /drive_intent: valid, reports the command that was published, and can never delay or stop the drive command
test_opponent_tracking.py 62 Unit Moving-car detection, tracking and the follow decision
test_opponent_awareness_node.py 9 Node, ROS Opponent awareness wired into the node
test_gap_follow_live_tuning.py 29 Unit Which parameters the dashboard may change live, and the limits it may set them to
test_speed_overrides.py 17 Unit The coupled speed overrides every mapping launch uses
test_launch_speed.py 11 Configuration, ROS gap_follow_launch.py’s max_speed:=: accepted values, refused values, and the speeds lowered with it
test_gap_mirror_parity.py 4 Parity, ROS The simulator’s copy of gap_follow commands what the real node commands

pure_pursuit

python3 -m pytest src/pure_pursuit/test/ -v

The largest suite. Unsourced, it collects only part of its tests and stops on collection errors, which is the example in Check that every test was collected.

File Tests Kind Checks
test_racing_math.py 90 Unit The pure pursuit geometry, curvature, the speed profile, nearest-point search and opponent geometry
test_tracking_laws.py 69 Unit All four steering laws: signs, the LQR gain against a Riccati iteration and closed-loop stability, Stanley on a circle, MPC limits and misses
test_tracking_law_integration.py 21 Node, ROS The steering-law seam in the node: every safety layer still applies whatever law is selected
test_localization_watchdogs.py 8 Node, ROS The pose watchdogs: a frozen pose and a stale timestamp stop the car; a parked car does not trip them
test_opponent_integration.py 46 Node, ROS The reactive safety net, opponent detection and overtaking, in the real node
test_pure_pursuit_intent.py 17 Node, ROS /drive_intent from the race controller
test_pose_frame.py 9 Node, ROS Which point on the car a pose describes, and the 0.26 m LiDAR-to-rear-axle move
test_auto_map_race.py 63 Unit and node, ROS The mapping-to-racing handover: lap detection, quality checks, the switch of localizer
test_seed_start_pose.py 6 Node, ROS Seeding the particle filter at the start pose for a saved-map race
test_waypoint_recorder_integration.py 1 Node, ROS The waypoint recorder’s status messages
test_recorded_path.py 30 Unit Turning a recorded SLAM lap into a drivable racing line
test_raceline_optimizer.py 27 Unit The minimum-curvature optimizer, including a circular track whose answer is the outer wall
test_map_despeckle.py 18 Unit Removing stray returns from saved maps
test_pure_pursuit_live_tuning.py 29 Unit Which parameters the dashboard may change live
test_run_commands.py 9 Unit The race commands printed at the end of a mapping run

drive_intent

python3 -m pytest src/drive_intent/test/ -v

Pure Python, so it runs on any computer: 95 tests in under a second.

File Tests Kind Checks
test_predict.py 22 Unit The predicted path: a straight line along the heading, a quarter circle that lands where geometry says
test_schema.py 42 Unit The /drive_intent JSON format: what a payload must contain, its version, and the fields the browser draws
test_throttle.py 14 Unit The publish-rate limit and the failure latch that turns intent off after repeated errors

imu_bridge

python3 -m pytest src/imu_bridge/test/ -v
File Tests Kind Checks
test_convert.py 34 Unit Units, the mount rotation into car axes, calibration, startup bias and covariances
test_vehicle_state.py 49 Unit The fused speed and the measured steering angle, and the configuration checks that refuse bad values
test_gyro_odometry.py 31 Unit Gyro odometry: pose composition, angle wrapping, the heading sources and their fallback
test_imu_health.py 15 Unit The /imu/status verdict: startup bias, the gravity check, all-zero and stale data
test_vehicle_state_config.py 6 Configuration vehicle_state.yaml against the code that reads it
test_imu_status_node.py 5 Node, ROS The node publishes /imu/status the way neural_racer reads it

neural_racer

python3 -m pytest src/neural_racer/test/ -v
File Tests Kind Checks
test_observation.py 20 Unit The observation: scan pooling, the log encoding, history at the start of a run
test_policy_numpy.py 15 Unit The NumPy network: matches a reference implementation step by step, outputs stay in range for any input
test_safety_wrapper.py 17 Unit Every wrapper step, and that it never raises the network’s speed
test_preview.py 12 Unit Map-mode geometry
test_model_store.py 12 Unit Model loading and approval: hashes, the manifest, refusals
test_config.py 3 Configuration The shipped neural_racer.yaml
test_latency.py 2 Performance One tick under 5 ms at the 99th percentile. Meaningful only on the Jetson.
test_neural_racer_node.py 22 Node, ROS The real node: deadman, shadow mode, refusals, stops and intent

odom_calibration

python3 -m pytest src/odom_calibration/test/ -v

Pure Python, apart from five files that run the wizard’s JavaScript and need Node.js installed.

File Tests Kind Checks
test_calibration_math.py 15 Unit Speed-gain calibration from tape-measured runs, forward and reverse
test_steering_math.py 31 Unit Steering calibration geometry: the arc that produced a measured drift
test_steering_curve.py 35 Unit The multi-setting circle calibration used on October 16, 2026
test_steering_chain.py 11 Unit The reach and centre checks
test_active_samples.py 13 Unit The October 6, 2026 “gain 0.0” bug and the filter that fixes it
test_vesc_yaml.py 21 Configuration Writing vesc.yaml: only the requested values change, in the right block
test_teleop_yaml.py 12 Configuration Writing joy_teleop.yaml: only the full-stick steering scale may change
test_clamp_and_writes.py 15 Unit Which new values may be written, and the servo clamp check
test_overrides.py 22 Unit Values typed on the page, the servo-limit step, undo
test_modes_and_progress.py 12 Unit The wizard’s modes and progress
test_session_store.py 4 Unit Saving a session
test_wizard_actions.py 14 Unit What the wizard may write, and how it follows the car
test_wizard_apply.py, test_wizard_circles.py, test_wizard_overrides.py, test_wizard_steps.py, test_wizard_ui.py 1 each Front end The wizard’s JavaScript, run in Node.js with the page and the HTTP calls faked

race_diagnostics

python3 -m pytest src/race_diagnostics/test/ -v
File Tests Kind Checks
test_run_events.py 18 Unit Classifying log lines into events, and which stop reason wins
test_node_logs.py 10 Unit Finding and merging ROS’s own per-node log files for a run
test_run_metadata.py 14 Unit What a run records about the code it ran: git state, uncommitted edits
test_summarize_run.py 6 Unit summarize_run’s report
test_record_run_topics.py 6 Configuration Which topics record_run.py records by default

racerbot_doctor

python3 -m pytest src/racerbot_doctor/test/ -v

Only test_live.py needs ROS. The rest fake the operating system’s files, so they can describe an unplugged VESC or a missing kernel driver without one.

File Tests Kind Checks
test_checks.py 70 Unit Every verdict: a healthy car passes, an unplugged VESC fails at USB and blocks everything above it, a wrong kernel driver is not reported as unplugged
test_system.py 17 Unit Reading /sys, /proc, /dev and ip: USB IDs, drivers, device nodes
test_snapshot.py 7 Unit The result types and the layer-by-layer ladder
test_cli.py 16 Unit Exit codes and printed fixes, and that the doctor never opens a device or publishes
test_live.py 6 Node, ROS Sampling topics and reading the static transforms

The LiDAR and camera checks differ between the cars, and so do the corresponding tests.

racerbot_launch

python3 -m pytest src/racerbot_launch/test/ -v

This is the suite to run after any change to a car profile, a shared configuration file or a launch file, together with src/racerbot_car/test/. A failure in the hardware guard means the change overwrote one of a car’s own settings: fix the change, not the test.

File Tests Kind Checks
test_car_profiles.py Hardware guard Both cars’ LiDAR, camera, IMU wiring, steering calibration and limits, and dashboard settings, against each car’s profile and docs/car1-vs-car2.md, whichever car runs it
test_steering_limits_fit_servo.py 6 Configuration Every steering limit fits inside the servo range in vesc.yaml, and the planner plans below the controller’s limit
test_drive_path_wiring.py 5 Configuration Every bringup wires ackermann_mux’s output into ackermann_to_vesc, in the real launch files and the simulator’s
test_map_course.py 13 Unit The map_course wrapper: which run folder it reports
test_map_course_imu.py 13 Configuration, ROS map_course’s imu:= and fused_speed:= wiring, and that fused_speed:=true without the IMU refuses to start
test_web_dashboard_rb1_config.py (car 1), test_web_dashboard_rb2_config.py (car 2) 10 Configuration The dashboard settings against the parameters the node declares and the bringup transforms

racerbot_sim

python3 -m pytest src/racerbot_sim/test/ -v
File Tests Kind Checks
test_hardware_guard.py 8 Unit The interlock that stops the simulator when any real driver appears on the graph
test_sim_bridge.py 17 Unit The scripted opponent and the dead-reckoned odometry
test_tracks.py 8 Unit The generated tracks close a lap and are large enough. Needs Pillow.
test_harness_procs.py 5 Unit The validation harness cleans up its processes

racerbot_wiimote_driver

python3 -m pytest src/racerbot_wiimote/racerbot_wiimote_driver/test/ -v
File Tests Kind Checks
test_wiimote_connect.py 10 Unit wiimote_connect against a fake bluetoothctl: reconnecting, pairing a new Wiimote, the instructions when none is found

Tools

These test the simulators and the analysis and training code in tools/, not anything that runs on the car.

Suite Files Checks
tools/f1tenth_sim/tests/ 5 The promotion rule for steering laws, track import, that the harness steers with the selected law, and that the Gym’s own collision response never moves a car
tools/run_analysis/tests/ 4 The run analyzer’s actuation measurements, log replay, scan motion, and the IMU report (ROS for the last)
tools/neural_racer/tests/ 7 Training: the GPU simulator against the CPU referee, the exported network against the car’s, the observation and wrapper against the car’s code, release selection
python3 -m pytest tools/f1tenth_sim/tests/ -v

Vendored packages

f1tenth_system carries its upstream projects’ own tests: flake8, pep257 and copyright checks, plus joy_teleop’s ROS tests. They test upstream code, and colcon test runs them with everything else.

Checked against car 1 commit 0265263 and car 2 commit b81b291, before the two workspaces merged.