| # cli-test |
| |
| ## What? |
| |
| `cli-test` makes integration testing of command-line tools easier. |
| |
| ## Goals |
| |
| * Readable syntax. Common cases should be concise, and pretty much anyone |
| should be able to read tests even if they've never seen this tool before. |
| |
| * Minimal issues with quoting. The toybox tests -- being shell scripts -- |
| quickly become a nightmare of quoting. Using a non ad hoc format (such as |
| JSON) would have introduced similar but different quoting issues. A custom |
| format, while annoying, side-steps this. |
| |
| * Sensible defaults. We expect your exit status to be 0 unless you say |
| otherwise. We expect nothing on stderr unless you say otherwise. And so on. |
| |
| * Convention over configuration. Related to sensible defaults, we don't let you |
| configure things that aren't absolutely necessary. So you can't keep your test |
| data anywhere except in the `files/` subdirectory of the directory containing |
| your test, for example. |
| |
| ## Non Goals |
| |
| * Portability. Just being able to run on Linux (host and device) is sufficient |
| for our needs. macOS is probably easy enough if we ever need it, but Windows |
| probably doesn't make sense. |
| |
| ## Syntax |
| |
| Any all-whitespace line, or line starting with `#` is ignored. |
| |
| A test looks like this: |
| ``` |
| name: unzip -l |
| command: unzip -l $FILES/example.zip d1/d2/x.txt |
| after: [ ! -f d1/d2/x.txt ] |
| expected-stdout: |
| Archive: $FILES/example.zip |
| Length Date Time Name |
| --------- ---------- ----- ---- |
| 1024 2017-06-04 08:45 d1/d2/x.txt |
| --------- ------- |
| 1024 1 file |
| --- |
| ``` |
| |
| The `name:` line names the test, and is only for human consumption. |
| |
| The `command:` line is the command to be run. Additional commands can be |
| supplied as zero or more `before:` lines (run before `command:`) and zero or |
| more `after:` lines (run after `command:`). These are useful for both |
| setup/teardown but also for testing post conditions (as in the example above). |
| |
| Any `command:`, `before:`, or `after:` line is expected to exit with status 0. |
| Anything else is considered a test failure. |
| |
| The `expected-stdout:` line is followed by zero or more tab-prefixed lines that |
| are otherwise the exact output expected from the command. (There's magic behind |
| the scenes to rewrite the test files directory to `$FILES` because otherwise any |
| path in the output would depend on the temporary directory used to run the test.) |
| |
| There is currently no `expected-stderr:` line. Standard error is implicitly |
| expected to be empty, and any output will cause a test failure. (The support is |
| there, but not wired up because we haven't needed it yet.) |
| |
| The fields can appear in any order, but every test must contain at least a |
| `name:` line and a `command:` line. |
| |
| ## Output |
| |
| The output is intended to resemble gtest. |
| |
| ## Future Directions |
| |
| * It's often useful to be able to *match* against stdout/stderr/a file rather |
| than give exact expected output. We might want to add explicit support for |
| this. In the meantime, it's possible to use an `after:` with `grep -q` if |
| you redirect in your `command:`. |
| |
| * In addition to using a `before:` (which will fail a test), it can be useful |
| to be able to specify tests that would cause us to *skip* a test. An example |
| would be "am I running as root?". |
| |
| * It might be useful to be able to make exit status assertions other than 0? |
| |
| * There's currently no way (other than the `files/` directory) to share repeated |
| setup between tests. |