1 Migrating from Parachute
dxtr edited this page 2026-10-18 12:07:40 +02:00

Migrating from Parachute

A one-screen cheat sheet. Most of the work is mechanical: define-test becomes deftest, and Parachute's many assertion names collapse into is around an ordinary predicate.

Parachute assay
(define-test name ...) (deftest name ...)
(is = a b) (is (= a b))
(is eql a b) (is (eql a b))
(true x) (is x)
(false x) (is (not x))
(of-type type x) (is (typep x 'type))
(fail form) / (fail ...) (fail ...) (unchanged)
(skip ...) (skip ...)
:parent other-test dropped — use Structure's subtest to nest
:fix / fixtures a let, or deftest's :wrap (see Defining Tests)

Notes on the differences

  • One assertion, not many. Because is reads its own form, you write the predicate you already know — (is (= a b)), (is (string= x y)), (is (subsetp a b)) — and get the operands and a one-line explanation on failure. There is no is-values, fail-compile or per-predicate macro to learn. See Assertions and Explain.

  • No test tree. Parachute's :parent builds a tree of tests. assay has a flat registry grouped by package, plus subtest for structure inside a test. To run a group, select its package: (run :my-project/test). See Running.

  • No fixture objects. Parachute's :fix is replaced by a with- macro and deftest's :wrap, which splices the body into your own setup/teardown macro. See Structure.

  • Reporting is a protocol, not a class hierarchy. Where Parachute has report classes, assay signals conditions and you add report methods (or your own handler-bind). See Events and Reporters.

  • Running from CI. The test-op wiring is the same shape; assay's :signal-on-failure t is what fails the build. See Command Line.

Example

Before (Parachute):

(define-test parse
  (is = 42 (parse "42"))
  (true (null (parse "")))
  (of-type parse-error (handler-case (parse "4x2") (parse-error (e) e))))

After (assay):

(deftest parse
  (is (= 42 (parse "42")))
  (is (null (parse "")))
  (signals parse-error (parse "4x2")))

Back to Home.