Ranveo
  • Built player
  • Mono · IL2CPP
  • No C# in the tests
  • Hidden window
  • uGUI
  • C# · MIT · UPM
UnityuGUI apps beyond games

Your Unity tests check the code. Ranveo checks the app.

Keep your Unity Test Framework tests for the code. Ranveo tests the built player the way your users see it, with no C# in the tests.

Ranveo SDK for Unity: C#, MIT licence, a UPM package.

Aurora Home Twin, a Unity digital twin of an apartment, with its uGUI objects found by role

15 of 17 conformance checks pass on Unity

Unity Test Framework

Your code has tests. Now test the app.

Keep the Unity Test Framework for the code. Ranveo adds the layer above it: the built player, tested the way your users see it, in steps anyone on the team can record or ask the AI assistant to write.

Checks the code Unity Test Framework

[Test]
public void SetpointStopsAt28()
{
  var room = new RoomModel();
  room.Setpoint = 35f;
  Assert.AreEqual(28f, room.Setpoint);
}
Written in
C#, with NUnit
Runs
Edit Mode and Play Mode tests
Results
The Test Runner window and an XML file

Checks the app Ranveo

{ "tap": { "name": "inp_search" } },
{ "type": "Living" },
{ "tap": { "role": "item", "text": "Living room" } },
{ "tap": { "role": "button", "text": "Apply" } },
{ "wait": { "visible":
  { "text": "Setpoint synced to Aurora T1" } } }
Written as
Steps, recorded or written by the AI assistant
Runs
The built player, Mono or IL2CPP
Results
History, bug tracker and reports on the team server
Builds

Your release build stays byte-for-byte the same.

The SDK compiles only when the RANVEO symbol is set, and your hooks sit behind #if RANVEO. Tests live outside the player, so changing a test never means a rebuild.

Your test build

Scripting Define SymbolsRANVEO
#if RANVEO
using Input = Ranveo.SessionInput;
#endif

build hash · with the Ranveo SDK a91c 04de 7b12 55f0

Your release build

build hash 3f9c 21ab 77e0 9d41

The same build, without the SDK at all

build hash 3f9c 21ab 77e0 9d41

Byte-for-byte the same

  • One scripting define symbol, on the test build only
  • Mono or IL2CPP, obfuscated or not
  • Change a test, run it again: no rebuild
Hidden window

Your editor stays yours.

On Windows the player runs in a hidden window that never takes the focus, so you keep working while tests run, and the screen is still captured.

0
times a test takes the focus
30fps
in the live view, while you work
  • No taskbar button, never activated
  • On Linux and macOS, a normal window of the size you set
Determinism

Deterministic when you need it.

An optional virtual clock on Unity’s scaled time, app state and commands open to tests, and a reset the runner calls between tests.

  • Time stops between requests, frames advance in fixed steps
  • State, commands, screens and busy probes in a few lines
  • The runner reuses the app between tests
#if RANVEO
[RuntimeInitializeOnLoadMethod(
    RuntimeInitializeLoadType.SubsystemRegistration)]
static void Options() =>
    RanveoSdk.Options.VirtualClock = true;
#endif

Time.timeScale0 between requests, fixed steps during them

Performance

Frame time and memory in every test.

Each test measures the player’s frame time and managed heap. Set a budget, and a test that goes over it fails, even when every step passed.

  • Limits for the slowest frame and the average
  • The heap’s peak and growth, per test
  • Unity’s log in each test’s log

living-room.test.json · frame time per stepfailed · budget

15.3 ms average, under 1641 ms slowest, at step 9182 MB managed heap, at its peak

"budget": { "render_ms_max": 33, "render_ms_avg": 16 }
One test

The embedded device and its Unity twin, in one test.

Tap Heat on the Aurora T1, then check the twin. Each step names the app it acts on, the apps share the test’s values, and they can run on different machines.

The Aurora T1 thermostat on its embedded device, set to Heat
Aurora T1 app: "device"
{
  "name": "Heat on the device shows in the twin",
  "apps": ["device"],
  "steps": [
    { "app": "device",
      "tap": { "role": "button", "text": "Heat" } },
    { "app": "device", "as": "sp",
      "store": { "subject": "heat_setpoint" } },
    { "wait": { "text": { "name": "dd_mode" },
                "equals": "Mode: Heat" } },
    { "expect": { "subject": "setpoint",
                  "value": "${sp}" } }
  ]
}
The Aurora Home Twin in Unity, showing Mode: Heat
Aurora Home Twin the test’s own app
Set up

From project to first test in three steps.

3 levels · about ten minutes

  1. Level 1

    Add the package

    From a folder or the package’s git address.

    // Packages/manifest.json
    "com.ranveo.unity":
      "file:../path/to/sdk/unity"
  2. Level 2

    Mark the test build

    Add RANVEO to its Scripting Define Symbols.

    #if RANVEO
    void Awake() {
      RanveoSdk.Screen("main", mainScreen);
      RanveoSdk.Reset = BackToStart;
    }
    #endif
  3. Level 3

    Run the tests

    Or ask the AI assistant to write the first one.

    ranveowall test tests \
      --platform unity \
      --set executable=build/AuroraTwin.exe \
      --set width=1280 --set height=720
Under the hood

Your canvas, as objects.

Ranveo reads the uGUI objects on your canvases. Give the ones a test uses a name, or find them by role and text.

Name
The GameObject’s name, without (Clone)
Text
A Text’s content without rich-text tags, a field’s content, a button’s first label
Role
From the uGUI component, or the one you set with RanveoRole
Screen
The registered screen that is active

Today

  • uGUI with the built-in Text component only: TextMeshPro, UI Toolkit, IMGUI and the new Input System are not supported yet.
  • 3D content is not an object in the tree; a busy probe tells tests when it has settled.
  • Hidden runs on Windows only, and one display.

Roles, from the uGUI component

  • Buttonbecomesbutton
  • Togglebecomescheckbox
  • Toggle in a groupbecomesradio
  • Sliderbecomesslider
  • InputFieldbecomesinput
  • Dropdownbecomesdropdown
  • ScrollRectbecomeslist
  • Textbecomestext
  • Imagebecomesimage

In a test

{ "tap": { "name": "btn_apply" } }
{ "tap": { "role": "button", "text": "Apply" } }
{ "expect": { "subject": "setpoint", "value": 225 } }
15/17

conformance checks pass on the Unity reference app. The two that don’t, emulate and route, test what only a web page has.

Compare every platform
  • busy: passes
  • clear: passes
  • clock: passes
  • commands: passes
  • emulate: skipped
  • input: passes
  • keys: passes
  • layout: passes
  • locators: passes
  • platform: passes
  • popup: passes
  • reset: passes
  • roles: passes
  • route: skipped
  • screens: passes
  • subjects: passes
  • visibility: passes
Questions

Unity, answered.

Do I still need the Unity Test Framework?

Yes, for the code. Keep your Edit Mode and Play Mode tests: Ranveo adds the layer above them, the built player tested the way your users see it.

Does it work with IL2CPP?

Yes. The SDK is an assembly of its own: IL2CPP keeps its entry point, and obfuscators that work on Assembly-CSharp leave it alone.

What if someone runs the test build by hand?

The SDK starts only when the Ranveo agent starts the player, so it behaves like a release build.

Do I have to rename my objects?

Only the ones a test uses that still have Unity’s generated names, such as Button (1). Or find them by role and text.