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:
- conciseness – spend less time reading and writing test boilerplate
- flexibility:
- switch order of examples to improve readability
- check return against a predicate or equality relative to other data types
- focus on specific tests while developing
- examples as data - for trivial tool support, examples are just data!
- function like test definitions - akin to
clojure.spec/fdef
, but for tests - compatibility with clojure.test - along with its excelent tooling support
eg targets both Clojure and ClojureScript JVM. Untested for ClojureScript JS.
Disclaimer: eg is work-in-progress. Use it at your own risk!
Leiningen/Boot
[eg "0.2.4-alpha"]
Clojure CLI/deps.edn
eg {:mvn/version "0.2.4-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})
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:
- The tests report counts towards non focused tests, although assertions under such tests are not executed.
- Assertions for tests defined directly with
clojure.test/deftest
will be executed, despite the presence of focusedeg
, orge
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)
- Fix test name to support qualified symbols
- Document being able to skip a test with vanilla clojure
- Suffix test name with '-slow' when using ':slow' selector
- Mention:
- leiningen
test-selectors
for use of metadata - https://github.com/weavejester/eftest
- leiningen
- Support expression testing
- Spec API macros
eg
andge
- Test against ClojureScript JS
- Create API to access example data for i.e. tool use
- Document dev flow using clipboard
- Create focus of test partial example using don't care generator(s) for the rest
- Reduce clojure and clojurescript requirements
- Provide workaround to remove warning of eg being a single segment ns
Run 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
- humane-test-output - Humane test output for clojure.test
Copyright (c) 2019 Carlos da Cunha Fontes
The Universal Permissive License (UPL), Version 1.0