Oda's source ships several test tiers, from benches that render one part of the interface in isolation to suites that run the real agent process end to end. This page maps them, says what each proves, and helps you choose one for the change you are making. Each tier has its own page, where its settings, messages and fixtures live. All of these are developer tooling; none of them is part of the app's user surface.
Slot bench (Client test benches). Renders one part of the interface with the real rendering machinery and test-owned session and workspace doubles, in a jsdom test environment. It is the tier for a single feature's behaviour, its slots and its stores. Mounting checks the services the feature declares and names any that are missing; rendering a slot key before declaring it fails; the store lookup refuses outside the installed renderer; and the file-upload stub rejects until a test replaces it. Every failure names its cause instead of passing silently.
Whole-client bench (Client test benches). Boots the web interface's composed plugin set in the test process and never fetches bundles: the connection is replaced with a mock, so every call to the host side is answered by an endpoint-named double. Start takes options for mounting into a fresh element (mount), waiting for the connection (awaitConnected) and the wait budget (connectTimeoutMs). When the wait runs out, the start fails and names the connection state, the budget, the calls with no answer and the streams still open; a start call made after its test fixture closed is refused. Underneath, the mock is preloaded with answers for the calls the interface makes while starting (the chat list, the default workspace setup, the settings description, the model catalogue, the presets and the account state, with the follow stream declared up front), so a fresh client boots with no sessions and no workspaces; endpoints the startup never touches stay absent, so a new call fails loudly instead of answering nothing.
Remote mocks (Remote mocks and the client test runtime). The endpoint-named doubles behind the whole-client bench, one mock per endpoint and mode: a unary rule answers a call from a fixed value or a handler, and a stream rule scripts an endpoint's openings. They are in-process carriers only, so values cross by reference unchecked and rules match on the endpoint, never on the payload; calls and stream openings are logged with their outcomes.
Mock model server (The mock LLM server). A standalone local process that stands in for a model provider at the messages endpoint, playing one scripted behaviour per accepted request, successes and transport faults alike. It never retries and never interprets recovery policy of its own, so the recovery you are testing belongs to your code. No provider key is needed.
Session replay (Session replay fixtures). Rebuilds each model call from a recorded session log, so the real agent runs its loops with no provider key and the same output every run. A live chat claims its recorded script by first-call order, a fixture is never rewritten, and shapes a log cannot hold (a call that threw before any chunk, a hang, a cancellation) take a sidecar.
Recorded-session snapshots (Recorded-session snapshots). The end-to-end tier: it starts the real agent as a subprocess, drives it with a scripted input, and compares the protocol transcript, the session log and the files the run wrote against committed evidence, keyless by default. Recording calls the live model and never renames or deletes a completed generation; refresh rebuilds the derived files with no key.
Loader smoke (The loader smoke test). Boots an application fixture from its real entry point and configuration inside an isolated temporary folder, so nothing touches your working tree, then drives exactly one task through the fixture's single top-level agent and returns the session id, the final output and the token usage.
Agent-loop testkit (The agent-loop testkit). Gives a loop test the six services an agent loop depends on, mounted in a fixed order and stopping before the loop, or mounts the production loop with an empty agent list and create and claim helpers. It mounts no model adapter, so the test registers the route it exercises, and it adds two inbox stubs beside the testkit's real inbox.
| If the change touches | Start with |
|---|---|
| One feature's interface, its slots or its stores | Slot bench |
| The interface's boot, its plugin set or wiring across plugins | Whole-client bench |
| How your code reacts to model failures | Mock model server |
| Agent behaviour against exact recorded model traffic | Session replay |
| The agent end to end, pinned to committed evidence | Recorded-session snapshots |
| An application's real startup path, or one full run of a fixture | Loader smoke |
| The agent loop itself, its inbox or its claim behaviour | Agent-loop testkit |
Start with what the change touches. A single feature's interface goes to the slot bench; the interface's boot or cross-plugin wiring goes to the whole-client bench; model-failure handling goes to the mock model server; agent behaviour against exact recorded traffic goes to session replay, and its end-to-end equivalent goes to the recorded-session snapshots; an application's real startup path goes to loader smoke; and the agent loop itself goes to the agent-loop testkit. The table above maps each case, and every tier's own page carries its settings and limits.
All of them, as they ship, with one exception: recording a snapshot scenario's fixtures calls the live model. The client benches never reach a model request, the mock model server stands in for the provider, replay and the recorded-session suite rebuild model traffic from recordings, and the loader smoke test runs keyless by design. After a recording, replay and refresh need no key.
The mock server is a live stand-in: real requests arrive, and each one gets a scripted answer or fault on the wire, so you can watch how your code reacts to resets, stalls and malformed data. Replay never shapes traffic at request time; it reconstructs each model stream from a recording, so the transcript is fixed and the run is deterministic. The recorded-session suite builds on replay, while the mock server is a tier of its own.
Yes, two. The recorded-session suite starts the real agent as a subprocess and drives it through a scripted input, and the loader smoke test boots a fixture application from its real entry point and configuration in an isolated folder. The other tiers run in the test process or as the standalone mock server.
It starts the same composed plugin set, through the same boot the app uses, with the plugin modules loaded in the test process and no bundles fetched. The shortcuts are host-side: everything the interface calls is the mock, and the bench's own proxies replace the generated remote clients, so those calls get no wire-level validation or name mapping. Assert on the code an answer carries, never on the error class.
Because a silent pass would hide the gap you were testing for. A missing service stops a mount and names itself; a slot key rendered before it is declared fails; an unstubbed call names itself at the call site; a call with no mock rule is recorded and reported at teardown; and endpoints nobody booted stay absent, so a new call fails loudly. Each failure points at the fixture or the wiring that is missing.
Yes. The recorded-session suite runs on model replay and the subprocess launcher; the whole-client bench runs on the client runtime over the remote mock; and smoke compositions mount the replay fixture in place of a live model, so a smoke test needs no provider key. Picking a top tier means using the tiers underneath it.