151 lines
3.4 KiB
Markdown
151 lines
3.4 KiB
Markdown
# shout
|
|
|
|
`shout` is kinda like really basic integration testing for your cli.
|
|
|
|
Write `.shout` files that look like shell sessions and run `shout` to test 'em.
|
|
|
|
## Install
|
|
|
|
```
|
|
bun install -g @because/shout
|
|
```
|
|
|
|
## Features
|
|
|
|
Everything you could ever ask for:
|
|
|
|
```
|
|
$ echo hello
|
|
hello
|
|
|
|
$ brew --version
|
|
Homebrew 5...
|
|
|
|
$ ls missing
|
|
ls: missing: No such file or directory
|
|
[1]
|
|
```
|
|
|
|
`...` matches anything — a whole line inline, or any number of lines on its own.
|
|
|
|
`[1]` after the expected output matches the exit code.
|
|
|
|
`$#` is a comment line — not executed, no output expected:
|
|
|
|
```
|
|
$# start the server
|
|
$ my-server &
|
|
$# now test it
|
|
$ curl localhost:8080
|
|
OK
|
|
```
|
|
|
|
## Usage
|
|
|
|
```
|
|
$ shout test
|
|
...............
|
|
15 passed in 23ms
|
|
```
|
|
|
|
`shout test` runs code in a temp directory. `-k`/`--keep` keeps it around.
|
|
|
|
`--update` will modify `.shout` files to match reality, without running any tests.
|
|
|
|
Each line in a `.shout` file is run sequentially, unless `--parallel` is passed.
|
|
|
|
## Directives
|
|
|
|
Directives go at the top of a `.shout` file, before any commands.
|
|
|
|
### `@env`
|
|
|
|
Set environment variables for the test:
|
|
|
|
```
|
|
@env GREETING=hello
|
|
@env TARGET=world
|
|
|
|
$ echo "$GREETING $TARGET"
|
|
hello world
|
|
```
|
|
|
|
### `@setup`
|
|
|
|
Prepend commands (and `@env` directives) from another `.shout` file:
|
|
|
|
```
|
|
@setup setup-shared.shout
|
|
```
|
|
|
|
Setup commands run first and their failures abort the test. Setup files cannot themselves contain `@setup` — no nesting. If both the setup file and the user file define the same `@env`, the user file wins.
|
|
|
|
### `@teardown`
|
|
|
|
Run a cleanup command after all test commands, regardless of pass/fail:
|
|
|
|
```
|
|
@teardown rm -f "$SHOUT_PROJECT_DIR/data/test.db"
|
|
|
|
$ create-db && run-tests
|
|
...
|
|
```
|
|
|
|
Teardown failures produce warnings but don't affect test results. You can also put `@teardown` in setup files:
|
|
|
|
```
|
|
# setup.shout
|
|
export DB_URL=sqlite:data/test.db
|
|
@teardown rm -f "$SHOUT_PROJECT_DIR/data/test.db"
|
|
```
|
|
|
|
```
|
|
Usage: shout test [options] [files...]
|
|
|
|
Run .shout test files
|
|
|
|
Arguments:
|
|
files Files or directories to test
|
|
|
|
Options:
|
|
-u, --update Rewrite expected output in-place with actual output
|
|
-k, --keep Keep temp directories after run
|
|
--clean-env Start with empty environment
|
|
--path <path> Prepend <path> to PATH (repeatable)
|
|
--timeout <dur> Per-command timeout (default: "10s")
|
|
-v, --verbose Print each command as it runs
|
|
--port-from <n> Auto-assign $PORT starting from n (default: "5400")
|
|
--parallel Run files in parallel
|
|
-h, --help display help for command
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
### Set automatically
|
|
|
|
| Variable | Value |
|
|
|---|---|
|
|
| `HOME` | Path to the temp directory created for the test |
|
|
| `SHOUT_DIR` | Same as `HOME` — the temp directory for the test |
|
|
| `SHOUT_SOURCE_DIR` | Directory containing the `.shout` file being run |
|
|
| `SHOUT_PROJECT_DIR` | The `cwd` where `shout` was invoked |
|
|
| `PORT` | Auto-assigned starting from `5400` (or the value of `--port-from`), increments per file. Not set if `PORT` is already defined via `@env` or `@setup`. |
|
|
|
|
### Inherited
|
|
|
|
By default, the test shell inherits all environment variables from the parent process. Use `--clean-env` to start with an empty environment instead.
|
|
|
|
### Modified
|
|
|
|
`PATH` is prepended with any directories passed via `--path <path>`.
|
|
|
|
### User-defined
|
|
|
|
Use `@env KEY=VALUE` directives to set arbitrary variables. See [Directives](#directives).
|
|
|
|
Print an example `.shout` file:
|
|
|
|
```
|
|
$ shout example
|
|
```
|