How Axx works
Axx is one Go binary with its own Cucumber executor. It reads Gherkin, matches every step to a definition, starts the system under test, runs the scenarios against it from the outside, and reports.
axx.yaml ─┐features ─┼─▶ load & validate ─▶ match steps ─▶ start services ─▶ run scenarios ─▶ report ───────────────▶ stop servicespacks ─┘ (registry) (lifecycle) (workers) (pretty, junit, html…) (cleanup)1. Load
Section titled “1. Load”Axx finds axx.yaml by walking up from the working directory, applies the selected profile and axx.local.yaml, expands ${env:...} and ${sys:...}, and validates the result against the schema. It then parses the feature files with the official Cucumber Gherkin parser and applies the path, line, tag and name filters.
2. Match
Section titled “2. Match”Every step line is matched against the registry: the steps of the packs the project loads. Steps are Cucumber Expressions with custom parameter types such as {ordinal} and {service}. Optional segments like [[ on {service}]] register every variant of a step.
A line that matches nothing is undefined; a line that matches two definitions is ambiguous. axx validate, axx explain and axx run --dry-run are this phase alone: they find both without starting a service or running a step. In a run, a scenario stops at an undefined or ambiguous step, and the report suggests the closest real steps or lists the candidates.
3. Start the services
Section titled “3. Start the services”The lifecycle manager starts services one after another in the order axx.yaml declares them, or, when services declare dependsOn, in dependency order with independent services in parallel. Each runs in its own process group. It polls every ready check until they pass or time out. With active.enabled, only the services the selected scenarios’ tags call for start, with the services they depend on. With axx up, a background supervisor keeps them running and later runs skip this step.
4. Run
Section titled “4. Run”Scenarios run in parallel on run.workers workers; steps within a scenario run in order. Scenarios tagged with a run.exclusive tag run one at a time after the parallel phase.
Each scenario gets a fresh world: its registered services and the state each pack keeps (requests built and responses received, selections, events, browser pages). Nothing in the world is shared between scenarios, which is why parallel runs are safe as long as the external data is unique. See Scenario isolation.
5. Packs
Section titled “5. Packs”A pack is a bundle of steps, parameter types and hooks, its settings in axx.yaml and its tools for agents (axx mcp), plus the per-scenario context its steps share. The packs are rest, mock, grpc, jsonrpc, graphql, sql, mongo, redis, kafka, amqp, mqtt, nats, websocket, sse, asyncapi, logs, files, mail, cli, the web packs (web-core, web-screenshots…), the cloud service packs (aws-s3, gcp-pubsub, azure-blob…), and core for shared parameter types.
A project lists the packs it uses in axx-packs.yaml. The axx binary is the core alone: on first use, it builds a copy of itself with the project’s packs, caches it and runs it in its place (Choose packs).
6. Report and stop
Section titled “6. Report and stop”Reporters follow the run as it goes, as Cucumber Messages events and scenario results, and finish their reports after the last scenario: pretty, progress or compact on the console, TeamCity service messages for the editors’ test runners, and JUnit, HTML, Cucumber JSON, NDJSON messages and the JSON agent report to files. Then services are stopped (signal, grace period, kill) and every cleanup runs, including after a crash or an interrupt. The exit code summarizes the worst outcome (exit codes).
What Axx is not
Section titled “What Axx is not”- Not a unit test framework. Axx tests a running system through its public interfaces. It never loads your code.
- Not a load-testing tool. Parallelism is for speed, not for generating traffic.