Testing

Test Data

Routebase has a native test-data system so you don't need inline setup in every test, shared "magic" databases, or external shell scripts that drift out of sync with your specs. It rests on three concepts that compose:

Concept What it is
Fixture A reusable, structured data set (YAML or JSON) referenced from tests and mocks via {{fixture.*}} placeholders.
Seed A sequence of HTTP steps that runs before or after a test suite to set up or clean up state.
Snapshot A recorded "known good" state that can be restored before each suite run for a consistent baseline.

A typical setup: a suite runs a pre-run seed that POSTs fixture entries to your API, test cases reference the fixtures in their requests, and a snapshot resets everything to a clean baseline before each run.

The Test Data page

Open Test Data from the sidebar (requires tests:read). The page is split into three sections:

Section Contents
Fixtures This project's fixtures. Empty state: "Create your first fixture to share test data across tests, mocks and docs."
Seeds Reusable setup/cleanup HTTP sequences.
Snapshots Recorded restore points.
The Test Data page with fixtures, seeds and snapshots sections

Fixtures

A fixture is a named set of structured data. Click New Fixture (requires tests:write). The dialog explains it up front: "Fixtures are reusable test data sets. Link a schema to fill a typed table, or edit the raw YAML/JSON directly."

Every fixture carries a Name (e.g. users), an optional Description, and comma-separated Tags (e.g. auth,users,smoke). How you edit the content depends on the editor mode.

Table vs. Advanced

A toggle at the top of the dialog switches between two editors:

Mode When to use
Table The default for project fixtures. Link one of your schemas and fill a typed, spreadsheet-style table — one row per record. Content is always stored as JSON.
Advanced (YAML/JSON) The raw code editor for nested or non-tabular data. Pick the FormatYAML or JSON — at creation; the format is fixed afterwards.

Table mode

Pick a schema with the SpecSchema selectors at the top of the editor. The chosen schema's properties become the table's typed columns, and you add and edit records row by row. Until you pick one, the editor prompts "Select a schema above to define your columns." Table mode always stores JSON, so there's no format choice and no separate preview — the table is the view.

Linking a schema keeps fixtures aligned with the shapes your API actually uses, and a fixture whose schema matches an endpoint's request body can be inserted directly into a seed step (see Seeds below).

Advanced mode

Advanced mode is a syntax-highlighted code editor for the raw fixture content. Parse errors are shown inline and block saving. Example (YAML):

alice:
  email: alice@example.com
  role: admin
bob:
  email: bob@example.com
  role: member

Dialog tabs

Both modes share the dialog's tabs:

  • Editor — the table or the code editor for the mode you're in.
  • Preview — the fixture rendered as a table. Advanced mode only.
  • Warnings — appears when the fixture has validation warnings; warnings never block saving.
  • Used By — which test cases and suites reference the fixture. Edit mode only.

Every save creates a new version — the list shows the current version as v3, v4, and so on. Open History from a fixture's menu to browse previous versions and restore any of them with one click; up to 50 versions are retained per fixture, older ones prune automatically.

Deleting a fixture is a soft delete — tests that reference it will fail until it's restored, and the confirmation dialog says so.

Fixture limits

Each fixture is capped at 1 MB. The number of fixtures depends on your plan — Free: 5, Starter: 25, Pro: 100, Enterprise: unlimited. At the limit, creating a fixture opens an upgrade prompt.

The count is per owner, not per organization: each project gets its own allowance, and the organization library below will get one of its own on top of them.

Organization fixture library

Cross-project data — test credit cards, sample addresses, country codes — is a natural fit for an organization-wide library that every project can import. This shared library is not yet available and will roll out in a later release. For now, fixtures live in the project where you create them.

Substitution syntax

Anywhere Routebase renders a request template — test-case URLs, headers, bodies, assertion expected values, seed steps, mock responses — you can reference a fixture:

{{fixture.users.alice.email}}              — dot path
{{fixture.users[0].id}}                    — array index
{{fixture.users[*]}}                       — wildcard (returns array)
{{fixture.users[?(@.role=='admin')]}}      — filter (== / !=)

Pipes

Pipes transform the resolved value; chain them with |:

Pipe Effect
toJson Serialize to a JSON string
toJsonArray Serialize as a JSON array
count Number of entries
first First entry
last Last entry
random Random entry
pluck:<field> Extract one field from each entry
where:<field>=<value> Filter entries by equality
jsonPath:<expr> JSONPath expression over the entries

Chaining example:

{{fixture.users | where:role=admin | pluck:email | toJsonArray}}

Mixing namespaces

Fixture placeholders coexist with environment variables (referenced by their bare name, {{BASE_URL}}), data-set columns ({{data.*}}), and dynamic values ({{$uuid}}, {{$timestamp}}, ...):

{{BASE_URL}}/users/{{fixture.users.alice.id}}

