# Run your test suite

Run your application's assertions against selected twins, using the same SDK calls as production.
This complete example uses Node's test runner, a local Stripe twin and no real vendor credentials.
Use Node 22.6 or newer and npm; installing packages needs registry access.

## Save the app and its test

In an empty directory, save `package.json`:

```json file=package.json
{
  "name": "signup-tests",
  "private": true,
  "type": "module",
  "scripts": { "test": "node --test --test-reporter=tap signup.test.mjs" },
  "dependencies": { "stripe": "17.7.0" },
  "devDependencies": {
    "@volter/world": "3.0.63",
    "@volter/twin-stripe": "3.0.1"
  }
}
```

Save `.env.example`, with an empty value:

```text file=.env.example
STRIPE_SECRET_KEY=
```

Save `signup.test.mjs`:

```js file=signup.test.mjs
import { test } from 'node:test';
import assert from 'node:assert/strict';
import Stripe from 'stripe';

test('signup stores a retrievable customer', async () => {
  const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  const created = await stripe.customers.create({ email: 'ada@example.com', name: 'Ada' });
  const saved = await stripe.customers.retrieve(created.id);
  assert.equal(saved.id, created.id);
  assert.equal(saved.email, 'ada@example.com');
  assert.equal(saved.name, 'Ada');
});
```

The test checks a stored result through the real SDK; a fabricated success response alone would
not pass it. [Choose a twin](./choose-a-twin.md) explains selecting an implementation for these calls.

## Run the suite inside the World

```bash
npm install
npx volter world init --name signup-tests
npx volter world up
npx volter world clock set 2026-01-15T12:00:00Z
npx volter world run -- npm test
```

```text
# pass 1
# fail 0
```

`run` supplies fake credentials and routes selected SDK destinations. The World stays up after
the command finishes; its state accumulates between commands until you reset it.

## Inspect the writes

```bash
npx volter world log
npx volter world diff
```

```text
customer.create
event.record
```

SDK reads verify records; the log tells you which stored operations the app performed. It is
not a line-coverage report or a transcript of every read. [Inspect a World](./inspect-a-world.md)
adds the dashboard and vendor screens.

## Repeat from known data

Reset before the next suite run and set the same starting clock:

```bash
npx volter world reset
npx volter world clock set 2026-01-15T12:00:00Z
npx volter world run -- npm test
```

```text
# pass 1
# fail 0
```

Create stored prerequisites through the vendor API in your setup or project-owned seed.
[Seed and reset](./seed-and-reset.md) makes that starting data repeatable. Use separate World
roots for concurrent suites that must not share mutations; do not reset a World another test uses.

For a scripted answer, rate-limit error or retry path, see [shape the World for a test](./shape-the-world-for-a-test.md).
Freeze time before TTL assertions and advance it explicitly. Generative twins check calls and
state effects; they do not assess the prose quality of a real model.

## Other runners and browser tests

Replace `npm test` with your own Node runner's command. A Bun test runner needs its injector
armed as described in the [CLI reference](../reference/cli.md); install the imported kernel
package in the app, since a global CLI does not supply app dependencies. Non-Node programs and
browser-side vendor requests need their supported routing path; see [route a CLI](./route-a-cli-through-the-world.md)
and [run a full stack](./run-a-full-stack.md).

Catalog assessment measures its published journeys. Your application suite measures your own
requirements; passing either does not prove every vendor operation or state works.

## Stop

```bash
npx volter world down
```

```text
Stopped signup-tests
```

Stop application consumers before the World. Ordinary shutdown retains data.
[Use in CI](./use-in-ci.md) runs the same commands with cleanup after success or failure.

<!-- Fenced tutorial executor: packages/cli/src/journeys/tutorial.ts. Execution scope is recorded separately. -->
