This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Structure
assay has no suites and no fixture registry. You get two building blocks —
subtest and cases — and :wrap for setup and teardown.
subtest
subtest is Go's t.Run: a named child with its own result, its own
assertions and its own abort boundary.
(subtest name body...) ; NAME is evaluated; a string, symbol or number
An unhandled error or a must failure inside a subtest ends the subtest only;
the test continues after it. A failing or erroring child makes the parent fail;
a skipped child does not. Subtests nest, and their names join with › in the
report.
(deftest roundtrip
(dolist (s '("0" "1" "-7" "1000000"))
(subtest s
(is (string= s (unparse (parse s)))))))
A failure in one iteration is reported under roundtrip › -7 and the loop
keeps going.
cases
cases is the table-driven idiom on top of subtest: one subtest per row.
(cases (var...) rows body...) ; ROWS evaluates to a list of lists
vars is a lambda list used with destructuring-bind on each row, so a row may
be shorter than the list with &optional. Each subtest is named from the
variables and their values, var=value pairs separated by one space, the
values printed with prin1.
(deftest arithmetic
(cases (expr expected)
'(("1+1" 2)
("2*3" 6)
("7/2" 7/2))
(is (= expected (eval-string expr)))))
The failing row above is reported as:
✗ parser/test/arithmetic › expr="7/2" expected=7/2
(is (= expected (eval-string expr)))
expected ⇒ 7/2
(eval-string expr) ⇒ 3
differ by 1/2
Fixtures
There is no fixture mechanism because there does not need to be one: a with-
macro plus unwind-protect is a fixture, and deftest's :wrap applies
one to a whole body.
(defmacro with-temp-dir ((var) &body body)
`(let ((,var (make-temp-dir)))
(unwind-protect (progn ,@body)
(delete-directory ,var))))
(deftest (writes-a-file :wrap ((with-temp-dir (dir))))
(write-report (merge-pathnames "r.txt" dir))
(is (probe-file (merge-pathnames "r.txt" dir))))
For per-assertion setup inside a body, just use let and with- directly.
There are no @BeforeAll-style hooks, and no ordering guarantees between tests
beyond definition order in a serial run.
Next: Running.