Skip to content

Tutorial 7 RF Test

ibnHatab edited this page Jul 4, 2026 · 1 revision

6. Provision a board + deploy from the Ground Station · Tutorial index · 8. Observe in the supervisor GUI


Chapter 7 — Write a Robot Framework test

Theia ships a Robot Framework harness, rf-theia, that drives a live system the way an external tool does — over the com gRPC bridge and the artheia probe (a Python client that speaks a node's TIPC gen_server wire). You write tests in .robot files that cast/call your nodes and assert on replies and trace records.

Back to the developer hat for this chapter.

7.1 What you can drive

rf-theia gives you, via Library rf_theia.TheiaTestLibrary:

  • probe a node — bind a node's TIPC address and cast/call it with typed messages (the same Inc/Get you defined in .art).
  • assert on traces — every node can emit Tracer records; the harness decodes them (the framework + your workspace each ship a trace decoder .so) so you can wait for a state or assert on payload.
  • drive an FSM — generic hybrid-automata keywords (Emit Statem Event, Wait For Statem State, Assert Statem Data) for GenStateM nodes.

Never test over raw TIPC. Always go through the probe — it's built from your .art, so it speaks the exact wire your node expects.

7.2 The harness layout

Tests live in your workspace under tests/ (the demo's are in demo/tests/). A scenario is a .robot file, optionally with a small Python helper library (*_lib.py) for anything Robot keywords can't express directly. The demo has two worked examples:

demo/tests/
  demo_fsm.robot                      drive a gen_statem, assert transitions + data
  demo_chain/
    demo_chain_selftest.robot         cast/call across a multi-node chain
    demo_chain_lib.py

7.3 Write a test for the counter

Create tests/counter.robot. It probes the live CounterNode over the artheia probe, casts Inc, calls Get, and asserts the accumulated delta:

*** Settings ***
Documentation    CounterNode — cast Inc, call Get via the artheia probe, assert
...              the accumulated value. Probes a LIVE counter, so start it first
...              (`theia install single && theia start`).

Library          rf_theia.TheiaTestLibrary
Force Tags       counter    live


*** Test Cases ***
Counter Accumulates Increments
    [Documentation]    cast Inc{n=5} twice, then call Get → delta +10.

    # bind the probe to CounterNode's TIPC address (resolved from the .art).
    ${counter}=    Probe Node    CounterNode

    # read the starting value (so the test is idempotent across re-runs).
    ${before}=     Call    ${counter}    Get

    # cast Inc — fire-and-forget (drives handle_cast).
    Cast    ${counter}    Inc    n=5
    Cast    ${counter}    Inc    n=5

    # call Get — request/reply (drives handle_call), assert the delta.
    ${after}=      Call    ${counter}    Get
    ${delta}=      Evaluate    ${after}[value] - ${before}[value]
    Should Be Equal As Integers    ${delta}    10

The keyword names (Probe Node, Cast, Call) are the harness verbs; the message names (Inc, Get) and fields (n, value) are exactly what you declared in package.art. The mapping is 1:1 — that's the payoff of modelling in .art. Call returns the reply as a dict, so ${reply}[value] reads a field.

Two probe surfaces. Probe Node + Cast/Call bind a live node straight from your .art — the natural first test, and the same path theia cast/call use. For richer scenarios (co-located drivers, FSMs, loop transports) the harness also has Load Rig + Run Component/Component Call with a Python prober per node type — see the _selftest/components scenarios (Run Component SmProberComponent Call).

7.4 Bring up the stack the test probes

Probe Node binds a live node, so the counter must be running. Build, stage, and start it (the Chapter 5 loop):

bazel build //apps/...
theia install single
theia start                   # CounterNode now live on its TIPC address

7.5 Run the test

With the theia-rf package installed (Chapter 1) and the stack up:

# from your workspace (RF_THEIA_WORKSPACE defaults to the cwd)
robot tests/counter.robot

Robot runs your cases against the live node and writes log.html / report.html with pass/fail + the captured trace. A green report means your live FC behaves as specified.

7.6 Assert on traces (the deeper test)

For nodes that emit Tracer records (state machines, periodic loops), you don't poke and read — you wait for a trace:

# drive a gen_statem node and assert it reached a state, with its data:
Emit Statem Event       DemoStart
Wait For Statem State   PROCESSING    within=2s
Assert Statem Data      visits=1

This is how you test internal behaviour without a request/reply port — the node self-describes via traces, the harness decodes and asserts. (See demo_fsm.robot.)


You now have: a Robot Framework test that drives your FC over the probe and asserts on its behaviour — runnable in CI.

Next: Chapter 8 — The operator GUI, to watch the whole thing live.


6. Provision a board + deploy from the Ground Station · Tutorial index · 8. Observe in the supervisor GUI

Clone this wiki locally