Merge: model: is_accessor
[nit.git] / src / testing / README.md
1 # Test unit generation and execution for Nit.
2
3 In Nit, unit testing can be achieved in two ways:
4
5 * using `DocUnits` in code comments
6 * using `TestSuites` with test unit files
7
8 DocUnits are executable pieces of code found in the documentation of modules,
9 classes and properties.
10 They are used for documentation purpose, they should be kept simple and illustrative.
11 More advanced unit testing can be done using TestSuites.
12
13 TestSuites are test files coupled to a tested module.
14 They contain a list of test methods called TestCase.
15
16 ## Working with `DocUnits`
17
18 With DocUnits, executable code can be placed in comments of modules, classes and properties.
19 The execution can be verified using `assert`
20
21 Example with a class:
22
23         module foo
24
25         #    var foo = new Foo
26         #    assert foo.bar == 10
27         class Foo
28                 var bar = 10
29         end
30
31 Everything used in the test must be declared.
32 To test a method you have to instanciate its class:
33
34         module foo
35
36         #    var foo = new Foo
37         #    assert foo.bar == 10
38         class Foo
39                 #    var foo = new Foo
40                 #    assert foo.baz(1, 2) == 3
41                 fun baz(a, b: Int) do return a + b
42         end
43
44 `nitunit` is used to test Nit files:
45
46         $ nitunit foo.nit
47
48 ## Working with `TestSuites`
49
50 TestSuites are Nit files that define a set of TestCase for a particular module.
51
52 The test suite module must be declared using the `test` annotation.
53 The structure of a test suite is the following:
54
55         # test suite for module `foo`
56         module test_foo is test
57
58         import foo # can be intrude to test private things
59
60         class TestFoo
61                 test
62
63                 # test case for `foo::Foo::baz`
64                 fun baz is test do
65                         var subject = new Foo
66                         assert subject.baz(1, 2) == 3
67                 end
68         end
69
70 Test suite can be executed using the same `nitunit` command:
71
72         $ nitunit foo.nit
73
74 To be started automatically with nitunit, the module must be called `test_`
75 followed by the name of the module to test.
76 So for the module `foo.nit` the test suite will be called `test_foo.nit`.
77 Otherwise, you can use the `-t` option to specify the test suite module name:
78
79         $ nitunit foo.nit -t my_test_suite.nit
80
81 `nitunit` will execute a test for each method annotated with `test` in a class also annotated with `test`
82 so multiple tests can be executed for a single method:
83
84         class TestFoo
85                 test
86
87                 fun baz_1 is test do
88                         var subject = new Foo
89                         assert subject.baz(1, 2) == 3
90                 end
91
92                 fun baz_2 is test do
93                         var subject = new Foo
94                         assert subject.baz(1, -2) == -1
95                 end
96         end
97
98 `TestSuites` also provide methods to configure the test run:
99
100 `before` and `after` annotations can be added to methods that must be called before/after each test case.
101 They can be used to factorize repetitive tasks:
102
103         class TestFoo
104                 test
105
106                 var subject: Foo is noinit
107
108                 # Method executed before each test
109                 redef fun set_up is before do
110                         subject = new Foo
111                 end
112
113                 fun baz_1 is test do
114                         assert subject.baz(1, 2) == 3
115                 end
116
117                 fun baz_2 is test do
118                         assert subject.baz(1, -2) == -1
119                 end
120         end
121
122 When using custom test attributes, a empty init must be declared to allow automatic test running.
123
124 `before_all` and `after_all` annotations can be set on methods that must be called before/after each test suite.
125 They have to be declared at top level:
126
127         module test_bdd_connector
128
129         import bdd_connector
130
131         # Testing the bdd_connector
132         class TestConnector
133                 test
134                 # test cases using a server
135         end
136
137         # Method executed before testing the module
138         fun before_module is before_all do
139                 # start server before all test cases
140         end
141
142         # Method executed after testing the module
143         fun after_module is after_all do
144                 # stop server after all test cases
145         end
146
147 ## Generating test suites
148
149 Write test suites for big modules can be a pepetitive and boring task...
150 To make it easier, `nitunit` can generate test skeletons for Nit modules:
151
152         $ nitunit --gen-suite foo.nit
153
154 This will generate the test suite `test_foo` containing test case stubs for all public
155 methods found in `foo.nit`.
156
157 Useful options with `--gen-suite`:
158
159 * `--private`: also generate tests for protected and private methods
160 * `--force`: force generation of the skeleton (existing test suite will be overwritten)