## 自动化测试
Clojure里面主要的主要自动化测试框架是clojure core里面自带的。下面的代码演示了它的一些主要特性:
```
(use 'clojure.test)
; Tests can be written in separate functions.
(deftest add-test
; The "is" macro takes a predicate, arguments to it,
; and an optional message.
(is (= 4 (+ 2 2)))
(is (= 2 (+ 2 0)) "adding zero doesn't change value"))
(deftest reverse-test
(is (= [3 2 1] (reverse [1 2 3]))))
; Tests can verify that a specific exception is thrown.
(deftest division-test
(is (thrown? ArithmeticException (/ 3.0 0))))
; The with-test macro can be used to add tests
; to the functions they test as metadata.
(with-test
(defn my-add [n1 n2] (+ n1 n2))
(is (= 4 (my-add 2 2)))
(is (= 2 (my-add 2 0)) "adding zero doesn't change value"))
; The "are" macro takes a predicate template and
; multiple sets of arguments to it, but no message.
; Each set of arguments are substituted one at a time
; into the predicate template and evaluated.
(deftest multiplication
(are [n1 n2 result]
(= (* n1 n2) result) ; a template
1 1 1,
1 2 2,
2 3 6))
; Run all the tests in the current namespace.
; This includes tests that were added as function metadata using with-test.
; Other namespaces can be specified as quoted arguments.
(run-tests)
```
为了限制运行一个test的时候抛出来的异常的深度,bind一个数字到special symbol: `*stack-trace-depth*` 。
当你要把Clojure代码编译成bytecode以部署到生成环境的时候, 你可以给 `*load-tests*` symbol bind一个 `false` 值,以避免把测试代码编译进去。
虽然和自动化测试不是同一个层面的东西,还是值得一提的是Clojure提供一个宏: `assert` 。它测试一个表达式, 如果这个表达式的值为false的话,他们它会抛出异常。这可以警告我们这种情况从来都不应该发生。看例子:
```
(assert (>= dow 7000))
```
自动化测试的另外一个重要的特性是fixtures。fixture其实就是JUnit里面的setup和tearDown方法。fixture分为两种,一种是在每个测试方法的开始,结束的时候 执行。一种是在整个测试(好几个测试方法)的开始和结束的时候执行。
照下面的样子编写fixture:
```
(defn fixture-name [test-function]
; Perform setup here.
(test-function)
; Perform teardown here.
)
```
这个fixture函数会在执行每个测试方法的时候执行一次。这里这个 `test-function` 及时要被执行的测试方法。
用下面的方法去注册这些fixtures去包裹每一个测试方法:
```
(use-fixtures :each fixture-1 fixture-2 ...)
```
执行的顺序是:
1. fixture-1 setup
2. fixture-2 setup
3. ONE test function
4. fixture-2 teardown
5. fixture-1 teardown
用下面的方法去注册这些fixtures去包裹整个一次测试:
```
(use-fixtures nce fixture-1 fixture-2 ...)
```
执行顺序是这样的:
1. fixture-1 setup
2. fixture-2 setup
3. ALL test functions
4. fixture-2 teardown
5. fixture-1 teardown
Clojure本身的测试在 `test` 子目录里面. 要想运行他们的话, cd到包含 `src` 和 `test` 的目录下面去,然后执行: " `ant test` "。