@@ -0,0 +1,94 @@
1++++
2+title = "Unit tests"
3+weight = 10
4+template = "doc.html"
5++++
6+
7+The `%base` desk includes a `-test` thread which can run unit tests you've
8+written. A test is a Hoon file which produces a `core`. The `-test` thread will
9+look for any arms in the core whose name begin with `test-`, e.g:
10+
11+```hoon
12+|%
13+++ test-foo
14+ ...
15+++ test-bar
16+ ...
17+++ test-foo-bar
18+ ...
19+--
20+```
21+
22+Any arms that don't begin with `test-` will be ignored. Each `test-` arm must
23+produce a `tang` (a `(list tank)`). If the `tang` is empty (`~`), it indicates
24+success. If the `tang` is non-empty, it indicates failure, and the contents of
25+the `tang` is the error message.
26+
27+To make test-writing easier, the `%base` desk includes the `/lib/test.hoon`
28+library which you can import into your test file. The library contains four
29+functions which all produce `tang`s:
30+
31+- `expect-eq` - test whether an expression produces the expected value. This
32+ function takes `[expected=vase actual=vase]`, comparing `.expected` to
33+ `.actual`.
34+- `expect` - test whether an expression produces `%.y`. This function takes a
35+ `vase` containing the result to check.
36+- `expect-fail` - tests whether the given `trap` crashes, failing if it succeeds.
37+- `category` - this is a utility that prepends an error message to a failed test
38+ (non-null `tang`), passing through an empty `tang` (successful test)
39+ unchanged.
40+
41+The most commonly used function is `expect-eq`, which is used like:
42+
43+```hoon
44+++ test-foo
45+ %+ expect-eq
46+ !> 'the result I expect'
47+ !> (function-i-want-to-test 'some argument')
48+```
49+
50+Of course, you'll want to test something else you've written rather than just
51+expressions in the test file itself. To do that, you'd just import the file with
52+`/=` or a similar Ford rune, and then call its functions in the test arms.
53+You're free to do any compositions, import types, etc, as long as the file
54+ultimately produces a `core` with `test-*` arms.
55+
56+The `-test` thread takes a `(list path)` in the Dojo, where each path is a path
57+to a test file. The `path` must include the full path prefix
58+(`/[ship]/[desk]/[case]`). The conventional location for tests is a `/tests`
59+directory in the root of a desk.
60+
61+The output of the `-test` thread will note which arms were tested and whether
62+they succeeded. It will also include:
63+
64+- The number of micro-seconds it took to execute each test arm.
65+- A `?` specifying whether all tests succeeded.
66+- A message confirming the file was built successfully.
67+
68+Here's an example of running the tests for the `naive.hoon` library:
69+
70+```
71+> -test ~[%/tests/lib/naive/hoon]
72+built /tests/lib/naive/hoon
73+> test-zod-spawn-to-zero: took 81359µs
74+OK /lib/naive/test-zod-spawn-to-zero
75+> test-zod-spawn-proxy: took 128125µs
76+OK /lib/naive/test-zod-spawn-proxy
77+.............................
78+....truncated for brevity....
79+.............................
80+> test-approval-for-all: took 647403µs
81+OK /lib/naive/test-approval-for-all
82+> test-address-padding: took 75104µs
83+OK /lib/naive/test-address-padding
84+ok=%.y
85+```
86+
87+A good reference example is the test file for the `/lib/number-to-words.hoon`
88+library, located in `/tests/lib/number-to-words.hoon`. Note that the `/tests`
89+directory is not typically included in standard pills. If you want to have a
90+look at existing tests as a reference, you may need to clone the `urbit/urbit`
91+repo on [Github](https://github.com/urbit/urbit).
92+
93+If you write tests for some of your code, you may wish to exclude the `/tests`
94+directory from the production version of your desk.