model: remove a warning :p
[nit.git] / share / man / nitunit.md
1 # NAME
2
3 nitunit - executes the unit tests from Nit source files.
4
5 # SYNOPSIS
6
7 nitunit [*options*] FILE...
8
9 # DESCRIPTION
10
11 Unit testing in Nit can be achieved in two ways:
12
13 * using `DocUnits` in code comments or in markdown files
14 * using `TestSuites` with test unit files
15
16 `DocUnits` are executable pieces of code found in the documentation of groups, modules,
17 classes and properties.
18 They are used for documentation purpose, they should be kept simple and illustrative.
19 More advanced unit testing can be done using TestSuites.
20
21 `DocUnits` can also be used in any markdown files.
22
23 `TestSuites` are test files coupled to a tested module.
24 They contain a list of test methods called TestCase.
25
26 ## Working with `DocUnits`
27
28 DocUnits are blocks of executable code placed in comments of modules, classes and properties.
29 The execution can be verified using `assert`.
30
31 Example with a class:
32
33 ~~~
34 module foo
35 #    var foo = new Foo
36 #    assert foo.bar == 10
37 class Foo
38     var bar = 10
39 end
40 ~~~
41
42 Everything used in the test must be declared.
43 To test a method you have to instantiate its class:
44
45 ~~~
46 module foo
47 #    var foo = new Foo
48 #    assert foo.bar == 10
49 class Foo
50     #    var foo = new Foo
51     #    assert foo.baz(1, 2) == 3
52     fun baz(a, b: Int) do return a + b
53 end
54 ~~~
55
56 In a single piece of documentation, each docunit is considered a part of a single module, thus regrouped when
57 tested.
58 Therefore, it is possible (and recommended) to split docunits in small parts if it make the explanation easier.
59
60 ~~~~
61 # Some example of grouped docunits
62 #
63 # Declare and initialize a variable `a`.
64 #
65 #     var a = 1
66 #
67 # So the value of `a` can be used
68 #
69 #     assert a == 1
70 #
71 # even in complex operations
72 #
73 #     assert a + 1 == 2
74 fun foo do end
75 ~~~~
76
77 Sometime, some blocks of code has to be included in documentation but not considered by `nitunit`.
78 Those blocks are distinguished by their tagged fences (untagged fences or fences tagged `nit` are considered to be docunits).
79
80 ~~~~
81 # Some ASCII drawing
82 #
83 # ~~~~raw
84 #   @<
85 # <__)
86 # ~~~~
87 fun foo do end
88 ~~~~
89
90 The special fence-tag `nitish` could also be used to indicate pseudo-nit that will be ignored by nitunit but highlighted by nitdoc.
91 Such `nitish` piece of code can be used to enclose examples that cannot compile or that one do not want to be automatically executed.
92
93 ~~~~
94 # Some pseudo-nit
95 #
96 # ~~~~nitish
97 # var a: Int = someting
98 # # ...
99 # if a == 1 then something else something-else
100 # ~~~~
101 #
102 # Some code to not try to execute automatically
103 #
104 # ~~~~nitish
105 # system("rm -rf /")
106 # ~~~~
107 ~~~~
108
109 The `nitunit` command is used to test Nit files:
110
111     $ nitunit foo.nit
112
113 Groups (directories) can be given to test the documentation of the group and of all its Nit files:
114
115     $ nitunit lib/foo
116
117 Finally, standard markdown documents can be checked with:
118
119     $ nitunit foo.md
120
121 When testing, the environment variable `NIT_TESTING` is set to `true`.
122 This flag can be used by libraries and program to prevent (or limit) the execution of dangerous pieces of code.
123
124 ~~~~~
125 # NIT_TESTING is automatically set.
126 #
127 #     assert "NIT_TESTING".environ == "true"
128 ~~~~
129
130 ## Working with `TestSuites`
131
132 TestSuites are Nit modules that define a set of TestCases.
133
134 A test suite is a module that uses the annotation `is test_suite`.
135
136 It is common that a test suite focuses on testing a single module.
137 In this case, the name of the test_suite is often `test_foo.nit` where `foo.nit` is the tested module.
138
139 The structure of a test suite is the following:
140
141 ~~~~
142 # test suite for module `foo`
143 module test_foo is test_suite
144
145 import test_suite
146 import foo # can be intrude to test private things
147
148 class TestFoo
149         super TestSuite
150
151     # test case for `foo::Foo::baz`
152     fun test_baz do
153         var subject = new Foo
154         assert subject.baz(1, 2) == 3
155     end
156 end
157 ~~~~
158
159 Test suite can be executed using the same `nitunit` command:
160
161     $ nitunit foo.nit
162
163 `nitunit` will execute a test for each method named `test_*` in a class
164 subclassing `TestSuite` so multiple tests can be executed for a single method:
165
166 ~~~~
167 class TestFoo
168         super TestSuite
169
170     fun test_baz_1 do
171         var subject = new Foo
172         assert subject.baz(1, 2) == 3
173     end
174     fun test_baz_2 do
175         var subject = new Foo
176         assert subject.baz(1, -2) == -1
177     end
178 end
179 ~~~~
180
181 ## Black Box Testing
182
183 Sometimes, it is easier to validate a `TestCase` by comparing its output with a text file containing the expected result.
184
185 For each TestCase `test_bar` of a TestSuite `test_mod.nit`, a corresponding file with the expected output is looked for:
186
187 * "test_mod.sav/test_bar.res". I.e. test-cases grouped by test-suites.
188
189         This is the default and is useful if there is a lot of test-suites and test-cases in a directory
190
191 * "sav/test_bar.res". I.e. all test-cases grouped in a common sub-directory.
192
193         Useful if there is a lot of test-suites OR test-cases in a directory.
194
195 * "test_bar.res" raw in the directory.
196
197         Useful is there is a few test-suites and test-cases in a directory.
198
199 All 3 are exclusive. If more than one exists, the test-case is failed.
200
201 If a corresponding file then the output of the test-case is compared with the file.
202
203 The `diff(1)` command is used to perform the comparison.
204 The test is failed if non-zero is returned by `diff`.
205
206 ~~~
207 module test_mod is test_suite
208
209 class TestFoo
210         super TestSuite
211
212         fun test_bar do
213                 print "Hello!"
214         end
215 end
216 ~~~
217
218 Where `test_mod.sav/test_bar.res` contains
219
220 ~~~raw
221 Hello!
222 ~~~
223
224 If no corresponding `.res` file exists, then the output of the TestCase is ignored.
225
226 To helps the management of the expected results, the option `--autosav` can be used to automatically create and update them.
227
228
229 ## Configuring TestSuites
230
231 `TestSuite`s also provide methods to configure the test run:
232
233 `before_test` and `after_test`: methods called before/after each test case.
234 They can be used to factorize repetitive tasks:
235
236 ~~~~
237 class TestFoo
238         super TestSuite
239     var subject: Foo
240     # Mandatory empty init
241     init do end
242     # Method executed before each test
243     fun before_test do
244         subject = new Foo
245     end
246     fun test_baz_1 do
247         assert subject.baz(1, 2) == 3
248     end
249     fun test_baz_2 do
250         assert subject.baz(1, -2) == -1
251     end
252 end
253 ~~~~
254
255 When using custom test attributes, an empty `init` must be declared to allow automatic test running.
256
257 `before_module` and `after_module`: methods called before/after each test suite.
258 They have to be declared at top level:
259
260 ~~~~
261 module test_bdd_connector
262 import bdd_connector
263 # Testing the bdd_connector
264 class TestConnector
265     # test cases using a server
266 end
267 # Method executed before testing the module
268 fun before_module do
269     # start server before all test cases
270 end
271 # Method executed after testing the module
272 fun after_module do
273     # stop server after all test cases
274 end
275 ~~~~
276
277 ## Accessing the test suite environment
278
279 The `NIT_TESTING_PATH` environment variable contains the current test suite
280 file path.
281 Nitunit define this variable before the execution of each test suite.
282 It can be used to access files based on the current test_suite location:
283
284 ~~~
285 class TestWithPath
286         super TestSuite
287
288     fun test_suite_path do
289         assert "NIT_TESTING_PATH".environ != ""
290     end
291 end
292 ~~~
293
294 ## Generating test suites
295
296 Write test suites for big modules can be a repetitive and boring task...
297 To make it easier, `nitunit` can generate test skeletons for Nit modules:
298
299     $ nitunit --gen-suite foo.nit
300
301 This will generate the test suite `test_foo` containing test case stubs for all public
302 methods found in `foo.nit`.
303
304
305 # OPTIONS
306
307 ### `--full`
308 Process also imported modules.
309
310 By default, only the modules indicated on the command line are tested.
311
312 With the `--full` option, all imported modules (even those in standard) are also precessed.
313
314 ### `-o`, `--output`
315 Output name (default is 'nitunit.xml').
316
317 `nitunit` produces a XML file compatible with JUnit.
318
319 ### `--dir`
320 Working directory (default is 'nitunit.out').
321
322 In order to execute the tests, nit files are generated then compiled and executed in the giver working directory.
323
324 In case of success, the directory is removed.
325 In case of failure, it is kept as is so files can be investigated.
326
327 ### `--nitc`
328 nitc compiler to use.
329
330 By default, nitunit tries to locate the `nitc` program with the environment variable `NITC` or heuristics.
331 The option is used to indicate a specific nitc binary.
332
333 ### `--no-act`
334 Does not compile and run tests.
335
336 ### `-p`, `--pattern`
337 Only run test case with name that match pattern.
338
339 Examples: `TestFoo`, `TestFoo*`, `TestFoo::test_foo`, `TestFoo::test_foo*`, `test_foo`, `test_foo*`
340
341 ### `--autosav`
342 Automatically create/update .res files for black box testing.
343
344 If a black block test fails because a difference between the expected result and the current result then the expected result file is updated (and the test is passed).
345
346 If a test-case of a test-suite passes but that some output is generated, then an expected result file is created.
347
348 It is expected that the created/updated files are checked since the tests are considered passed.
349 A VCS like `git` is often a good tool to check the creation and modification of those files.
350
351 ### `--no-time`
352 Disable time information in XML.
353
354 This is used to have reproducible XML results.
355
356 This option is automatically activated if `NIT_TESTING` is set.
357
358 ## SUITE GENERATION
359
360 ### `--gen-suite`
361 Generate test suite skeleton for a module.
362
363 ### `-f`, `--force`
364 Force test generation even if file exists.
365
366 Any existing test suite will be overwritten.
367
368 ### `--private`
369 Also generate test case for private methods.
370
371 ### `--only-show`
372 Only display the skeleton, do not write any file.
373
374
375 # ENVIRONMENT VARIABLES
376
377 ### `NITC`
378
379 Indicate the specific Nit compiler executable to use. See `--nitc`.
380
381 ### `NIT_TESTING`
382
383 The environment variable `NIT_TESTING` is set to `true` during the execution of program tests.
384 Some libraries of programs can use it to produce specific reproducible results; or just to exit their executions.
385
386 Unit-tests may unset this environment variable to retrieve the original behavior of such piece of software.
387
388 ### `SRAND`
389
390 In order to maximize reproducibility, `SRAND` is set to 0.
391 This make the pseudo-random generator no random at all.
392 See `Sys::srand` for details.
393
394 To retrieve the randomness, unit-tests may unset this environment variable then call `srand`.
395
396 ### `NIT_TESTING_ID`
397
398 Parallel executions can cause some race collisions on named resources (e.g. DB table names).
399 To solve this issue, `NIT_TESTING_ID` is initialized with a distinct integer identifier that can be used to give unique names to resources.
400
401 Note: `rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default. See `SRAND`.
402
403 ### `NIT_TESTING_PATH`
404
405 Only available for test suites.
406 Contains the module test suite path.
407
408 # SEE ALSO
409
410 The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>