Driving your service from a shell
Start. tomato starts your service and its dependencies. The client only needs to know where the service is: an address, or nothing at all for the shell.
Act. A When step tells the client what to do, and it does it the way another service would: it sends a request.
Answer. The service answers through the same door: a status, headers and a body.
Assert. Then steps check that answer. Check the effects too, through the other resources: the row in the database, the message on Kafka.
Reset. Before the next scenario the client forgets its headers and cookies, so no scenario leans on another's.
The suite
The service here ships a small command-line tool, cli.js, that talks to its
API.
resources:
todo-cli:
type: shell
options:
env: { TODOS_API: http://localhost:3000 } # what every command sees
Scenario: A todo added from the command line
When "todo-cli" runs "node cli.js add Buy milk"
Then "todo-cli" succeeds
And "todo-cli" stdout contains "Buy milk"
When "todo-cli" runs "node cli.js list"
Then "todo-cli" stdout contains "Buy milk"
Scenario: A todo without a title is refused
When "todo-cli" runs "node cli.js add"
Then "todo-cli" exit code is "1"
And "todo-cli" stderr contains "title is required"
And "todo-cli" stdout is empty
What it can do
| To | Step |
|---|---|
| set up | env "API_KEY" is "…", workdir is "./fixtures" |
| run | runs "cmd", runs: (a multi-line script), runs script "scripts/seed.sh", runs with timeout "60s": |
| check the exit | succeeds, fails, exit code is "2" |
| check output | stdout contains "…", stdout is:, stdout is empty, stderr contains "…" |
| check files | file "out/report.csv" exists, file "…" contains "…" |
Notes
- It runs on the machine tomato runs on, in tomato’s directory, with
tomato’s environment plus
options.envandenvsteps. - Use it for anything with a command: your CLI, a migration tool, a
backup script,
curlagainst an endpoint no client covers. - Check stderr and the exit code on the failure path. A CLI that prints
an error and exits 0 breaks every script that calls it;
exit code is "1"catches that.