Thomas Sojka

Setup tests with Cider & deps.edn in 5 steps

The Gist

1. Setup project structure

File structure

.
├── deps.edn
└── src
    └── your_group
        └── your_project
            └── core.clj

deps.edn file

{:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
 :paths ["src" "resources"]}

2. Write test

File structure

.
├── deps.edn
├── src
│   └── your_group
│       └── your_project
│           └── core.clj
└── test
    └── your_group
        └── your_project
            └── core_test.clj

Test file

(ns your-group.your-project.core-test
  (:require [clojure.test :refer [deftest is]]))

(deftest core-test
  (is (= 2 (+ 1 1))))

3. Add :test alias to deps.edn

deps.end file

{:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
 :paths ["src" "resources"]
 :aliases {:test {:extra-paths ["test"]}}} ;; <- test alias

4. Add dir local variable for jack-in

File structure

.
├── deps.edn
├── .dir-locals.el <-- added
└── src/..

.dir-locals.el file

((clojure-mode . ((cider-clojure-cli-global-options . "-M:test"))))

5. Run tests

C-c C-t l or M-x cider-test-run-loaded-tests

Setup tests with Cider & deps.edn in 5 steps

Based on Clojure development with Spacemacs & Cider, How to setup deps.edn project with cider and some further resources, this is my summary to setup your tests.

1. Setup project structure

One thing I like about deps.edn is that creating a new project does not need a bootstrapping command, you just create a deps.edn file and your source files.

Hint: To avoid learning the deps.edn file structure by heart, you can use a snippet. After the creation of the deps.edn file run M-x cider-jack-in-clj and then M-x cljr-add-project-dependency to add any dependencies.

File structure

.
├── deps.edn
└── src
    └── your_group
        └── your_project
            └── core.clj

deps.edn file

{:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
 :paths ["src" "resources"]}

2. Write tests

To add a new test, create your test folders and test file according to this structure:

File structure

.
├── deps.edn
├── src
│   └── your_group
│       └── your_project
│           └── core.clj
└── test
    └── your_group
        └── your_project
            └── core_test.clj

This follows the advice from The Clojure Style Guide - Testing to have a separate test directory.

Test file

(ns your-group.your-project.core-test
  (:require [clojure.test :refer [deftest is]]))

(deftest core-test
  (is (= 2 (+ 1 1))))

clojure.test is part of Clojure, you do not need any additional dependency.

3. Add :test alias to deps.edn

deps.edn file

{:deps {org.clojure/clojure {:mvn/version "1.10.1"}}
 :paths ["src" "resources"]
 :aliases {:test {:extra-paths ["test"]}}} ;; <- test alias

This adds an alias to your project. An alias is a shortcut to adjust your deps.edn file. In this example we add extra-paths to our classpath. Since we add extra-paths for our tests we can exclude them from deployments. There is nothing special about the added path test, it is just a folder we want to be able to condtionally add or remove from our classpath.

4. Add dir local variable for jack-in

During development we want to make sure that our tests are available so we want to use our alias to include the test directory. When using Cider you typically run a project with cider-jack-in. It is possible to add a default alias for all calls to cider-jack-in by setting cider-clojure-cli-global-options. You probably want to have different settings per project and you can use Directory Local Variables to achieve that. You create a Directory Local Variable by creating a .dir-locals.el file in your project root.

File structure

.
├── deps.edn
├── .dir-locals.el <-- added
└── src/..

This file will set the cider-clojure-cli-global-options variable whenever clojure-mode is active:

.dir-locals.el file

((clojure-mode . ((cider-clojure-cli-global-options . "-M:test"))))

Hint: A Directory Local Variable is only read when you revoke your buffer, so make sure to revoke your buffer manually with M-x revert-buffer if it was already open when you created .dir-locals.el. Otherwise the variable will not be read.

5. Run tests

In the documententation of Cider you can find several fine-grained commands to control which test case should run. To run all loaded tests in your project you can run M-x cider-test-run-loaded-tests or use the shortcut C-c C-t l.

Conclusion

Setting up tests with Cider & deps.edn involves quite many steps due to the flexibility this setup offers. I hope with this blog post, you can configure your first tests faster than I did. You can find the source of this minimal example on github.