← Driving your service: HTTP, gRPC, a browser and a shell

Driving your service from a shell

clientsshellcli
A scenario tells a client what to do; the client uses the service the way a person or another system would, and the scenario checks what came back.tomato runreads the scenario, drives the client, checks the answerthe scenarioWhensends "POST" to …Thenresponse status is …features/*.feature"todos-client"http-client resourcedoesPOST /api/todos{"title": "Buy milk"}gets back201{"id": 1, "title": "Buy milk"}todosyour serviceHTTP API :3000gRPC API :50051web page /CLI todo add …

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

ToStep
set upenv "API_KEY" is "…", workdir is "./fixtures"
runruns "cmd", runs: (a multi-line script), runs script "scripts/seed.sh", runs with timeout "60s":
check the exitsucceeds, fails, exit code is "2"
check outputstdout contains "…", stdout is:, stdout is empty, stderr contains "…"
check filesfile "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.env and env steps.
  • Use it for anything with a command: your CLI, a migration tool, a backup script, curl against 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.