6.2 Fixtures and Test Suites

In many ways, ERT is similar to frameworks for other languages like SUnit or JUnit. However, two features commonly found in such frameworks are notably absent from ERT: fixtures and test suites.

Fixtures are mainly used (e.g., in SUnit or JUnit) to provide an environment for a set of tests, and consist of set-up and tear-down functions.

While fixtures are a useful syntactic simplification in other languages, this does not apply to Lisp, where higher-order functions and unwind-protect are available. One way to implement and use a fixture in ERT is

(defun my-fixture (body)
  (unwind-protect
      (progn [set up]
             (funcall body))
    [tear down]))

(ert-deftest my-test ()
  (my-fixture
   (lambda ()
     [test code])))

(Another way would be a with-my-fixture macro.) This solves the set-up and tear-down part, and additionally allows any test to use any combination of fixtures, so it is more flexible than what other tools typically allow.

If the test needs access to the environment the fixture sets up, the fixture can be modified to pass arguments to the body.

These are well-known Lisp techniques. Special syntax for them could be added but would provide only a minor simplification.

(If you are interested in such syntax, note that splitting set-up and tear-down into separate functions, like *Unit tools usually do, makes it impossible to establish dynamic let bindings as part of the fixture. So, blindly imitating the way fixtures are implemented in other languages would be counter-productive in Lisp.)

The purpose of test suites is to group related tests together.

The most common use of this is to run just the tests for one particular module. Since symbol prefixes are the usual way of separating module namespaces in Emacs Lisp, test selectors already solve this by allowing regexp matching on test names; e.g., the selector "^ert-" selects ERT’s self-tests.

Other uses include grouping tests by their expected execution time, e.g., to run quick tests during interactive development and slow tests less often. This can be achieved with the :tag argument to ert-deftest and tag test selectors.