Local vs cloud
The SDK is the same in both places. The decision is about what runs the tests — your laptop, a hosted Roboticks runner, or one you operate yourself.At a glance
| Local | rbtk test cloud | GitHub PR | |
|---|---|---|---|
| Triggered by | You, manually | You, manually | git push |
| Tree bundled | N/A | Working tree, including dirty files | The PR head SHA |
| Auth | None | rbtk login (OAuth) | GitHub App installation |
| JUnit destination | local file | uploaded automatically | uploaded automatically |
| Result appears | terminal | terminal + dashboard | dashboard + Check Run |
| Costs sim minutes? | No | Yes (if @requires_sim) | Yes (if @requires_sim) |
| Required for the matrix? | No | No | Yes (matrix tracks the platform-recorded commit SHA) |
Local: pytest and colcon as you know them
Nothing about the SDK forces a runner. Run pytest the way you always have:@confirms decorators still take effect — the pytest plugin still writes properties into the JUnit XML — but no one is uploading that XML to the platform. The local run is for the inner loop: write code, run tests, iterate.
Cloud: rbtk test cloud
rbtk test cloud is the “skip the PR loop” command. It bundles your working tree (including dirty files), uploads to the platform, runs on a hosted runner of the right shape, and streams logs back to your terminal in real time.
| Flag | Effect |
|---|---|
--filter <expr> | pytest -k style filter; same goes through to the remote pytest |
--sim <engine> | Force a sim-capable runner even if no test is marked @requires_sim |
--watch | Stream stdout / stderr live; otherwise the command exits with the run URL |
--detach | Print run ID and exit immediately |
--no-upload-tree | Use the current commit on the remote instead of the working tree (cheaper, requires push) |
GitHub PR: the default cloud path
When the GitHub App is installed on a repo, every PR automatically runs the test suite on a hosted (or self-hosted, by routing label) runner. The Check Run posts back to the PR with a coverage delta. This is the normal mode of operation. You don’t runrbtk test cloud for the PR loop. You run it for between-PR experiments: trying a fault-injection scenario that needs sim minutes you don’t have locally, or asking “does this branch break REQ-014?” without the overhead of opening a draft PR.
Auth flows
| Surface | How auth works |
|---|---|
pytest locally | None — local files only. |
rbtk test cloud | rbtk login opens a browser OAuth flow against app.roboticks.io; token is cached in ~/.config/roboticks/auth.json. |
| GitHub App | OAuth install grants the App per-repo permissions; no per-user auth on the runner side. |
| Self-hosted runner | Runner exchanges a one-time enrolment token for a per-runner OIDC identity. See Runners → Installation. |
Decision matrix
| Situation | Use |
|---|---|
| Writing a new test, iterating | Local pytest |
| Test passes locally but you want sim verification | rbtk test cloud --sim gazebo |
| You don’t have GPUs and the test needs Webots | rbtk test cloud (routes to hosted GPU pool) |
| You’re about to push and want a dry-run | rbtk test cloud --no-upload-tree |
| You opened a PR | Nothing — the GitHub App runs it automatically |
| You want the matrix updated without a PR | rbtk test results upload after the local run |
What never changes
@confirms,@tags,@deadline,@requires_simproduce the same JUnit XML wherever they run.- The wire contract is the same wherever they run.
- The matrix doesn’t care whether a test ran locally-uploaded, via
rbtk test cloud, via PR, or via a self-hosted runner — only that the commit SHA is recorded.
Next
CLI: test commands
Full surface of
rbtk test cloud, results, upload, retry.Sim runners
When
--sim gazebo matters and what it costs.GitHub App
How the PR loop produces a Check Run.
Self-host a runner
Bring your own compute, no sim-minute charges.