On this page
clojure.test Testing Framework
Overview
Qualified supports clojure.test, the built-in testing framework for Clojure 1.6.0
The following notes are largely derived from: clojure.test - Clojure API Documentation.
Basic Example
Solution
(ns challenge)
(defn add [a b]
(+ a b))
Tests
(ns challenge-test
(:require [clojure.test :refer :all]
[challenge :refer [add]]))
(deftest Add
(is (= (add 1 2) 3)))
is
The core of the clojure.test
library is the is
macro, which lets you make
assertions of any arbitrary expression:
(is (= 4 (+ 2 2)))
(is (instance? Integer 256))
(is (.startsWith "abcde" "ab"))
These are all passing tests. They are all expected to output:
Test Passed
The following test won't pass, however:
(deftest Will-Fail
(is (= 5 (+ 2 2))))
It will output:
Will-Fail
expected: (= 5 (+ 2 2)) - actual: (not (= 5 4))
The expected:
line shows you the original expression, and the
actual:
shows you what actually happened. In this case, it
shows that (+ 2 2)
returned 4
, which is not =
to 5
.
There are two special assertions for testing exceptions. The
(is (thrown? c ...))
form tests if an exception of class c
is
thrown:
(is (thrown? ArithmeticException (/ 1 0)))
(is (thrown-with-msg? c re ...))
does the same thing and also
tests that the message on the exception matches the regular
expression re
:
(is (thrown-with-msg? ArithmeticException #"Divide by zero"
(/ 1 0)))
Documenting Tests
is
takes an optional second argument, a string describing the
assertion. This message will be included in the error report.
(is (= 5 (+ 2 2)) "Crazy arithmetic")
In addition, you can document groups of assertions with the "testing" macro, which takes a string followed by any number of assertions. The string will be included in failure reports. Calls to "testing" may be nested, and all of the strings will be joined together with spaces in the final report, in a style similar to RSpec.
(testing "Arithmetic"
(testing "with positive integers"
(is (= 4 (+ 2 2)))
(is (= 7 (+ 3 4))))
(testing "with negative integers"
(is (= -4 (+ -2 -2)))
(is (= -1 (+ 3 -4)))))
Note that, unlike RSpec, the testing
macro may only be used
INSIDE a deftest
.
are
Usage: (are argv expr & args)
Checks multiple assertions with a template expression.
See clojure.template/do-template for an explanation of templates.
Example:
(are [x y] (= x y)
2 (+ 1 1)
4 (* 2 2))
Expands to:
(do (is (= 2 (+ 1 1)))
(is (= 4 (* 2 2))))
Note: This breaks some reporting features, such as line numbers.
with-redefs
One of the most powerful tools of testing in clojure is the with-redefs
macro, which allows you to mock functions.
This is especially useful when you want to prevent access to built-ins for some exercise. For example, the following disables clojure.core/reverse
:
(with-redefs
[clojure.core/reverse
(fn [& _]
(throw (Exception. "Sorry! The reverse built-in is disabled for this challenge!")))]
(deftest Reversing
(is (= (reverse [1]) [1]))))
We should expect this test to fail, since it is clearly is using clojure.core/reverse