|
14 | 14 | ;; Thanks to Chas Emerick, Allen Rohner, and Stuart Halloway for |
15 | 15 | ;; contributions and suggestions. |
16 | 16 |
|
17 | | - |
18 | | - |
19 | | -(comment |
20 | | - ;; Inspired by many Common Lisp test frameworks and clojure/test, |
21 | | - ;; this file is a Clojure test framework. |
22 | | - ;; |
23 | | - ;; |
24 | | - ;; |
25 | | - ;; ASSERTIONS |
26 | | - ;; |
27 | | - ;; The core of the library is the "is" macro, which lets you make |
28 | | - ;; assertions of any arbitrary expression: |
29 | | - |
30 | | - (is (= 4 (+ 2 2))) |
31 | | - (is (instance? Integer 256)) |
32 | | - (is (.startsWith "abcde" "ab")) |
33 | | - |
34 | | - ;; You can type an "is" expression directly at the REPL, which will |
35 | | - ;; print a message if it fails. |
36 | | - ;; |
37 | | - ;; user> (is (= 5 (+ 2 2))) |
38 | | - ;; |
39 | | - ;; FAIL in (:1) |
40 | | - ;; expected: (= 5 (+ 2 2)) |
41 | | - ;; actual: (not (= 5 4)) |
42 | | - ;; false |
43 | | - ;; |
44 | | - ;; The "expected:" line shows you the original expression, and the |
45 | | - ;; "actual:" shows you what actually happened. In this case, it |
46 | | - ;; shows that (+ 2 2) returned 4, which is not = to 5. Finally, the |
47 | | - ;; "false" on the last line is the value returned from the |
48 | | - ;; expression. The "is" macro always returns the result of the |
49 | | - ;; inner expression. |
50 | | - ;; |
51 | | - ;; There are two special assertions for testing exceptions. The |
52 | | - ;; "(is (thrown? c ...))" form tests if an exception of class c is |
53 | | - ;; thrown: |
54 | | - |
55 | | - (is (thrown? ArithmeticException (/ 1 0))) |
56 | | - |
57 | | - ;; "(is (thrown-with-msg? c re ...))" does the same thing and also |
58 | | - ;; tests that the message on the exception matches the regular |
59 | | - ;; expression re: |
60 | | - |
61 | | - (is (thrown-with-msg? ArithmeticException #"Divide by zero" |
62 | | - (/ 1 0))) |
63 | | - |
64 | | - ;; |
65 | | - ;; |
66 | | - ;; |
67 | | - ;; DOCUMENTING TESTS |
68 | | - ;; |
69 | | - ;; "is" takes an optional second argument, a string describing the |
70 | | - ;; assertion. This message will be included in the error report. |
71 | | - |
72 | | - (is (= 5 (+ 2 2)) "Crazy arithmetic") |
73 | | - |
74 | | - ;; In addition, you can document groups of assertions with the |
75 | | - ;; "testing" macro, which takes a string followed by any number of |
76 | | - ;; assertions. The string will be included in failure reports. |
77 | | - ;; Calls to "testing" may be nested, and all of the strings will be |
78 | | - ;; joined together with spaces in the final report, in a style |
79 | | - ;; similar to RSpec <http://rspec.info/> |
80 | | - |
81 | | - (testing "Arithmetic" |
82 | | - (testing "with positive integers" |
83 | | - (is (= 4 (+ 2 2))) |
84 | | - (is (= 7 (+ 3 4)))) |
85 | | - (testing "with negative integers" |
86 | | - (is (= -4 (+ -2 -2))) |
87 | | - (is (= -1 (+ 3 -4))))) |
88 | | - |
89 | | - ;; Note that, unlike RSpec, the "testing" macro may only be used |
90 | | - ;; INSIDE a "deftest" or "with-test" form (see below). |
91 | | - ;; |
92 | | - ;; |
93 | | - ;; |
94 | | - ;; DEFINING TESTS |
95 | | - ;; |
96 | | - ;; There are two ways to define tests. The "with-test" macro takes |
97 | | - ;; a defn or def form as its first argument, followed by any number |
98 | | - ;; of assertions. The tests will be stored as metadata on the |
99 | | - ;; definition. |
100 | | - |
101 | | - (with-test |
102 | | - (defn my-function [x y] |
103 | | - (+ x y)) |
104 | | - (is (= 4 (my-function 2 2))) |
105 | | - (is (= 7 (my-function 3 4)))) |
106 | | - |
107 | | - ;; As of Clojure SVN rev. 1221, this does not work with defmacro. |
108 | | - ;; See http://code.google.com/p/clojure/issues/detail?id=51 |
109 | | - ;; |
110 | | - ;; The other way lets you define tests separately from the rest of |
111 | | - ;; your code, even in a different namespace: |
112 | | - |
113 | | - (deftest addition |
114 | | - (is (= 4 (+ 2 2))) |
115 | | - (is (= 7 (+ 3 4)))) |
116 | | - |
117 | | - (deftest subtraction |
118 | | - (is (= 1 (- 4 3))) |
119 | | - (is (= 3 (- 7 4)))) |
120 | | - |
121 | | - ;; This creates functions named "addition" and "subtraction", which |
122 | | - ;; can be called like any other function. Therefore, tests can be |
123 | | - ;; grouped and composed, in a style similar to the test framework in |
124 | | - ;; Peter Seibel's "Practical Common Lisp" |
125 | | - ;; <http://www.gigamonkeys.com/book/practical-building-a-unit-test-framework.html> |
126 | | - |
127 | | - (deftest arithmetic |
128 | | - (addition) |
129 | | - (subtraction)) |
130 | | - |
131 | | - ;; The names of the nested tests will be joined in a list, like |
132 | | - ;; "(arithmetic addition)", in failure reports. You can use nested |
133 | | - ;; tests to set up a context shared by several tests. |
134 | | - ;; |
135 | | - ;; |
136 | | - ;; |
137 | | - ;; RUNNING TESTS |
138 | | - ;; |
139 | | - ;; Run tests with the function "(run-tests namespaces...)": |
140 | | - |
141 | | - (run-tests 'your.namespace 'some.other.namespace) |
142 | | - |
143 | | - ;; If you don't specify any namespaces, the current namespace is |
144 | | - ;; used. To run all tests in all namespaces, use "(run-all-tests)". |
145 | | - ;; |
146 | | - ;; By default, these functions will search for all tests defined in |
147 | | - ;; a namespace and run them in an undefined order. However, if you |
148 | | - ;; are composing tests, as in the "arithmetic" example above, you |
149 | | - ;; probably do not want the "addition" and "subtraction" tests run |
150 | | - ;; separately. In that case, you must define a special function |
151 | | - ;; named "test-ns-hook" that runs your tests in the correct order: |
152 | | - |
153 | | - (defn test-ns-hook [] |
154 | | - (arithmetic)) |
155 | | - |
156 | | - ;; |
157 | | - ;; |
158 | | - ;; |
159 | | - ;; OMITTING TESTS FROM PRODUCTION CODE |
160 | | - ;; |
161 | | - ;; You can bind the variable "*load-tests*" to false when loading or |
162 | | - ;; compiling code in production. This will prevent any tests from |
163 | | - ;; being created by "with-test" or "deftest". |
164 | | - ;; |
165 | | - ;; |
166 | | - ;; |
167 | | - ;; FIXTURES (new) |
168 | | - ;; |
169 | | - ;; Fixtures allow you to run code before and after tests, to set up |
170 | | - ;; the context in which tests should be run. |
171 | | - ;; |
172 | | - ;; A fixture is just a function that calls another function passed as |
173 | | - ;; an argument. It looks like this: |
174 | | - (defn my-fixture [f] |
175 | | - ;; Perform setup, establish bindings, whatever. |
176 | | - (f) ;; Then call the function we were passed. |
177 | | - ;; Tear-down / clean-up code here. |
178 | | - ) |
179 | | - |
180 | | - ;; Fixtures are attached to namespaces in one of two ways. "each" |
181 | | - ;; fixtures are run repeatedly, once for each test function created |
182 | | - ;; with "deftest" or "with-test". "each" fixtures are useful for |
183 | | - ;; establishing a consistent before/after state for each test, like |
184 | | - ;; clearing out database tables. |
185 | | - ;; |
186 | | - ;; "each" fixtures can be attached to the current namespace like this: |
187 | | - (use-fixtures :each fixture1 fixture2 ...) |
188 | | - ;; The fixture1, fixture2 are just functions like the example above. |
189 | | - ;; They can also be anonymous functions, like this: |
190 | | - (use-fixtures :each (fn [f] setup... (f) cleanup...)) |
191 | | - ;; |
192 | | - ;; The other kind of fixture, a "once" fixture, is only run once, |
193 | | - ;; around ALL the tests in the namespace. "once" fixtures are useful |
194 | | - ;; for tasks that only need to be performed once, like establishing |
195 | | - ;; database connections, or for time-consuming tasks. |
196 | | - ;; |
197 | | - ;; Attach "once" fixtures to the current namespace like this: |
198 | | - (use-fixtures :once fixture1 fixture2 ...) |
199 | | - ;; |
200 | | - ;; |
201 | | - ;; |
202 | | - ;; SAVING TEST OUTPUT TO A FILE |
203 | | - ;; |
204 | | - ;; All the test reporting functions write to the var *test-out*. By |
205 | | - ;; default, this is the same as *out*, but you can rebind it to any |
206 | | - ;; PrintWriter. For example, it could be a file opened with |
207 | | - ;; clojure.contrib.duck-streams/writer. |
208 | | - ;; |
209 | | - ;; |
210 | | - ;; |
211 | | - ;; EXTENDING TEST-IS (ADVANCED) |
212 | | - ;; |
213 | | - ;; You can extend the behavior of the "is" macro by defining new |
214 | | - ;; methods for the "assert-expr" multimethod. These methods are |
215 | | - ;; called during expansion of the "is" macro, so they should return |
216 | | - ;; quoted forms to be evaluated. |
217 | | - ;; |
218 | | - ;; You can plug in your own test-reporting framework by rebinding |
219 | | - ;; the "report" function: (report event) |
220 | | - ;; |
221 | | - ;; The 'event' argument is a map. It will always have a :type key, |
222 | | - ;; whose value will be a keyword signaling the type of event being |
223 | | - ;; reported. Standard events with :type value of :pass, :fail, and |
224 | | - ;; :error are called when an assertion passes, fails, and throws an |
225 | | - ;; exception, respectively. In that case, the event will also have |
226 | | - ;; the following keys: |
227 | | - ;; |
228 | | - ;; :expected The form that was expected to be true |
229 | | - ;; :actual A form representing what actually occurred |
230 | | - ;; :message The string message given as an argument to 'is' |
231 | | - ;; |
232 | | - ;; The "testing" strings will be a list in "*testing-contexts*", and |
233 | | - ;; the vars being tested will be a list in "*testing-vars*". |
234 | | - ;; |
235 | | - ;; Your "report" function should wrap any printing calls in the |
236 | | - ;; "with-test-out" macro, which rebinds *out* to the current value |
237 | | - ;; of *test-out*. |
238 | | - ;; |
239 | | - ;; For additional event types, see the examples in the code below. |
240 | | - |
241 | | - ) ;; end comment |
242 | | - |
243 | | - |
244 | | - |
245 | 17 | (ns |
246 | 18 | #^{:author "Stuart Sierra, with contributions and suggestions by |
247 | | -Chas Emerick, Allen Rohner, and Stuart Halloway", |
248 | | - :doc "Inspired by many Common Lisp test frameworks and clojure/test, |
249 | | - this file is a Clojure test framework. |
| 19 | + Chas Emerick, Allen Rohner, and Stuart Halloway", |
| 20 | + :doc "A unit testing framework. |
250 | 21 |
|
251 | 22 | ASSERTIONS |
252 | 23 |
|
|
0 commit comments