Learn Robotics
Module: Build And Share

Testing Robot Software

How to test robot code — unit tests for individual functions, integration tests for multi-node systems, and simulation tests for full behaviors.

10 min read

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.

Unit test example (pytest)

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"
Tip

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 test (multi-node)

Integration tests verify:

  • Nodes can communicate
  • Topics are correctly remapped
  • Message types match
  • Timing constraints are met (e.g., "detector must respond within 100ms")
Warning

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 test

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.

Mock sensor 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.

Got questions? Join the community

Discuss this lesson, get help, and connect with other learners on Discord.

Join Discord

Discussion

Sign in to join the discussion.