## 自動化測試
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` "。