Variables

Define test data upfront and extract runtime values to chain multi-step workflows.

Defining variables

Variables are key-value pairs defined at the definition level or test level:

{
  "name": "my-suite",
  "variables": {
    "baseEmail": "test@example.com"
  },
  "tests": [
    {
      "name": "Test 1",
      "variables": {
        "testEmail": "specific@example.com"
      },
      "steps": [ ... ]
    }
  ]
}

Interpolation: {{variableName}}

Reference variables with {{variableName}} anywhere in actions and assertions:

WhereExample
Action URLs"url": "api-gateway/api/users/{{userId}}"
Action headers"Authorization": "Bearer {{token}}"
Action body (string values)"email": "{{email}}"
Database queries"query": "SELECT * FROM users WHERE id = {{userId}}"
Assertion values"value": "{{email}}"
Match block fields"url": "user-service/{{path}}"
Console log messages"value": "User {{userId}} created"

Extraction

Extract values from responses at runtime using JSONPath expressions:

{
  "name": "Create user",
  "action": {
    "type": "httpRequest",
    "method": "POST",
    "url": "api-gateway/api/users",
    "body": { "email": "{{testEmail}}" }
  },
  "extract": {
    "userId": "$.body.id",
    "authToken": "$.headers.x-auth-token",
    "firstName": "$.body.user.profile.name",
    "firstItem": "$.body.items[0].id"
  }
}

Extracted values become variables available in all subsequent steps.

Regex extraction

Extract rules can also be regex extract objects — resolve a JSONPath first, then apply a regex pattern to pull out a substring:

{
  "extract": {
    "userId": "$.body.id",
    "correlationId": {
      "path": "$.body.message",
      "pattern": "correlation_id=([a-f0-9-]+)",
      "group": 1
    }
  }
}
FieldTypeRequiredDescription
pathstringYesJSONPath to the source value
patternstringYesRegex pattern (with capture groups)
groupnumberNoCapture group index (default: 1; use 0 for full match)

The JSONPath is resolved first, the result is coerced to a string, then the regex is applied. An error is raised if the path doesn't exist, the pattern doesn't match, or the capture group is out of range.

When to use regex extraction. Use the simple string form when the value you need is already a discrete field. Use the regex form when the value is embedded inside a larger string — for example, extracting an ID from a log message or a token from a URL.

Extract paths

For HTTP responses:

For database query results:

Extract paths vs assertion paths. Extract paths use a flat document ($.body.field). Assertion paths use a nested format (response.body.field). Don't mix them — see Assertions for assertion path syntax.

Extraction in assertion blocks

You can also extract values from within assertion blocks — useful for capturing values from intercepted inter-service traffic:

{
  "match": {
    "origin": "api-gateway",
    "method": "POST",
    "url": "order-service/api/orders"
  },
  "extract": {
    "internalOrderId": "$.response.body.orderId"
  },
  "assertions": [
    { "path": "response.status", "operator": "eq", "value": 201 }
  ]
}

Precedence

Variables come from three sources, in order of increasing precedence:

  1. Definition-level variables — shared across all tests
  2. Test-level variables — per-test overrides
  3. extract on steps — runtime extraction (overwrites all hardcoded values)

Scoping rules

Build-time vs runtime variables

SyntaxResolvedByPurpose
${{VAR}}Build timeDefinition resolverConfig values from config.yaml env
{{VAR}}RuntimeTest agentVariables from variables / extract

You can combine both — use ${{}} inside a variables value to compose runtime variables from config:

{
  "variables": {
    "baseUrl": "${{API_HOST}}/v1"
  }
}