eg delivers clojure.test
function tests with conciseness.
(deftest inc-test
(is (= 1 (inc 0))))
in eg becomes:
(eg inc [0] 1)
Core ideas driving eg:
clojure.spec/fdef
, but for testsDisclaimer: eg is work-in-progress. Use it at your own risk!
Leiningen/Boot
[eg "0.3.0-alpha"]
Clojure CLI/deps.edn
eg {:mvn/version "0.3.0-alpha"}
eg
stands for e.g. (short for example), and ge
is just eg
reversed. Reversed example: (ge inc 1 [0])
.
Let's try eg! Start by creating a REPL session and then requiring eg
and ge
:
(require '[eg :refer [eg ge]])
Each eg test tests one function using examples. You could think of it as a function's test definition:
(eg not ; testing clojure.core/not
[false] ; with input parameters vector `[false]`
true) ; returning expected value `true`
a clojure.test
test named not-test
was generated.
There are times when we prefer to have expected values
on the left, and input parameters on the right.
For that we use ge
, a useful mnemonic for the inverted flow of the test example:
(ge + 10 [3 7]) ; one liners are also ok, as with `defn`
Each eg test can contain an arbitrary number of examples:
(eg *
[3] 3
[3 2] 6)
Predicates can also be used in place of an expected value:
(eg dec [4] integer?)
=>
or <=
delimiters between input parameters and expected value can be used to improve readability, or
override the default order of eg
or ge
.
(eg hash-map
[:d 1] {:d 1}
[:a 1 :b 2 :c 3 :d 4] => {:a 1 :b 2 :c 3 :d 4}
map? <= {:a 1 :b 2 :c 3 :d 4})
ex
makes it possible to test the result of calling an arbitrary form expression. Typical scenarios include testing the result of calling a macro (eg
, and ge
only support function testing), or decomposing the assertion of different properties or values from calling a form:
(let [test-eg-ret (ex (inc 0) 1)
f-len (count "eg-test-")]
; arrows are compulsory
(ex var? <= test-eg-ret
(-> test-eg-ret meta :test) => boolean
(-> test-eg-ret meta :test) => fn?
(-> test-eg-ret meta :name name (subs f-len)) => not-empty))
;=> eg-test-<rand-id>
(ex (true? false) => false) ;=> eg-test-<rand-id>
There are times when we just want to test a certain input parameter value, but fill the
remainder input parameters nevertheless. eg provides a don't care placeholder – _
,
for these cases:
(eg vector
[1 2 3 4] [1 2 3 4]
[5 6 _ 8] vector?
[4 _ 5] vector?)
We can map *don't care* inputs to matching parts of the expected result, by using *bound don't cares*:
```clj
(eg assoc-in
[{} [:a :b] {:eggs "boiled"}] => {:a {:b {:eggs "boiled"}}}
[_ _ $1] => {:a {:b $1}})
When writing the assertion, don't cares enable us to spend less time doing fillers, and the reader is able to better understand the focus of the assertion.
It's possible to run only selected tests by using metadata ^:focus
on eg
or ge
:
(eg ^:focus false? [false] true)
There are some caveats to consider when using ^:focus
with ClojureScript:
clojure.test/deftest
will be executed, despite the presence of focused eg
, or ge
tests.Between eg
, and ge
, choose the form that is most convenient for your combination of function examples and use it only once for testing a function. For example, don't do this:
(ge inc [1] 2)
(ge inc [0] 1)
or this:
(eg inc [1] 2)
(ge inc [0] 1)
Finally, run your tests as you normally would with clojure.test
.
Clojure tests in the REPL:
(clojure.test/run-all-tests)
; or
(clojure.test/run-tests some.ns)
Clojure tests in the terminal:
> lein test
ClojureScript tests in the REPL:
(cljs.test/run-all-tests)
; or
(cljs.test/run-tests some.ns)
test-selectors
for use of metadataeg
, ge
, and ex
^:focus
caveats in ClojureScriptRun tests expected to pass, targeting Clojure:
> lein clj-test-pass
Run tests expected to pass, targeting ClojureScript JVM->nodejs:
> lein cljs-test-pass
Run tests expected to fail, targeting Clojure:
> lein clj-test-fail
Run tests expected to fail, targeting ClojureScript JVM->nodejs:
> lein cljs-test-fail
Copyright (c) 2019 Carlos da Cunha Fontes
The Universal Permissive License (UPL), Version 1.0
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close