# Running unattended ROS 2 hardware tests

ROS 2 / DDS Testing



ROS 2 / DDS Testing  5 min read  Published 2026-09-18

 Reframe 

## The bottleneck isn't ROS 2. It's the terminal.

Most ROS 2 test workflows are limited by how much a person can watch at once, not by what the robot can do.

 

## The one-person stack problem

 

Testing a ROS 2 robot usually starts the same way: SSH into the robot, run `ros2 topic echo` or `ros2 service call` by hand, and eyeball the telemetry scrolling past in a terminal to decide whether a requirement passed. It works, and it's how most teams still validate robotics behavior today. It also doesn't scale past the one person who knows the stack well enough to read that terminal output and judge, in real time, whether what just happened was correct.

 

That's the real constraint on most ROS 2 test coverage: not compute, not the robot, but how many hours a specific person can spend watching a terminal. Every regression check re-runs the same manual steps. And at the end of it, there's usually  no artifact : the "evidence" that a requirement passed is whoever happened to be watching the screen when it did.

 

## What "unattended" actually requires

 

Making a ROS 2 test run without a person watching it isn't just a matter of writing a script that calls the same `ros2` commands non-interactively. Three things have to be true for an unattended run to be trustworthy rather than just unsupervised:

 

The test needs to reach the robot without ROS tooling on the test side.  Joining the robot's DDS domain over the network means enumerating participants and topics through the CycloneDDS layer the robot already runs. The thing driving the test doesn't need a matching ROS environment installed, just network access to the domain and a readiness gate confirming the middleware, clock, and interfaces are actually up before anything is commanded.

 

The pass/fail decision has to be made on live data, not a fixed wait.  "Send the command, sleep five seconds, check the result" is exactly the pattern that produces flaky tests: too short a wait and the test fails when the robot was simply still working, too long and every run wastes time waiting past the point the answer was already known. Gating the next step on a live telemetry condition replaces the guess with a real check: publish a bounded command, then wait for a specific signal on a specific topic to reach the expected value.

 

The evidence has to be captured while it's still true, not reconstructed afterward.  Recording multiple topics into a single artifact as a bounded, unattended job means the trace exists whether or not anyone was watching when it happened, and a reviewer looking at it a day later sees the same data the operator would have seen live.

 

## What a repeatable sequence looks like

 

Put those three pieces together, join, command-and-gate, record, and a ROS 2 test stops being "one person's terminal session." It becomes a repeatable sequence with a defined start, a defined end, and an ordered verdict:

 

One unattended test sequence

1 Join the domain

2 Publish the command

3 Wait for the telemetry condition

4 Record the window

5 Leave the domain cleanly

 

That sequence runs the same way whether it's triggered by a person, a CI job, or a schedule, and it produces the same kind of artifact every time: a single recording that covers every topic relevant to the check, not a partial capture assembled from whatever the operator remembered to note down.

 

This also changes what a regression check costs. Instead of re-running the same manual `ros2` commands and eyeballing new output against old memory, a sequence defined once can be re-run against a new build and diffed against a prior baseline: the same requirement, verified the same way, without requiring the one engineer who knows the stack to sit through it again.

 

## Why the operator still matters

 

None of this replaces engineering judgment. It changes when that judgment is needed. The engineer still defines what "correct" means: which topic, which condition, which tolerance. What moves is  watching the terminal in real time  to catch the moment a signal crosses that line. That's the part that doesn't need a person present once the requirement is written down as something a machine can check.

  What changes 

## The requirement gets written once. It gets checked every time.

Joining the DDS domain, commanding, gating on live telemetry, and recording the evidence turns a terminal session into a sequence: something that can run overnight, on a schedule, or against every new build, without a person re-deriving the steps.

ROS 2 / DDS Testing: Run unattended ROS 2 hardware tests without ROS tooling on your side

[See how this workflow can be automated →](https://www.plotune.net/solutions/ros2-dds-testing?segment=ros2-dds-testing&article=running-unattended-ros2-hardware-tests&entry_source=direct)

Source: https://www.plotune.net/research/articles/running-unattended-ros2-hardware-tests
