Atmos Tests
Use type: test to run smoke tests that validate deployed stacks or other
integration tests. It groups existing typed steps into a test report: passing
logs stay hidden, failures reveal their buffered output, and independent checks
continue by default.
Read patterns for complete custom-command, HTTP,
parallel/dependency, matrix, script/interpreter, and post-apply hook examples.
Use atmos-steps for shared step fields and the relevant
surface skill: custom commands,
workflows, or hooks.
Authoring Process
- Inspect the project's commands, workflows, hooks, and existing test scripts.
Discover actual stack/component names and deployment outputs before choosing
targets. Do not invent endpoints or hard-code credentials.
- Prefer a custom command for a directly invoked suite with its own arguments
or flags. Use a workflow for an existing orchestration sequence, or a lifecycle
hook to run checks after deployment. There is no built-in standalone
atmos test
command: defining a custom command named test creates that invocation.
- Choose the smallest step type that expresses each assertion. A command that
merely prints a response is not an assertion; it must fail when expectations
are unmet. Name cases descriptively and use
title for readable display labels.
- Keep direct children sequential. Use a sibling
parallel or matrix group
when cases should run concurrently. Set a concurrency limit suitable for the
service and isolate mutable fixtures for each concurrent case.
- Keep default failure-only output and continuation unless the test contract
requires otherwise. Add bounded retries for eventual consistency; do not use
retries to conceal a reproducible assertion failure.
- Verify a passing case and an intentionally failing case against local fixtures
or an appropriate test environment. Check the exit status, failure details,
continuation, and expanded leaf totals. Restore the intended expectations.
Choose a Test Step
| Need |
Step and pattern |
| HTTP status, health endpoint, or response text |
http with expect.status and optionally expect.response; prefer this over curl and shell parsing. |
| JSON structure, numerical comparisons, or multi-part assertions |
script with explicit interpreter and script; consume an HTTP step's response through its result value or use a language client. |
| Existing test script or external CLI |
shell with command; ensure assertion failures propagate as a nonzero exit. Prefer checked-in scripts for substantial logic. |
| Required tools, files, or directories |
require with tools, files, or dirs; useful as a precondition, not proof that a service is healthy. |
| Atmos validation or inspection with meaningful exit status |
atmos with a command such as validate stacks; inspect-only commands need a separate assertion on their output. |
| An isolated test runner image |
Foreground container with a finite test command; consult its step documentation for image/runtime fields. Do not detach it or request a TTY. |
| Independent named checks |
parallel with max_concurrency; use child needs for prerequisites and result consumption. |
| The same checks across regions, endpoints, runtimes, or other axes |
matrix with named axis lists and max_concurrency; use {{ .matrix.<axis> }} in child fields. |
script requires both interpreter and script; do not put command on it.
Python, Node.js, and other interpreters are patterns, not new step types. Declare
needed runtimes using the owning command/workflow's dependencies.tools and the
project's toolchain conventions. require verifies availability; it never installs.
Execution and Failure Rules
- Direct children run in declaration order.
test does not accept
max_concurrency; put it on parallel or matrix.
needs is supported on children of parallel/matrix, not direct children of
test. Use it whenever a check consumes another concurrent check's result.
A failed dependency skips its dependent checks.
- Parallel and matrix groups can be siblings under
test, but cannot contain
another parallel/matrix group. Nested test groups are unsupported.
fail.mode: wait_all is the default: independent tests continue, then unhandled
failures fail the group. Unset when permits continuation after a failure;
explicit when: success would instead gate a check on success.
fail.mode: fail_fast cancels remaining work; fail.max_failures configures the
existing failure threshold. best_effort records failures but lets the group
succeed. Use these deliberately, especially for deployment gates.
- Preserve explicit child
continue and nested group failure policies. For
example, continue: always tolerates a leaf failure, but that case still appears
red in the report. Tolerated failures are not passing assertions.
retry retries a leaf as one case; the final attempt determines its outcome.
Use explicit expectations and bounded attempts for readiness checks.
- Use supported noninteractive registered handlers. Interactive prompts, terminal
handoff, process replacement (
exec, exit), background/async work, recording
or emulator sessions, and wait/wait-all/cancel steps cannot run inside a test.
Start services and prepare fixtures outside the group.
Output and Results
Set output: failures (the default) or output: all on the test group. These are
scalar test-specific choices, not raw, none, log, or viewport. Both buffer
per leaf; all also reveals successful logs at completion. Do not redirect leaf
output to /dev/null: it removes the evidence needed when a test fails.
The terminal report uses a hierarchical tree and progress bar. CI/non-TTY output
is static. Counts cover expanded leaves once, excluding group nodes; retries do
not add cases. The summary includes passed, failed, skipped, canceled, and elapsed
time. Group result metadata exposes total, passed, failed, skipped, and
canceled.
Use scoped environment variables and step result values rather than shared files
or process-global state to pass data. Matrix cases must not overwrite the same
fixture paths. Keep secrets in existing Atmos auth/secret mechanisms; masking
still applies to captured output, but do not deliberately print credentials.
Place optional success messages after the test group with when: success and
content such as Tests passed. Message-only steps inside the group would count
as cases without validating anything.
Canonical References
Consult the project docs for exact fields before extending a pattern:
website/docs/workflows/workflows/workflow/steps/type/test.mdx
- The neighboring
http.mdx, script.mdx, shell.mdx, require.mdx,
atmos.mdx, container.mdx, parallel.mdx, and matrix.mdx files.
website/docs/workflows/workflows/workflow/steps/continue.mdx and retry.mdx.
examples/tests/atmos.yaml for runnable local examples.
If behavior is unclear, inspect pkg/schema/test_step.go and the registered
handlers under pkg/runner/step/ rather than inventing test-only assertion fields.
1---2name: atmos-tests3description: Author Atmos smoke tests, post-deployment stack checks, and integration tests using type: test, HTTP assertions, shell or script/interpreter checks, require gates, parallel dependencies, matrix cases, and lifecycle hooks. Use for test suites in Atmos configuration, not Go unit tests of Atmos itself.4---56# Atmos Tests78Use `type: test` to run smoke tests that validate deployed stacks or other9integration tests. It groups existing typed steps into a test report: passing10logs stay hidden, failures reveal their buffered output, and independent checks11continue by default.1213Read [patterns](references/patterns.md) for complete custom-command, HTTP,14parallel/dependency, matrix, script/interpreter, and post-apply hook examples.15Use [atmos-steps](../atmos-steps/SKILL.md) for shared step fields and the relevant16surface skill: [custom commands](../atmos-custom-commands/SKILL.md),17[workflows](../atmos-workflows/SKILL.md), or [hooks](../atmos-hooks/SKILL.md).1819## Authoring Process20211. Inspect the project's commands, workflows, hooks, and existing test scripts.22 Discover actual stack/component names and deployment outputs before choosing23 targets. Do not invent endpoints or hard-code credentials.242. Prefer a custom command for a directly invoked suite with its own arguments25 or flags. Use a workflow for an existing orchestration sequence, or a lifecycle26 hook to run checks after deployment. There is no built-in standalone `atmos test`27 command: defining a custom command named `test` creates that invocation.283. Choose the smallest step type that expresses each assertion. A command that29 merely prints a response is not an assertion; it must fail when expectations30 are unmet. Name cases descriptively and use `title` for readable display labels.314. Keep direct children sequential. Use a sibling `parallel` or `matrix` group32 when cases should run concurrently. Set a concurrency limit suitable for the33 service and isolate mutable fixtures for each concurrent case.345. Keep default failure-only output and continuation unless the test contract35 requires otherwise. Add bounded retries for eventual consistency; do not use36 retries to conceal a reproducible assertion failure.376. Verify a passing case and an intentionally failing case against local fixtures38 or an appropriate test environment. Check the exit status, failure details,39 continuation, and expanded leaf totals. Restore the intended expectations.4041## Choose a Test Step4243| Need | Step and pattern |44|---|---|45| HTTP status, health endpoint, or response text | `http` with `expect.status` and optionally `expect.response`; prefer this over `curl` and shell parsing. |46| JSON structure, numerical comparisons, or multi-part assertions | `script` with explicit `interpreter` and `script`; consume an HTTP step's response through its result value or use a language client. |47| Existing test script or external CLI | `shell` with `command`; ensure assertion failures propagate as a nonzero exit. Prefer checked-in scripts for substantial logic. |48| Required tools, files, or directories | `require` with `tools`, `files`, or `dirs`; useful as a precondition, not proof that a service is healthy. |49| Atmos validation or inspection with meaningful exit status | `atmos` with a command such as `validate stacks`; inspect-only commands need a separate assertion on their output. |50| An isolated test runner image | Foreground `container` with a finite test command; consult its step documentation for image/runtime fields. Do not detach it or request a TTY. |51| Independent named checks | `parallel` with `max_concurrency`; use child `needs` for prerequisites and result consumption. |52| The same checks across regions, endpoints, runtimes, or other axes | `matrix` with named axis lists and `max_concurrency`; use `{{ .matrix.<axis> }}` in child fields. |5354`script` requires both `interpreter` and `script`; do not put `command` on it.55Python, Node.js, and other interpreters are patterns, not new step types. Declare56needed runtimes using the owning command/workflow's `dependencies.tools` and the57project's toolchain conventions. `require` verifies availability; it never installs.5859## Execution and Failure Rules6061- Direct children run in declaration order. `test` does not accept62 `max_concurrency`; put it on `parallel` or `matrix`.63- `needs` is supported on children of `parallel`/`matrix`, not direct children of64 `test`. Use it whenever a check consumes another concurrent check's result.65 A failed dependency skips its dependent checks.66- Parallel and matrix groups can be siblings under `test`, but cannot contain67 another parallel/matrix group. Nested `test` groups are unsupported.68- `fail.mode: wait_all` is the default: independent tests continue, then unhandled69 failures fail the group. Unset `when` permits continuation after a failure;70 explicit `when: success` would instead gate a check on success.71- `fail.mode: fail_fast` cancels remaining work; `fail.max_failures` configures the72 existing failure threshold. `best_effort` records failures but lets the group73 succeed. Use these deliberately, especially for deployment gates.74- Preserve explicit child `continue` and nested group failure policies. For75 example, `continue: always` tolerates a leaf failure, but that case still appears76 red in the report. Tolerated failures are not passing assertions.77- `retry` retries a leaf as one case; the final attempt determines its outcome.78 Use explicit expectations and bounded attempts for readiness checks.79- Use supported noninteractive registered handlers. Interactive prompts, terminal80 handoff, process replacement (`exec`, `exit`), background/async work, recording81 or emulator sessions, and `wait`/`wait-all`/`cancel` steps cannot run inside a test.82 Start services and prepare fixtures outside the group.8384## Output and Results8586Set `output: failures` (the default) or `output: all` on the test group. These are87scalar test-specific choices, not `raw`, `none`, `log`, or `viewport`. Both buffer88per leaf; `all` also reveals successful logs at completion. Do not redirect leaf89output to `/dev/null`: it removes the evidence needed when a test fails.9091The terminal report uses a hierarchical tree and progress bar. CI/non-TTY output92is static. Counts cover expanded leaves once, excluding group nodes; retries do93not add cases. The summary includes passed, failed, skipped, canceled, and elapsed94time. Group result metadata exposes `total`, `passed`, `failed`, `skipped`, and95`canceled`.9697Use scoped environment variables and step result values rather than shared files98or process-global state to pass data. Matrix cases must not overwrite the same99fixture paths. Keep secrets in existing Atmos auth/secret mechanisms; masking100still applies to captured output, but do not deliberately print credentials.101102Place optional success messages after the test group with `when: success` and103content such as `Tests passed`. Message-only steps inside the group would count104as cases without validating anything.105106## Canonical References107108Consult the project docs for exact fields before extending a pattern:109110- `website/docs/workflows/workflows/workflow/steps/type/test.mdx`111- The neighboring `http.mdx`, `script.mdx`, `shell.mdx`, `require.mdx`,112 `atmos.mdx`, `container.mdx`, `parallel.mdx`, and `matrix.mdx` files.113- `website/docs/workflows/workflows/workflow/steps/continue.mdx` and `retry.mdx`.114- `examples/tests/atmos.yaml` for runnable local examples.115116If behavior is unclear, inspect `pkg/schema/test_step.go` and the registered117handlers under `pkg/runner/step/` rather than inventing test-only assertion fields.