Merge: doc: fixed some typos and other misc. corrections
[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`.
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
144
145 import foo # can be intrude to test private things
146
147 class TestFoo
148     test
149
150     # test case for `foo::Foo::baz`
151     fun baz is test do
152         var subject = new Foo
153         assert subject.baz(1, 2) == 3
154     end
155 end
156 ~~~~
157
158 Test suite can be executed using the same `nitunit` command:
159
160     $ nitunit foo.nit
161
162 `nitunit` will execute a test for each method with the `test` annotation in a class
163 also annotated with `test` so multiple tests can be executed for a single method:
164
165 ~~~~
166 class TestFoo
167     test
168
169     fun baz_1 is test do
170         var subject = new Foo
171         assert subject.baz(1, 2) == 3
172     end
173     fun baz_2 is test do
174         var subject = new Foo
175         assert subject.baz(1, -2) == -1
176     end
177 end
178 ~~~~
179
180 ## Black Box Testing
181
182 Sometimes, it is easier to validate a `TestCase` by comparing its output with a text file containing the expected result.
183
184 For each TestCase `test_bar` of a TestSuite `test_mod.nit`, a corresponding file with the expected output is looked for:
185
186 * "test_mod.sav/test_bar.res". I.e. test-cases grouped by test-suites.
187
188         This is the default and is useful if there is a lot of test-suites and test-cases in a directory
189
190 * "sav/test_bar.res". I.e. all test-cases grouped in a common sub-directory.
191
192         Useful if there is a lot of test-suites OR test-cases in a directory.
193
194 * "test_bar.res" raw in the directory.
195
196         Useful is there is a few test-suites and test-cases in a directory.
197
198 All 3 are exclusive. If more than one exists, the test-case is failed.
199
200 If a corresponding file then the output of the test-case is compared with the file.
201
202 The `diff(1)` command is used to perform the comparison.
203 The test is failed if non-zero is returned by `diff`.
204
205 ~~~
206 module test_mod is test
207
208 class TestFoo
209         test
210
211         fun bar is test do
212                 print "Hello!"
213         end
214 end
215 ~~~
216
217 Where `test_mod.sav/test_bar.res` contains
218
219 ~~~raw
220 Hello!
221 ~~~
222
223 If no corresponding `.res` file exists, then the output of the TestCase is ignored.
224
225 To helps the management of the expected results, the option `--autosav` can be used to automatically create and update them.
226
227
228 ## Configuring TestSuites
229
230 `TestSuite`s also provide annotations to configure the test run:
231 `before` and `after` annotations can be added to methods that must be called before/after each test case.
232 They can be used to factorize repetitive tasks:
233
234 ~~~
235 class TestFoo
236         test
237
238         var subject: Foo is noinit
239
240         # Method executed before each test
241         fun set_up is before do
242                 subject = new Foo
243         end
244
245         fun baz_1 is test do
246                 assert subject.baz(1, 2) == 3
247         end
248
249         fun baz_2 is test do
250                 assert subject.baz(1, -2) == -1
251         end
252 end
253 ~~~
254
255 When using custom test attributes, a empty init must be declared to allow automatic test running.
256
257 At class level, `before_all` and `after_all` annotations can be set on methods that must be called before/after all the test cases in the class:
258
259 ~~~
260 class TestFoo
261         test
262
263         var subject: Foo is noinit
264
265         # Method executed before all tests in the class
266         fun set_up is before_all do
267                 subject = new Foo
268         end
269
270         fun baz_1 is test do
271                 assert subject.baz(1, 2) == 3
272         end
273
274         fun baz_2 is test do
275                 assert subject.baz(1, -2) == -1
276         end
277 end
278 ~~~
279
280 `before_all` and `after_all` annotations can also be set on methods that must be called before/after each test suite when declared at top level:
281
282 ~~~
283 module test_bdd_connector
284
285 import bdd_connector
286
287 # Testing the bdd_connector
288 class TestConnector
289         test
290         # test cases using a server
291 end
292
293 # Method executed before testing the module
294 fun setup_db is before_all do
295         # start server before all test cases
296 end
297
298 # Method executed after testing the module
299 fun teardown_db is after_all do
300         # stop server after all test cases
301 end
302 ~~~
303
304 When dealing with multiple test suites, niunit allows you to import other test suites to factorize your tests:
305
306 ~~~
307 module test_bdd_users
308
309 import test_bdd_connector
310
311 # Testing the user table
312 class TestUsersTable
313         test
314         # test cases using the db server from `test_bdd_connector`
315 end
316
317 fun setup_table is before_all do
318         # create user table
319 end
320
321 fun teardown_table is after_all do
322         # drop user table
323 end
324 ~~~
325
326 Methods with `before*` and `after*` annotations are linearized and called in different ways.
327
328 * `before*` methods are called from the least specific to the most specific
329 * `after*` methods are called from the most specific to the least specific
330
331 In the previous example, the execution order would be:
332
333 1. `test_bdd_connector::setup_db`
334 2. `test_bdd_users::setup_table`
335 3. `all test cases from test_bdd_users`
336 4. `test_bdd_users::teardown_table`
337 5. `test_bdd_connector::teardown_db`
338
339 ## Accessing the test suite environment
340
341 The `NIT_TESTING_PATH` environment variable contains the current test suite
342 file path.
343 Nitunit define this variable before the execution of each test suite.
344 It can be used to access files based on the current test suite location:
345
346 ~~~
347 class TestWithPath
348     test
349
350     fun test_suite_path do
351         assert "NIT_TESTING_PATH".environ != ""
352     end
353 end
354 ~~~
355
356 ## Generating test suites
357
358 Write test suites for big modules can be a repetitive and boring task...
359 To make it easier, `nitunit` can generate test skeletons for Nit modules:
360
361     $ nitunit --gen-suite foo.nit
362
363 This will generate the test suite `test_foo` containing test case stubs for all public
364 methods found in `foo.nit`.
365
366
367 # OPTIONS
368
369 ### `--full`
370 Process also imported modules.
371
372 By default, only the modules indicated on the command line are tested.
373
374 With the `--full` option, all imported modules (even those in standard) are also precessed.
375
376 ### `-o`, `--output`
377 Output name (default is 'nitunit.xml').
378
379 `nitunit` produces a XML file compatible with JUnit.
380
381 ### `--dir`
382 Working directory (default is 'nitunit.out').
383
384 In order to execute the tests, nit files are generated then compiled and executed in the giver working directory.
385
386 In case of success, the directory is removed.
387 In case of failure, it is kept as is so files can be investigated.
388
389 ### `--nitc`
390 nitc compiler to use.
391
392 By default, nitunit tries to locate the `nitc` program with the environment variable `NITC` or heuristics.
393 The option is used to indicate a specific nitc binary.
394
395 ### `--no-act`
396 Does not compile and run tests.
397
398 ### `-p`, `--pattern`
399 Only run test case with name that match pattern.
400
401 Examples: `TestFoo`, `TestFoo*`, `TestFoo::test_foo`, `TestFoo::test_foo*`, `test_foo`, `test_foo*`
402
403 ### `--autosav`
404 Automatically create/update .res files for black box testing.
405
406 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).
407
408 If a test-case of a test-suite passes but that some output is generated, then an expected result file is created.
409
410 It is expected that the created/updated files are checked since the tests are considered passed.
411 A VCS like `git` is often a good tool to check the creation and modification of those files.
412
413 ### `--no-time`
414 Disable time information in XML.
415
416 This is used to have reproducible XML results.
417
418 This option is automatically activated if `NIT_TESTING` is set.
419
420 ## SUITE GENERATION
421
422 ### `--gen-suite`
423 Generate test suite skeleton for a module.
424
425 ### `-f`, `--force`
426 Force test generation even if file exists.
427
428 Any existing test suite will be overwritten.
429
430 ### `--private`
431 Also generate test case for private methods.
432
433 ### `--only-show`
434 Only display the skeleton, do not write any file.
435
436
437 # ENVIRONMENT VARIABLES
438
439 ### `NITC`
440
441 Indicate the specific Nit compiler executable to use. See `--nitc`.
442
443 ### `NIT_TESTING`
444
445 The environment variable `NIT_TESTING` is set to `true` during the execution of program tests.
446 Some libraries of programs can use it to produce specific reproducible results; or just to exit their executions.
447
448 Unit-tests may unset this environment variable to retrieve the original behavior of such piece of software.
449
450 ### `SRAND`
451
452 In order to maximize reproducibility, `SRAND` is set to 0.
453 This make the pseudo-random generator no random at all.
454 See `Sys::srand` for details.
455
456 To retrieve the randomness, unit-tests may unset this environment variable then call `srand`.
457
458 ### `NIT_TESTING_ID`
459
460 Parallel executions can cause some race collisions on named resources (e.g. DB table names).
461 To solve this issue, `NIT_TESTING_ID` is initialized with a distinct integer identifier that can be used to give unique names to resources.
462
463 Note: `rand` is not a recommended way to get a distinct identifier because its randomness is disabled by default. See `SRAND`.
464
465 ### `NIT_TESTING_PATH`
466
467 Only available for test suites.
468 Contains the module test suite path.
469
470 # SEE ALSO
471
472 The Nit language documentation and the source code of its tools and libraries may be downloaded from <http://nitlanguage.org>