Testing Robot Software
Imagine deploying a new path planner to your delivery robot. It works great in the office. You ship it. Two hours later, the robot gets stuck in a doorway and blocks traffic.
What went wrong? You tested it manually once. But you didn't test:
- Narrow doorways
- Moving obstacles
- Low battery scenarios
- Sensor failures
Testing is how you catch bugs before they reach real robots. And for robotics, testing is particularly challenging.
Why Robotics Testing Is Hard
Unlike web apps or desktop software:
- Physical hardware — can't run tests on a farm of real robots 24/7
- Sensors are noisy — LiDAR scans vary, cameras flicker, IMUs drift
- Time-dependent behavior — control loops run at 100Hz, paths evolve over time
- Rare edge cases — GPS dropout happens once a week, but it's critical
- Expensive failures — a bug can damage a $50k robot (or worse, harm people)
The solution: multi-level testing.
Unit Tests
Test individual functions in isolation. Fast, deterministic, no hardware required.
Good unit tests are:
- Fast — thousands run in seconds
- Isolated — no file I/O, no network, no hardware
- Deterministic — same input, same output, always
- Focused — one function or behavior per test
Run them constantly:
pytest tests/ # Run all tests
pytest tests/test_planner.py # Run one file
pytest -k "distance" # Run tests matching "distance"
Aim for 80%+ code coverage on core algorithms. Tools like pytest-cov show which lines aren't tested. But don't chase 100% — some code (like hardware drivers) is better tested via integration tests.
Integration Tests
Test multiple components working together. Slower, but closer to real behavior.
Integration tests verify:
- Nodes can communicate
- Topics are correctly remapped
- Message types match
- Timing constraints are met (e.g., "detector must respond within 100ms")
Integration tests can be flaky. Network delays, race conditions, and timing issues cause random failures. Use retries, generous timeouts, and idempotent assertions. If a test fails 1 in 20 times, it's worse than useless — it trains developers to ignore failures.
Simulation Tests
Test the full robot in a simulated environment. Slow, but catches system-level bugs.
Simulation tests are perfect for:
- Testing navigation algorithms (paths, obstacle avoidance)
- Verifying control loops (PID tuning, stability)
- Stress-testing sensor fusion (what if GPS drops out?)
- Reproducing rare bugs (recorded sensor logs as input)
Mocking Sensors
You can't always run tests with real sensors. Mocks provide fake but realistic data.
Advanced mocking can simulate sensor failures:
# GPS drops out after 5 seconds
mock_gps.get_position.side_effect = [
(10.0, 20.0),
(10.1, 20.1),
(10.2, 20.2),
None, # GPS lost signal
None,
(10.5, 20.5) # GPS recovered
]
What's Next?
Your code is tested and working. Now you need to get it onto a real robot. In the next lesson, we'll explore deployment — Docker containers, over-the-air updates, and cross-compilation for embedded systems.