Test Case

A test case describes a single HTTP operation. Only name and endpoint are required. All other fields are optional and mirror the fetch Request and Response objects.

Properties

KeyDescriptionDefault
nameHuman readable test namerequired
operationIdUnique identifier for the operationname
phaseExecution phase (setup, main, or teardown)main
dependsOnArray of operationId strings that must pass firstnone
endpointRequest path relative to the base URLrequired
request.methodHTTP methodGET
request.headersAdditional request headersnone
request.bodyRequest payloadnone
request.credentialsFetch credentials mode; 'include' reuses the session cookie captured from an earlier response in the runnone
request.*Any other valid fetch Request optionnone
response.statusExpected HTTP status200
response.jsonExpected partial JSON bodynone
response.schemaZod or JSON schema to validate responsenone
response.headersExpected response headersnone
response.*Other fetch Response fieldsnone
beforeSend(req, state)Function to finalize the requestnone
postTest(res, state, ctx)Function called after the responsenone
tagsTags used with --tags filteringnone
skipSkip this testfalse
focusRun only focused tests when presentfalse
repeatExtra sequential runs of the test0
bombardAdditional simultaneous runs of the test0
delayMilliseconds to wait before runningnone
timeoutPer‑test timeout overrideruntime timeout (60000ms)
recordingPer‑test HTTP recording mode override (off, replay, or record)runtime recording

Example

{
  name: 'Create a post',
  endpoint: '/posts',
  request: {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: { title: 'foo', body: 'bar', userId: 1 }
  },
  response: {
    status: 201,
    json: { id: 101, title: 'foo', body: 'bar', userId: 1 }
  }
}

If the server returns 201 with a matching body the case passes. Any mismatched status or body value results in a failure.

Validating with response.schema

response.schema accepts either a Zod schema (detected via .safeParse) or a raw JSON Schema / OpenAPI 3.0/3.1 Schema Object, validated directly — no __spectestJsonSchema wrapper needed. OpenAPI-only keywords (nullable, example, examples, discriminator, etc.) and 3.0-style boolean exclusiveMinimum/exclusiveMaximum are normalized before validation against a shared Ajv2020 instance, so schemas copied straight out of an OpenAPI document work unmodified.

// JSON Schema / OpenAPI Schema Object
{
  name: 'Get user',
  endpoint: '/users/1',
  response: {
    status: 200,
    schema: {
      type: 'object',
      properties: {
        id: { type: 'string', format: 'uuid' },
        email: { type: 'string', format: 'email' },
      },
      required: ['id', 'email'],
      additionalProperties: false,
    },
  },
}
// Zod
import { z } from 'zod';

{
  name: 'Get user',
  endpoint: '/users/1',
  response: {
    status: 200,
    schema: z.object({ id: z.string().uuid(), email: z.string().email() }),
  },
}

Phases

Tests run in three waves: setupmainteardown. phase is syntactic sugar for dependsOn — every setup test implicitly blocks every main test, and every main test implicitly blocks every teardown test, without listing operationIds by hand. Within a phase, tests still run concurrently as soon as their explicit dependsOn prerequisites pass.

See Helpers for utilities that modify multiple cases at once.