on master help sign in
Merge pull request #1550 from urbit/add-unit-test-guide

add unit test guide

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