772ec3838816d94ec53a96457a2e6acd6164f757
[nit.git] / src / testing / README
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_suite` annotation.
53 The structure of a test suite is the following:
54
55         # test suite for module `foo`
56         module test_foo is test_suite
57
58         import test_suite # import the `TestSuite` class and the `test_suite` annotation
59         import foo # can be intrude to test private things
60
61         class TestFoo
62                 super TestSuite
63
64                 # test case for `foo::Foo::baz`
65                 fun test_baz do
66                         var subject = new Foo
67                         assert subject.baz(1, 2) == 3
68                 end
69         end
70
71 Test suite can be executed using the same `nitunit` command:
72
73         $ nitunit foo.nit
74
75 To be started automatically with nitunit, the module must be called `test_`
76 followed by the name of the module to test.
77 So for the module `foo.nit` the test suite will be called `test_foo.nit`.
78 Otherwise, you can use the `-t` option to specify the test suite module name:
79
80         $ nitunit foo.nit -t my_test_suite.nit
81
82 `nitunit` will execute a test for each method named `test_*` in a class named `Test*`
83 so multiple tests can be executed for a single method:
84
85         class TestFoo
86                 super TestSuite
87
88                 fun test_baz_1 do
89                         var subject = new Foo
90                         assert subject.baz(1, 2) == 3
91                 end
92
93                 fun test_baz_2 do
94                         var subject = new Foo
95                         assert subject.baz(1, -2) == -1
96                 end
97         end
98
99 `TestSuites` also provide methods to configure the test run:
100
101 `before_test` and `after_test`: methods called before/after each test case.
102 They can be used to factorize repetitive tasks:
103
104         class TestFoo
105                 super TestSuite
106
107                 var subject: Foo is noinit
108
109                 # Method executed before each test
110                 redef fun before_test do
111                         subject = new Foo
112                 end
113
114                 fun test_baz_1 do
115                         assert subject.baz(1, 2) == 3
116                 end
117
118                 fun test_baz_2 do
119                         assert subject.baz(1, -2) == -1
120                 end
121         end
122
123 When using custom test attributes, a empty init must be declared to allow automatic test running.
124
125 `before_module` and `after_module`: methods called before/after each test suite.
126 They have to be declared at top level:
127
128         module test_bdd_connector
129
130         import test_suite
131         import bdd_connector
132
133         # Testing the bdd_connector
134         class TestConnector
135                 super TestSuite
136                 # test cases using a server
137         end
138
139         # Method executed before testing the module
140         redef fun before_module do
141                 # start server before all test cases
142         end
143
144         # Method executed after testing the module
145         redef fun after_module do
146                 # stop server after all test cases
147         end
148
149 ## Generating test suites
150
151 Write test suites for big modules can be a pepetitive and boring task...
152 To make it easier, `nitunit` can generate test skeletons for Nit modules:
153
154         $ nitunit --gen-suite foo.nit
155
156 This will generate the test suite `test_foo` containing test case stubs for all public
157 methods found in `foo.nit`.
158
159 Useful options with `--gen-suite`:
160
161 * `--private`: also generate tests for protected and private methods
162 * `--force`: force generation of the skeleton (existing test suite will be overwritten)