English | 日本語
scenario test framework — describe cross-business-date scenario tests with a directory convention and run them automatically from a single binary.
- Single binary: written in Go, with the execution engine built in (no external workflow engine such as digdag, no JVM).
- Convention-based: just drop scripts into the
scenario/{name}/_{seq}_{bizdate}/_{seq}_{group}_{type}/hierarchy. - Ordered, fail-fast: steps run sequentially in filename order; every step after a failure is
recorded as
Blocked. - Visibility: a JSONL execution journal +
stfw status+ a static HTML report. - Observability: run / scenario / bizdate / process / step execution is exported as OTLP traces (view them directly in Jaeger / Grafana Tempo / Datadog, etc.).
- Built-in plugins: compose Arrange → Act → Collect → Assert scenario tests from ready-made parts (RDBMS / Redis / ssh / scp / k6 / file comparison).
- Housekeeping:
stfw runautomatically deletes results older than the retention window (stfw.housekeep.retention_days) at the start of a run.
ℹ️ Internal documentation (
docs/) and in-code comments are written in Japanese.
-
Linux / macOS
curl -fsSL https://raw.githubusercontent.com/scenario-test-framework/stfw/master/install.sh | bash stfw --versioninstall.shauto-detects OS / arch and installs the latest release by default. You can pin a version or change the install directory:curl -fsSL https://raw.githubusercontent.com/scenario-test-framework/stfw/master/install.sh | \ STFW_VERSION=X.Y.Z STFW_BINDIR=$HOME/.local/bin bash
Uninstall:
curl -fsSL https://raw.githubusercontent.com/scenario-test-framework/stfw/master/uninstall.sh | bashPass the same directory if you changed the install location:
curl -fsSL https://raw.githubusercontent.com/scenario-test-framework/stfw/master/uninstall.sh | \ STFW_BINDIR=$HOME/.local/bin bash
-
Windows (PowerShell)
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/scenario-test-framework/stfw/master/install.ps1))) stfw --version
install.ps1auto-detects the architecture, installs the latest release to$HOME\binby default, and adds it to the user PATH. You can pin a version or change the install directory:& ([scriptblock]::Create((irm https://raw.githubusercontent.com/scenario-test-framework/stfw/master/install.ps1))) ` -Version X.Y.Z ` -BinDir "$HOME\bin"
Uninstall:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/scenario-test-framework/stfw/master/uninstall.ps1)))
Pass the same directory if you changed the install location:
& ([scriptblock]::Create((irm https://raw.githubusercontent.com/scenario-test-framework/stfw/master/uninstall.ps1))) ` -BinDir "$HOME\bin"
docker pull ghcr.io/scenario-test-framework/stfw:latest
docker run --rm -v "$PWD":/work ghcr.io/scenario-test-framework/stfw:latest --versionTo use the built-in plugins (RDBMS / Redis / ssh family / invokeWeb), use the all-runtime-bundled
stfw:full image (ships mysql / psql / redis-cli / sshpass / Chromium):
docker pull ghcr.io/scenario-test-framework/stfw:full$ mkdir myproject && cd myproject
$ stfw init # initialize the project (with a sample scenario)
$ stfw run sample # run the scenario
$ stfw status # show the result tree
$ stfw report # regenerate the HTML report (.stfw/reports/)Add a scenario:
$ stfw new scenario release_test # scenario
$ cd scenario/release_test
$ stfw new bizdate 10 20260701 # business date (seq + YYYYMMDD)
$ cd _10_20260701
$ stfw new process 10 web scripts # process (seq + group + type)
$ stfw validate release_test # static validation of the conventioncompose.yaml bundles stfw + nginx + reports-init (a one-shot that initializes volume ownership).
nginx serves the execution reports through a shared volume.
$ docker compose up -d nginx # start report serving
$ docker compose run --rm stfw init # initialize the project
$ docker compose run --rm stfw run sample # run the scenario
$ open http://localhost:8080 # view the report in a browsermyproject/
├── stfw.yml # project settings (overrides the defaults)
├── config/
│ ├── inventory/staging.yml # host group definitions for targets
│ ├── encrypt/ # encryption keys (stfw secret keygen)
│ └── passwd/ # encrypted credentials (stfw secret set)
├── plugins/ # hierarchy hooks / custom process plugins
│ └── {run,scenario,bizdate,process}/_common/{setup,teardown}/
└── scenario/
└── {scenario}/ # scenario
└── _{seq}_{bizdate}/ # business date (run in ascending order)
└── _{seq}_{group}_{type}/ # process (run in ascending order)
└── scripts/ # steps (run sequentially ascending, stop on error)
Process types are extensible through the following contract:
- Input: environment variables (
stfw_*= flattened settings, plus execution context such asSTFW_PROJ_DIR). - Output: a return code (
0= Success /3= Warn /6= Error). - Any implementation language (any executable file works).
Compose Arrange → Act → Collect → Assert scenario tests from ready-made parts. Targets are resolved from inventory groups and passwords from secrets; hard-coding them in configuration is forbidden.
| Phase | Plugin | Description |
|---|---|---|
| any | scripts |
run arbitrary scripts sequentially in ascending order (Go-native) |
| Arrange | importMysql / importPostgres / importRedis |
load data into a datastore from CSV |
| Arrange | clearMysql / clearPostgres / clearRedis |
reset a datastore |
| Arrange | scpPut |
place local files on a remote host atomically (scp + atomic rename) |
| Act | invokeRest / invokeWeb |
API transactions / browser operations via grafana k6 |
| Act | sshExec |
run remote scripts in bulk (ssh) |
| Collect | collectFile / collectLog |
collect evidence from remote hosts (with time filtering) |
| Collect | exportMysql / exportPostgres / exportRedis |
export a datastore to CSV |
| Assert | compare |
directory comparison of expected values vs. evidence (compare-files) |
For a runnable, close-to-real example and an end-to-end walkthrough of how to assemble one:
- examples/daily-balance — a runnable daily-balance batch sample that
spans business dates. It bundles postgres + a toy REST API and runs end-to-end via
./run.sh(Arrange→Act→Collect→Assert composed from built-in plugins only). - docs/GUIDE.md — scenario authoring guide (the 4-phase model, connection info, and the evidence convention, end to end). (Japanese)
See docs/AS-BUILT.md §4 for the detailed contract and settings. (Japanese)
| Command | Description |
|---|---|
stfw init |
initialize a project |
stfw new scenario/bizdate/process |
generate a hierarchy scaffold |
stfw scenario reverse <name> [-o dir] |
generate spec (.yml) + doc (.md) from a scenario (tree → spec + doc; default output dir docs/) |
stfw scenario scaffold <spec.yml> [--sync] |
generate a scenario skeleton from a spec (spec → tree, round-trip entry). --sync diff-syncs an existing scenario (add/keep/delete) |
stfw validate [scenario...] |
static validation of the directory convention and plugin resolution |
stfw run [--dry-run] <scenario...> |
run scenarios automatically in bulk |
stfw status [run_id] |
show the result tree |
stfw report [run_id] [--out dir] |
regenerate the HTML report |
stfw inventory list/exists |
inspect host groups |
stfw secret keygen/set/show/migrate |
encrypted credential management (age) |
stfw ssh trust <host|group> |
register SSH server keys in known_hosts |
stfw plugin list/install |
process plugin management |
$ go build ./...
$ go test ./... # unit + testscript acceptance testsThe requirement/spec extraction assets (USDM / RDRA) live in docs/usdm/ / docs/rdra/ /
docs/harvest/. See CLAUDE.md for the development conventions.
