Skip to content
axxbetadocs
nextv0.2.26
GitHub
These are the docs of main, not released yet. See the docs of v0.2.26, the latest release.

Configuration

View .mdOpen in Claude

An acceptance project has up to two configuration files, side by side: axx.yaml for the project and axx-packs.yaml for the packs it uses. Both are optional.

Without an axx.yaml, Axx runs features/ with defaults. The complete, versioned definition is the JSON Schema:

Add this first line to get completion and validation in editors that use the YAML language server (VS Code, IntelliJ, Neovim):

# yaml-language-server: $schema=https://axx.nimbusxr.us/schemas/v0/axx.schema.json
axx.yaml
# yaml-language-server: $schema=https://axx.nimbusxr.us/schemas/v0/axx.schema.json
version: 1
run:
paths: [features] # feature files or directories
tags: "not @wip" # default tag expression
uses: [web-core] # only the scenarios that use one of these packs (a profile per platform)
workers: auto # parallel scenarios: a number or auto (CPUs)
exclusive: ["@isolated"] # these run alone, after the parallel phase
order: defined # or random, random:<seed>
timeouts: {step: 60s, scenario: 5m, hook: 2m}
watch: false # show what scenarios do: browsers and devices on screen (axx run --watch)
slowdown: 300ms # in a watched run, pause after each action (axx run --slowdown)
reporters: [pretty, {junit: build/axx/junit.xml}]
resources: ["."] # where seed, payload and schema paths in steps resolve, after the feature file's directory
properties: # ${sys:name}; override with -D name=value
local.host: localhost
openapi:
levels: # suite-wide OpenAPI validation levels
validation.request.security.missing: IGNORE
active:
enabled: false # start only the services the selected scenarios' tags need
onNoTags: fallback
services:
api:
dir: .
command: docker compose up --build
ready:
http:
url: http://${sys:local.host}:8080/health
timeout: 120s
cleanup: docker compose down -v --remove-orphans
lint: {} # axx lint rules
fixtures: {} # axx fixtures settings
profiles: # overlays: --profile ci, several in order (--profile ios,watch), or AXX_PROFILE
ci:
properties: {local.host: docker}
Section What it configures Guide
version the schema version of this file; currently 1
run paths, default tags, workers, exclusive tags, order, timeouts, default reporters Run in parallel, Reports
resources directories that relative file paths in steps resolve against, in order; the directory of axx.yaml is searched last Configure services
properties values for ${sys:name} Configure services
openapi.levels default OpenAPI validation levels, by rule key Validate against OpenAPI
active service startup by the selected scenarios’ tags and packs Manage the services under test
services the system under test (keys) Manage the services under test
packs settings for packs, keyed by pack name each pack’s page under Packs
lint test-data isolation rules (keys) Isolate test data
fixtures fixture factory settings Fixture factories
profiles named overlays below

Each key under services: names one service: something that runs on its own, which scenarios connect to. A program a scenario runs as its user would, like a command-line tool or an MCP server over stdio, belongs in its step (command), not here.

Key Meaning
command How to start the service: a string (split into words, no shell) or an argv list. A command that exits 0 before the service is ready is fine: Axx keeps polling ready.
shell true runs command and cleanup through the shell, for pipes and &&.
dir, env Working directory (relative to axx.yaml) and extra environment.
dependsOn Services that must be ready first. Independent services start in parallel.
enabled false skips the service. Defaults to true.
ready Checks that must all pass: http.url (every URL returns 2xx), tcp (host:port accepts connections), exec (a command exits 0), log (a regular expression matches the service’s output). timeout defaults to 60s, interval to 1s.
stop signal (SIGTERM by default, or SIGINT) is sent to the service’s process group; after grace (default 10s) it is killed.
cleanup Runs after the service stops, even if it crashed or never became ready.
active.tags With active.enabled, the service starts only when a selected scenario has one of these tags.
active.uses With active.enabled, the service starts only when a selected scenario uses a step of one of these packs, like [mobile-android].
debug command, debugger (type, port, host, module, mode), onUnavailable and retry for axx run --debug and axx up --debug.

Rules live under lint.rules; lint.config sets baseDir (patterns are relative to it) and the default mode (error fails, warn only reports); lint.include merges rule files such as axx-lint.generated.yaml. Each rule has:

Key Meaning
name, description Shown in the report.
filePatterns Globs (*, **, ?, [abc], {a,b}), relative to baseDir. A leading ../ reaches outside it. The part before the first wildcard is a directory, and the rest matches the end of each path below it: seeds/*.yaml also finds YAML files in subdirectories of seeds. A pattern that ends in / matches folders, and all the files below each folder it matches count as one file: the folder of a scenario whose data spans several files (seeds/*/).
excludePatterns Globs removed from the match, against the whole path relative to baseDir, for example **.fixture.yaml.
type regex (default) or jsonpath.
regex The first capture group that matched is the value.
jsonPath A path in each file’s tree: order.id, payments[0].id, payments[*].id, an optional $. prefix, or any Jayway JsonPath. Files are read by their extension: JSON, YAML (.yaml, .yml), XML and CSV. A seed’s rows read alike in YAML, flat XML and CSV ($['public.closures'][*]['id']); in other XML, attributes are @name fields and an element with only text is a value.
validation global-unique (default): every occurrence is unique. file-unique: unique within each file. cross-file-unique: may repeat inside a file, never across files. A folder a folder pattern matches counts as one file.
mode Overrides the default mode for this rule.
ignoreValues Values that are shared on purpose.
  1. With -c path/to/axx.yaml, that file. Otherwise Axx looks for axx.yaml (or axx.yml) in the working directory, then in each parent directory up to the repository root.
  2. With --profile NAME or AXX_PROFILE=NAME, profiles.NAME is merged over the file, and then axx.NAME.yaml next to it, if either exists. Several profiles, comma-separated (--profile ios,watch), are merged in that order, each over the ones before: where they set different keys you get both, and where they set the same key the later one wins. A profile that exists in neither place is an error (AXX-E0104).
  3. axx.local.yaml next to axx.yaml, if present, is merged last. Keep it out of version control for personal settings.
  4. --set path.to.key=value sets any key for one run, over all of the above: --set run.workers=1 --set packs.web-core.watch=true. The value is read as YAML.
  5. -D name=value overrides properties.

Paths inside the file (services.*.dir, resources) are relative to the directory of axx.yaml.

String values can reference the environment and properties:

Syntax Value
${env:NAME} environment variable NAME
${sys:name} property name
${sys:name:-default} default when name is not set; defaults can nest (${sys:a:-${env:B}})
$${...} a literal ${...}

The same syntax works in feature files: in service tables and step arguments.

A syntax error or an invalid value stops every command with exit code 2 and points at the line: AXX-E0101 for YAML syntax and AXX-E0102 for values the schema rejects.

The packs a project uses: core, which is always there, and the listed packs. Without the file, a project has no steps. axx pack add, remove and new edit it, and axx init creates it.

axx-packs.yaml
packs:
- rest # one of Axx's packs, by name
- sql
- ./steps # a pack in this repository (a Go package)
- github.com/team/axx-grpc@v1.2.0 # a pack from a Go module; the version is optional

axx-packs.lock pins the versions of module packs; commit both files. Choose packs shows the commands.