Skip to main content

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

Localrbtk test cloudGitHub PR
Triggered byYou, manuallyYou, manuallygit push
Tree bundledN/AWorking tree, including dirty filesThe PR head SHA
AuthNonerbtk login (OAuth)GitHub App installation
JUnit destinationlocal fileuploaded automaticallyuploaded automatically
Result appearsterminalterminal + dashboarddashboard + Check Run
Costs sim minutes?NoYes (if @requires_sim)Yes (if @requires_sim)
Required for the matrix?NoNoYes (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:
pip install 'roboticks[mcap]'
pytest -v tests/
Or for a colcon workspace:
colcon test --packages-select my_pkg
colcon test-result --verbose
The @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.
If you want a local run to surface in the dashboard, upload the JUnit XML manually after the run:
rbtk test results upload --file test_results/junit.xml --commit $(git rev-parse HEAD)

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.
rbtk test cloud \
  --filter "tests/test_estop.py" \
  --sim gazebo \
  --watch
Flags:
FlagEffect
--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
--watchStream stdout / stderr live; otherwise the command exits with the run URL
--detachPrint run ID and exit immediately
--no-upload-treeUse the current commit on the remote instead of the working tree (cheaper, requires push)
Output:
$ rbtk test cloud --watch --filter test_estop
i  bundling working tree (12 files, 1.4 MB) ...
i  run #4218 dispatched to hosted-fargate-spot (us-east-1)
i  https://app.roboticks.io/runs/4218

[runner] collected 3 items
[runner] tests/test_estop.py::test_estop_halts_motion PASSED [33%]
[runner] tests/test_estop.py::test_estop_survives_comms_loss PASSED [66%]
[runner] tests/test_estop.py::test_estop_on_battery_low PASSED [100%]
[runner] 3 passed in 12.4s

ok  run #4218 PASSED · 3/3 tests · 3 requirements confirmed · 22s wall time
See CLI: test commands for the full surface.

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 run rbtk 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

SurfaceHow auth works
pytest locallyNone — local files only.
rbtk test cloudrbtk login opens a browser OAuth flow against app.roboticks.io; token is cached in ~/.config/roboticks/auth.json.
GitHub AppOAuth install grants the App per-repo permissions; no per-user auth on the runner side.
Self-hosted runnerRunner exchanges a one-time enrolment token for a per-runner OIDC identity. See Runners → Installation.

Decision matrix

SituationUse
Writing a new test, iteratingLocal pytest
Test passes locally but you want sim verificationrbtk test cloud --sim gazebo
You don’t have GPUs and the test needs Webotsrbtk test cloud (routes to hosted GPU pool)
You’re about to push and want a dry-runrbtk test cloud --no-upload-tree
You opened a PRNothing — the GitHub App runs it automatically
You want the matrix updated without a PRrbtk test results upload after the local run

What never changes

  • @confirms, @tags, @deadline, @requires_sim produce 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.