tush, a program-testing tool. Yes, the day after I sang the praises of 18th-century gay hobbit porn, this package rejoices in commands like
tush-bless, but honestly, it's a coincidence. I didn't want 2007 to go by without a single software release outside of work, and this one had the least left to fix. (The documentation is still in need of a wit transplant it's not going to get.)
Literate testing mixes executable tests into natural-language documents. The UpDoc page explains why:
- Nonexecutable documentation tends to start out inaccurate and grow worse.
- Conversely, unless tests stay intimate with documentation, they degenerate: "To keep the tests running as the software is changed, the purpose of the test is often lost, and the test is gradually changed into one that always passes."
- Software can support experimental reading. In Emacs you can change tush examples and gauge the effect at the press of a key.
- This extends to interactive or adversarial writing to produce the document in the first place.
To use it:
Tush looks for transcript-like lines in a file and checks them. For example:
$ echo Hello world | Hello world
If you run
READMEis this file), it notices the above two lines, executes
echo Hello world, and checks that 'Hello world' comes out on the standard output. Assuming the test passes, running
tush-checksucceeds silently. A failing test makes
tush-checkfail and output a diff.
You aren't limited to invoking the program under test; setup, clean-up, checking, etc., work the same way:
$ echo >test.in 'here is some test input' $ echo >>test.in 'and here is some more' $ sort test.in | wc -l # Check: sorting should not change the linecount. | 2
We didn't bother to
rm test.inafterwards because we have a crude kind of test isolation already: Tush makes a new temporary directory named
tush-scratch, runs all the commands in the input from within it, then deletes it.
What about checking commands that should fail? There are two more special prefixes. For example:
$ cat nonesuch @ cat: nonesuch: No such file or directory ? 1
The '@ ' line is like '| ', only for standard error instead of standard output. The '? ' line shows a nonzero exit status.
tush-checkwas introduced above. It calls
tush-run, which runs
tush-run-rawfrom within a temporary
tush-run-rawcopies its input except for the special-prefixed lines introduced above: '$ ' lines are copied, too, but also executed, with their outputs/status codes inserted into the output with appropriate prefixes, so that for a successful test the output is the same as the input. Input lines starting with '| ', '@ ', or '? ' are dropped.
The above tools, like
cat, take any number of files as arguments.
tush-check foowill then pass: it changes any output/status-code lines to the actual outputs from
tush-run. Use this when your program is correct but your test is wrong.
See the *.tush files in this directory. They're a kind of self-check of the Tush implementation, though a weak one, since implementing
catwould pass it. [XXX do something about that?]
tush.ellets you pass the file you're editing through tush-run with a single keystroke. This can go nicely with interactive development combining unit tests with the code under test.
*wonders if anyone will flag this for adult content*