Clojure自带的测试框架
原文地址
Clojure自带了一个测试框架,它位于 clojure.test
命名空间内。让我们从定义两个将要在REPL中被测试的简单函数开始吧。
user=> (defn add [x y] (+ x y))
user=> (defn subtract [x y] (- x y))
宏deftest
用于定义将要被执行的测试。deftest
可以被用于定义一个或一组测试:
user=> (use 'clojure.test)
user=> (deftest test-add (is (= 4 (add 2 2))))
user=> (deftest test-subtract (is (= 0 (subtract 2 2))))
user=> (deftest math
(is (= 4 (add 2 2)))
(is (= 0 (subtract 2 2))))
在REPL中运行测试:
user=> (run-tests)
Testing user
Ran 3 tests containing 4 assertions.
0 failures, 0 errors.
{:type :summary, :pass 4, :test 3, :error 0, :fail 0}
正如期望的,那里没有测试失败。为了强制失败发生,让我们重定义test-add
并且再次运行它。
user=> (deftest test-add (test/is (= 3 (add 2 2))))
user=> (run-tests)
Testing user
FAIL in (test-add) (NO_SOURCE_FILE:23)
expected: (= 3 (add 2 2))
actual: (not (= 3 4))
Ran 3 tests containing 4 assertions.
1 failures, 0 errors.
{:type :summary, :pass 3, :test 3, :error 0, :fail 1}
你还可以使用宏with-test
在函数中定义测试:(译者不解:什么情况下需要?)
user=> (with-test
(defn add [x y] (+ x y))
(is (= 4 (add 2 2))))
为了测试私有函数,你需要直接引用函数的var:
user=> (defn- multiply [x y] (* x y)) ;; private function
user=> (deftest test-multiply (is (= 9 (#'user/multiply 3 3))))
;;or
(deftest test-multiply (is (= 9 ((var user/multiply) 3 3))))
在测试中,你也许需要搭建测试运行的环境,clojure.test
中的use-fixtures
提供了那个函数:
(use-fixtures :each fixture1 fixture2 ...) ;;
(use-fixtures :once fixture1 fixture2 ...)
这里的fixture1,fixture2只是函数
???(没有搞明白)
缺省情况,测试的输出将被写入终端,你可以通过用clojure.java.io/writer
重绑定 *test-out*来将输出保存到文件中:
user=> (with-redefs [*test-out* (clojure.java.io/writer "test.out")] (run-tests))
user=> (run-tests) ;; test output will be written to test.out file
上面的例子运行在REPL中,接下来的例子展示了如何使用leiningen对源代码进行测试:
创建新工程 ·example·
$ lein new examples
添加如下代码到对应的文件中: src/core.clj
(ns examples.core)
(defn add [x y] (+ x y))
(defn subtract [x y] (- x y))
(defn- multiply [x y] (* x y)) ;; private function
test/core_test.clj
(ns examples.core-test
(:use clojure.test)
(:use examples.core))
(deftest test-add (is (= 4 (add 2 2))))
(deftest test-subtract (is (= 0 (subtract 2 2))))
(deftest test-multiply (is (= 9 (#'examples.core/multiply 3 3))))
(deftest math
(is (= 4 (add 2 2)))
(is (= 0 (subtract 2 2)))
(is (= 9 (#'examples.core/multiply 3 3))))
使用Leiningen的 test
任务去运行测试:
$ lein test
Testing examples.core-test
Ran 4 tests containing 6 assertions.
0 failures, 0 errors.