Template inputs highlight each namespace in its own color (fixtures teal, environment variables blue, data columns purple, dynamic values green) and offer autocomplete as soon as you type {{.

Seeds

Seeds are ordered HTTP sequences that prepare and tear down test data. Click New Seed in the Seeds section (requires tests:write). The editor has three tabs:

  • MetadataName (e.g. Standard Catalogue), Description, a Stop on error toggle (abort the sequence on the first failed step), and Timeout (seconds) (default 60) for the whole sequence.
  • Pre-Run Steps and Post-Run Steps — the two step lists.

Step types

Each step is a card with a type selector:

Type Purpose
HTTP Request Fire a single HTTP call — method, URL, headers, body, expected status codes (e.g. 200,201), and captures.
Fixture Loop Iterate over every entry of a fixture and fire one request per entry. Choose the fixture from the Fixture to loop over dropdown and name a Loop variable (e.g. user), then reference {{user}} in the URL or body. Only array-style fixtures can be looped; others appear in the list but are disabled.
Delay Sleep for N milliseconds (up to 300,000) — useful for rate-limited APIs.
Test Case Ref Run an existing test case as part of the sequence. Click Pick test case… to choose one, or toggle Enter id manually to paste a test-case id.

Building an HTTP step

HTTP Request and Fixture Loop steps have a spec-aware editor, so you rarely type a request by hand:

  • From spec… — pick an endpoint straight from one of your API specs (choose the API Specification, an optional version, then search the endpoint list). Selecting an endpoint fills the step's method and URL.
  • Method and URL — a method dropdown next to a URL field with {{...}} highlighting; start typing {{ for autocomplete of variables and fixtures.
  • Body — a Generate body button builds a sample body from the endpoint's request schema. When the endpoint defines a request schema, the body offers Form and Raw tabs; otherwise it's a single raw editor with {{fixture.*}} / {{var}} autocomplete. If a fixture is linked to the endpoint's request schema, the editor offers to insert a reference to it.
  • Headers — a structured name/value editor; values accept {{var}} placeholders.
  • Expected status codes — a comma-separated list (e.g. 200,201) the step must return to count as a success.
  • Captures — extract values from the response into runtime variables. The response-path field autocompletes JSONPaths derived from the picked endpoint's response schema.

Captures use a name:jsonPath list — e.g. id:$.id,token:$.token. Captured variables are available to later steps and, for pre-run seeds, to the suite's test cases; prefix a capture name with fixture. to merge the value into the fixture namespace instead.

Steps can be reordered with the up/down controls and removed individually.

Dry Run

The Dry Run button validates a seed without touching your API: Routebase resolves all variables and fixtures, expands loops, and returns the planned call list plus any errors and warnings. Use it to catch broken paths before a real run.

Snapshots

A snapshot pins a reproducible setup state. Recording and restoring snapshots requires the tests:execute permission.

  1. In the Snapshots section, click Record Snapshot — "Runs the selected seed once and stores cleanup instructions so the state can be restored before each suite run."
  2. Enter a Name (e.g. After Onboarding) and optional Description, pick the Environment, and choose the Base seed to execute.
  3. Click Record snapshot.

The snapshot list shows each snapshot's type, resource count, and last restore time. View details opens the resource manifest — the cleanup calls, in deletion order, that a restore executes — along with any Warnings from recording (for example, resources whose delete route couldn't be derived). Restore replays the cleanup and re-executes the base seed.

Privacy: snapshots store resource IDs and cleanup instructions only — no personal data is persisted. Fresh test data is generated on every restore from the base seed and fixtures. The create and detail dialogs surface this as an info notice.

Attaching test data to a suite

Open Suite Settings in the Test Runner to wire seeds and snapshots into a suite:

  • Pre-run seed — "Runs before the first test case. A failing pre-run seed aborts the suite."
  • Post-run seed — "Runs after the last test case. Failures are surfaced as warnings only."
  • Reset snapshot — "Restored before the pre-run seed. Cleanup runs in reverse order, then the base seed re-executes to produce fresh data. A failing restore aborts the suite."
  • Fixture scope — which fixtures the suite's runs can see. All fixtures (the default) loads every project fixture plus every imported organization fixture. Only selected loads just the fixtures you tick — a test referencing any other fixture will not resolve it. All except selected loads everything but the ticked ones. Names are the ones a run resolves a fixture under, so imported organization fixtures appear under their alias where they have one.

Scope is set per suite and applies to every case in the run: the suite loads one fixture set once, so that values captured with CaptureToFixtureName stay visible to later cases.

During a run, the results panel shows dedicated Pre-Run Seed, Post-Run Seed, and Snapshot Reset banners with per-step outcomes, elapsed times, and any captured variables.

Using fixtures beyond tests

  • Mock Server — a mock rule's response can be a Fixture Reference (the fixture is rendered as the response every time the rule matches, optionally through a pipe) or Smart Mock (Fixture + Faker), which resolves {{fixture.*}} placeholders inside a dynamic template. See Mock Server.
  • AI agents via MCP — the Routebase MCP server exposes list_fixtures and get_fixture tools, so agents can read your test data. See MCP Quickstart.

Sample data for new projects

When you create a project, you can start from a sample data set: Hello World Starter (a minimal set of fixtures and a simple seed) or Pet Store (rich demo) — a full demo with fixtures and seeds that's ideal for exploring every test-data feature right away.

Limits at a glance

Limit Value
Fixture size 1 MB per fixture
Fixtures per owner (each project, and the org library separately) 5 (Free) / 25 (Starter) / 100 (Pro) / unlimited (Enterprise)
Versions per fixture 50 — oldest auto-prune
Seed timeout 60 s default, configurable per seed
Delay step up to 300,000 ms