Any tricks in writing Clojure(Script) tests?

I use cljs.test running in Node.js mode. I think it would be better for debugging if I use Chrome DevTools.

Current I have a question: how to call a single test from API?

More tricks are welcome :smile:

I usually run all tests via the REPL.

(ns demo.app-test
  (:require [cljs.test :as ct :refer (deftest is)]))

(deftest a-failing-test
  (is (= 1 2)))

(deftest a-passing-test
  (is (= 1 1)))

Any REPL works but since you mentioned node I’ll just use a node REPL as an example here.

shadow-cljs clj-repl
shadow-cljs - config: /Users/zilence/code/shadow-cljs/shadow-cljs.edn version: 2.0.105
shadow-cljs - connected to server
shadow-cljs - REPL - see (help), :repl/quit to exit
[32:0]~shadow.user=> (shadow/node-repl {:node-args ["--inspect"]})
[:node-repl] Configuring build.
[:node-repl] Compiling ...
[:node-repl] Build completed. (39 files, 1 compiled, 0 warnings, 0.27s)
[32:1]~cljs.user=> Debugger listening on ws://127.0.0.1:9229/ea76ffd9-ed78-4dfd-bf97-4ffd4af6f32c
For help see https://nodejs.org/en/docs/inspector
[32:1]~cljs.user=> JS runtime connected.
[32:1]~cljs.user=> (require '[shadow.test :as t])
[32:1]~cljs.user=> (require 'demo.app-test)
[32:1]~cljs.user=> (t/run-all-tests)

Testing demo.app-test

FAIL in (a-failing-test) (cljs-runtime/cljs/test.cljs:473:6)
expected: (= 1 2)
  actual: (not (= 1 2))

Ran 0 tests containing 0 assertions.
0 failures, 0 errors.
nil

You can also use shadow-cljs node-repl directly but there is currently no way to pass in --inspect option to the node process which the (shadow/node-repl {:node-args ["--inspect"]}) call does. Once that process is running you can open about://inspect in chrome and it should list the node process to inspect/debug.

Note that run-all-tests only runs tests from namespaces that have already been loaded so you need to requires test namespaces manually before.

You can run a single test by calling it as a function.

[32:1]~cljs.user=> (demo.app-test/a-failing-test)

FAIL in (a-failing-test) (cljs-runtime/cljs/test.cljs:473:6)
expected: (= 1 2)
  actual: (not (= 1 2))
nil

There are many more ways to run tests, just take a look at cljs.test (or shadow.test which is basically the same just without all the macros).

I also recently added :target :karma which can build a file which can be used with karma and :browser-test to run tests in the browser. Both need work and are very alpha but they do work.

Just an example config for now. With :browser-test open http://localhost:8606 when shadow-cljs watch test-dummy is running. The karma stuff requires a config file. I know basically nothing about karma so someone with more knowledge could probably make all this way simpler.

  :test-dummy
  {:target :browser-test
   :test-dir "out/demo-test-dummy"
   :devtools
   {:http-port 8606
    :http-root "out/demo-test-dummy"}}

  :test-karma
  {:target :karma
   :output-to "out/demo-karma/test.js"}

I didn’t put much work into the testing side of things yet so there is much left to do. Consider it a start … Suggestions welcome.

5 Likes

What does :test-dir do in this configuration?

Just a folder where all files are placed. I’m still figuring this out and basically all the settings should be optional at some point. Expect that everything related to this is going to change in one way or another.

1 Like

@jiyinyiyong

https://github.com/fulcrologic/fulcro-spec/blob/develop/README.adoc seems really interesting.

Tony Kay has a nice talk on testing at clojure west and in the defn podcast they also talk a bit about testing.

Might be worth checking out for inspiration :slight_smile:

1 Like