For testing babashka scripts, you can write your own test runner from scratch, which is easy enough:
(ns my-test.runner
(:require
[clojure.test :as t]))
(def test-namespaces '[my-test])
(defn -main [& _]
(doseq [test-ns test-namespaces] (require test-ns))
(let [{:keys [fail error]}
(apply t/run-tests test-namespaces)]
(when (and fail error (pos? (+ fail error)))
(System/exit 1))))
and then run it with bb -m my-test.runner
.
Not too bad, but still, it's work and boilerplate and even more so when you want to make a runner with CLI argument parsing to support running a subset of your tests. Since a year or so, you can use the cognitect-labs/test-runner with babashka. But this required a fork of tools
namespace to be on your babashka classpath (using :deps
in your bb.edn
file).
No more! Since babashka version 1.0.166 you can use org.clojure/tools-namespace unmodified. The fix for this was to add the clojure.tools.reader
namespace with the read
function in babashka as a built-in. Babashka doesn't support the whole clojure.tools.reader
namespace yet, but this is a good start to make it compatible with tools.namespace and now also the cognitect test runner.
To use it with babashka, add the following to your bb.edn
.
{:tasks
{test:bb {:extra-paths ["test"]
:extra-deps {io.github.cognitect-labs/test-runner
{:git/tag "v0.5.1" :git/sha "dfb30dd"}}
:task (exec 'cognitect.test-runner.api/test)
:exec-args {:dirs ["test"]}
:org.babashka/cli {:coerce {:nses [:symbol]
:vars [:symbol]}}}}}
The exec
function call, :exec-args
and :org.babashka/cli
coercion is there so we can call a Clojure function from the command line. See Babashka tasks meets
babashka
CLI for more details.
Now create a test file in test/my_test.clj
:
(ns my-test
(:require [clojure.test :refer [deftest is testing]]))
(deftest my-first-test
(testing "equality works"
(is (= 1 1))))
(deftest my-second-test
(testing "equality still works"
(is (= 2 2))))
And run the tests:
$ bb test:bb
Running tests in #{"test"}
Testing my-test
Ran 2 tests containing 2 assertions.
0 failures, 0 errors.
To run a single test you can specify the name of a var:
$ bb test:bb --vars my-test/my-second-test
Running tests in #{"test"}
Testing my-test
Ran 1 tests containing 1 assertions.
0 failures, 0 errors.
$ bb test:bb --vars my-test/my-first-test my-test/my-second-test
Running tests in #{"test"}
Testing my-test
Ran 2 tests containing 2 assertions.
0 failures, 0 errors.
Perhaps this will come in handy for Advent of Code 2022!
Published: 2022-11-24