Configuration
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.
axx.yaml
Section titled “axx.yaml”Without an axx.yaml, Axx runs features/ with defaults. The complete, versioned definition is the JSON Schema:
- online:
https://raw.githubusercontent.com/nimbusxr/axx/main/schemas/v0/axx.schema.json - offline:
axx schema(oraxx schema --out axx.schema.json);axx schema --outlinelists the keys, a line each (compact output prints that foraxx schema, and--fullthe schema)
The IntelliJ plugin and the VS Code extension have the schemas themselves, with no network and nothing to add (Set up your editor). Other editors that use the YAML language server, like Neovim, take this first line, which axx init writes:
# yaml-language-server: $schema=https://raw.githubusercontent.com/nimbusxr/axx/main/schemas/v0/axx.schema.jsonA complete example
Section titled “A complete example”# yaml-language-server: $schema=https://raw.githubusercontent.com/nimbusxr/axx/main/schemas/v0/axx.schema.jsonversion: 1axx: 0.5.0 # the release this project runs on, whichever Axx is installed
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 exclusiveUses: [sql.trigger] # so do the scenarios that use these packs or steps 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 rulesfixtures: {} # axx fixtures settings
profiles: # overlays: --profile ci, several in order (--profile ios,watch), or AXX_PROFILE ci: properties: {local.host: docker}Sections
Section titled “Sections”| Section | What it configures | Guide |
|---|---|---|
version |
the schema version of this file; currently 1 |
|
axx |
the release of Axx this project runs on, exactly; only in axx.yaml itself, not an overlay |
Keep a project on one version |
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 |
services
Section titled “services”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, and stops the built-in one-behavior check failing too); 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. |
Finding and merging files
Section titled “Finding and merging files”- With
-c path/to/axx.yaml, that file. Otherwise Axx looks foraxx.yaml(oraxx.yml) in the working directory, then in each parent directory up to the repository root. - With
--profile NAMEorAXX_PROFILE=NAME,profiles.NAMEis merged over the file, and thenaxx.NAME.yamlnext 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). axx.local.yamlnext toaxx.yaml, if present, is merged last. Keep it out of version control for personal settings.--set path.to.key=valuesets 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.-D name=valueoverridesproperties.- A service’s command can write values to the file
$AXX_PROPERTIESnames. They fill in only the properties no one set:-Dandproperties(a profile’s included) win over them (Run beside your own stack).
Paths inside the file (services.*.dir, resources) are relative to the directory of axx.yaml.
Interpolation
Section titled “Interpolation”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.
Errors
Section titled “Errors”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.
axx-packs.yaml
Section titled “axx-packs.yaml”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.
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 optionalaxx-packs.lock pins the versions of module packs; commit both files. Choose packs shows the commands.