OSDN Git Service

to japanese documents
[ccunit/ccunit.git] / doc / cookbook.dox
1 /* -*- Indented-Text -*- */
2 /* $Id$ */
3 /** @page cookbook CCUnit Cookbook
4
5 Here is a short cookbook to help you get started.
6
7 @section simple_test_case Simple Test Case
8
9 Tests in <b>CCUnit</b> can be run automatically.  They are
10 easy to set up and once you have written them, they are
11 always there to help you keep confidence in the quality of
12 your code.
13
14 To make a simple test, here is what you do:
15
16 <ol>
17 <li> Create a test function</li>
18 <li> When you want to check a value, call 
19      @link CCUNIT_ASSERT() CCUNIT_ASSERT(bool) @endlink
20      and pass a bool that is true if the test succeeds</li>
21 </ol>
22
23 For example, to test that the sum of two complex number
24 which is the sum of the values of two complex numbers,
25 write:
26
27 @code
28 void test_complex_add ()
29 {
30   complex_t c10_1 = { 10.0, 1.0 };
31   complex_t c1_1 = { 1.0, 1.0 };
32   complex_t result;
33   complex_t c11_2 = { 11.0, 2.0 };
34   CCUNIT_ASSERT (complex_equals (&c11_2, complex_add (&result, c10_1, c1_1)));
35 }
36 @endcode
37
38 That was a very simple test. Ordinarily, you'll have many
39 little test cases that you'll want to run on the same set of
40 objects. To do this, use a fixture.
41
42 @section fixture Fixture
43
44 What if you have two or more tests that operate on the same
45 similar set of objects?
46
47 Tests need to run against the background of a known set of
48 objects. This set of objects is called a test fixture. When
49 you are writing tests you will often find that you spend
50 more time writing the code to set up the fixture than you do
51 in actually testing values.
52
53 Often, you will be able to use the same fixture for sevral
54 different tests. Each case will send slightly different
55 messages or parameteres to the fixture and will check for
56 different results.
57
58 When you have a common fixture, here is what you do:
59
60 <ol>
61 <li>Create a @link CCUnitTestCase TestCase @endlink object</li>
62 <li>Add an global variable for each part of the fixture</li>
63 <li>Write <code>setUp()</code> function to initialize the valiables</li>
64 <li>Write <code>tearDown()</code> to release any permanent
65     resources you allocated in <code>setUp</code></li>
66 <li>Create a @link CCUnitTestFixture TestFixture @endlink object</li>
67 <li>Add test case objects to fixture object</li>
68 </ol>
69
70 For example, to write several test cases, first create a
71 fixture:
72
73 @code
74 //** TEST CASE: complex number test *\/
75
76 #include "complex.h"
77
78 static complex_t* s10_1;
79 static complex_t* s1_1;
80 static complex_t* s11_2;
81
82 void setUp_ComplexTest ()
83 {
84   s10_1 = complex_new (10, 1);
85   s1_1 = complex_new (1, 1);
86   s11_2 = complex_new (11, 2);
87 }
88  
89 void tearDown_ComplexTest ()
90 {
91   complex_delete (s10_1);
92   complex_delete (s1_1);
93   complex_delete (s11_2);
94 }
95
96 ...
97
98   CCUnitTestFixture* fixture;
99   fixture = ccunit_newTestFixture ("ComplexTest",
100                                    CCUNIT_NEWTESTFUNC(setUp_ComplexTest),
101                                    CCUNIT_NEWTESTFUNC(tearDown_ComplexTest));
102 @endcode
103
104 Once you have the Fixture in place, you can write as complex
105 Test Cases as you'd like.
106
107 @section test_case Test Case
108
109 How do you write and invoke an individual test case when you
110 have a Fixture?
111
112 For example, to test the equality of two complex number,
113 write:
114
115 @code
116 void test_complex_equals ()
117 {
118   CCUNIT_ASSERT_TEST_OBJ (s10_1, complex_equals, s10_1, complex_to_string);
119   CCUNIT_ASSERT_TEST_OBJ (s10_1, !complex_equals, s1_1, complex_to_string);
120 }
121
122 ...
123
124   ccunit_addNewTestCase (fixture, 
125                          "test_complex_equals",
126                          "complex equals test",
127                          test_complex_equals);
128   ccunit_addNewTestCase (fixture,
129                          "test_complex_add",
130                          "complex add test",
131                          test_complex_add);
132 @endcode  
133
134 One may create and run objects for each test case like this:
135
136 @code
137   CCUnitTestResult* result;
138   result = ccunit_runTestFixture (fixture);
139 @endcode
140
141 When the test fixture is run, that specific test functions
142 will be run.  This is not a useful thing to do, however, as
143 no diagnostics will be displayed.  One will normally use a
144 @link ExecutingTest TestRunner @endlink (see below) to
145 display the results.
146
147 Once you have several tests, organize them into a suite.
148
149 @section suite Suite
150
151 How do you set up your tests so that you can run them all at once?
152
153 %CCUnit provides a @link CCUnitTestSuite TestSuite @endlink
154 module that runs any number of TestCases together.
155
156 You saw, above, how to run test fixture.
157
158 To create a suite of two or more tests, you do the following:
159
160 @code
161 CCUnitTestSuite* suite;
162 CCUnitTestFixture* fixture;
163 CCUnitTestResult* result;
164 suite = ccunit_newTestSuite ("Complex test suite");
165 fixture = ccunit_newTestFixture ("Complex Tests", 
166                                  CCUNIT_NEWTESTFUNC(setUp_complex_test),
167                                  CCUNIT_NEWTESTFUNC(tearDown_complex_test));
168 ccunit_addNewTestCase (fixture, "test_complex_equals", "complex equals test",
169                        test_complex_equals);
170 ccunit_addNewTestCase (fixture, "test_complex_add", "complex add test",
171                        test_complex_add);
172 ccunit_addNewTestCase (fixture, "test_complex_sub", "complex sub test",
173                        test_complex_sub);
174 ccunit_addTestFixture (suite, fixtuer);
175 result = ccunit_runTestSuite (suite, NULL);
176 @endcode         
177
178 @link CCUnitTestSuite TestSuites @endlink don't only have to
179 contain @link CCUnitTestFixture TestFixtures @endlink.  They
180 can contain any object that implements the @link CCUnitTest
181 Test @endlink interface.  For example, you can create a
182 @link CCUnitTestSuite TestSuite @endlink in your code and I
183 can create one in mine, and we can run them together by
184 creating a @link CCUnitTestSuite TestSuite @endlink that
185 contains both:
186
187 @code
188 CCUnitTestSuite* suite;
189 CCUnitTestResult* result;
190 suite = ccunit_newTestSuite ("suite");
191 ccunit_addTestSuite (suite, complex_add_sub_suite ());
192 ccunit_addTestSuite (suite, complex_mul_div_suite ());
193 result = ccunit_runTestSuite(suite, NULL);
194 @endcode
195
196
197 @section test_runner TestRunner
198
199 How do you run your tests and collect their results?
200
201 Once you have a test suite, you'll want to run it. %CCUnit
202 provides tools to define the suite to be run and to display
203 its results.  You make your suite accessible to a @link
204 CreatingTestSuite ccunit_makeSuite @endlink tool that generate a
205 creating test suite code.
206
207 For example, to make a ComplexTest suite available to a 
208 @link CreatingTestSuite ccunit_makeSuite @endlink, 
209 excute the following tool to 
210 ComplexTest.c:
211
212 @code
213 $ ccunit_makeSuite -f complex_suite -o suiteComplex.c ComplexTest.c
214 @endcode
215
216 @anchor test_runner_code
217 To use the TestRunner, include the header files for the tests in Main.c:
218
219 @code
220 #include <ccunit/CCUnitTestRunner.h>
221 #include <ccunit/CCUnitTestSuite.h>
222 @endcode
223
224 And call to
225 @link ccunit_runTestRunner()
226 ccunit_runTestRunner (CCUnitTestRunner*, CCUnitTestSuite *) @endlink 
227 in the <code>main()</code> function:
228
229 @code
230 extern CCUnitTestSuite* complex_suite(const char* name);
231
232 int main( int argc, char **argv)
233 {
234   CCUnitTestRunner* runner;
235   CCUnitTestSuite* suite;
236   runner = ccunit_newTestRunner (stdout);
237   suite = complex_suite ("complex test suite");
238   return ccunit_runTestRunner (runner, suite);
239 }
240 @endcode
241
242 The @link ExecutingTest TestRunner @endlink will run the tests. 
243 If all the tests pass, you'll get an informative message. 
244 If any fail, you'll get the following information:
245
246 <ul>
247 <li> The name of the source file that contains the test</li>
248 <li> The line number where the failure occurred</li>
249 <li> The name of the test case that failed</li>
250 <li> All of the text inside the call to
251      <code>CCUNIT_ASSERT ()</code> which detected the failure</li>
252 </ul>
253
254 @section helper_macros Helper Tool
255
256 As you might have noticed, implementing the fixture
257 <code>suite ()</code> function is a repetitive and error
258 prone task. A @ref CreatingTestSuite set of functions and
259 command have been created to automatically implements the
260 <code>suite()</code> method.
261
262 The following code is a rewrite of ComplexTest using those command:
263
264 @code
265 #include <cppunit/CCUnitAssert.h>
266 @endcode
267
268 First, you declare the fixture, passing the test fixture
269 name to the javaDoc style comment, which consist of a
270 C-style comment block starting with two <tt>*</tt>'s:
271
272 @code
273 //** test case: complex number test *\/
274 @endcode
275
276 The suite created by the <code>ccunit_suite()</code>
277 function is specified <code>-f</code> option of command
278 <code>ccunit_makeSuite</code>.  Then, you define each test
279 case of the fixture with prefix <code>test</code>,
280 <code>setUp</code>, <code>tearDown</code>:
281
282 @code
283 #include <complex.h>
284
285 static complex_t* s10_1;
286 static complex_t* s1_1;
287 static complex_t* s11_2;
288
289 void setUp_complex_test ()
290 {
291   s10_1 = complex_new (10, 1);
292   s1_1 = complex_new (1, 1);
293   s11_2 = complex_new (11, 2);
294 }
295  
296 void tearDown_complex_test ()
297 {
298   complex_delete (s10_1);
299   complex_delete (s1_1);
300   complex_delete (s11_2);
301 }
302
303 //** test equals *\/
304 void test_complex_equals ()
305 {
306   CCUNIT_ASSERT_TEST_OBJ (s10_1, complex_equals, s10_1, complex_to_string);
307   CCUNIT_ASSERT_TEST_OBJ (s10_1, !complex_equals, s1_1, complex_to_string);
308 }
309
310 //** test add *\/
311 void test_complex_add ()
312 {
313   complex_t c10_1 = { 10.0, 1.0 };
314   complex_t c1_1 = { 1.0, 1.0 };
315   complex_t result;
316   complex_t c11_2 = { 11.0, 2.0 };
317   CCUNIT_ASSERT (complex_equals (&c11_2, complex_add (&result, &c10_1, &c1_1)));
318 }
319
320 //** test sub *\/
321 void test_complex_sub ()
322 {
323   complex_t c9_0 = { 9, 0 };
324   complex_t result;
325   CCUNIT_ASSERT_TEST_OBJ (&c9_0, complex_equals,
326                           complex_sub (&result, s10_1, s1_1),
327                           complex_to_string);
328 }
329 @endcode
330
331 Finally, you end the fixture declaration:
332
333 @code
334 //** end test case *\/
335 @endcode
336
337 To generate creating suite function code, run
338 <code>ccunit_makeSuite</code> tool.
339
340 @code
341 $ ccunit_makeSuite testComplex.c
342
343 #include <ccunit/CCUnitTestSuite.h>
344 #include <ccunit/CCUnitTestFixture.h>
345 #include <ccunit/CCUnitTestCase.h>
346
347 //* test fixture: complex number test *\/
348 //* setUp_complex_test *\/
349 extern void setUp_complex_test ();
350 //* tearDown_complex_test *\/
351 extern void tearDown_complex_test ();
352 //* test_complex_equals *\/
353 extern void test_complex_equals ();
354 //* test_complex_add *\/
355 extern void test_complex_add ();
356 //* test_complex_sub *\/
357 extern void test_complex_sub ();
358
359
360 static CCUnitTestFixtureDfn fx_001 = {
361   { ccunitTypeFixture },
362   "complex number test",
363   {
364     "setUp_complex_test",
365     "setUp_complex_test",
366     setUp_complex_test
367   },
368   {
369     "tearDown_complex_test",
370     "tearDown_complex_test",
371     tearDown_complex_test
372   },
373   {
374     {
375       "test_complex_equals",
376       "test equals",
377       test_complex_equals
378     },
379     {
380       "test_complex_add",
381       "test add",
382       test_complex_add
383     },
384     {
385       "test_complex_sub",
386       "test sub",
387       test_complex_sub
388     },
389     {
390       NULL, NULL, NULL
391     },
392   }
393 };
394
395 static CCUnitTestSuiteDfn suite_001 = {
396   { ccunitTypeSuite },
397   "",
398   {
399     &suite_002.test,
400     NULL,
401   },
402 };
403
404 CCUnitTestSuite* ccunit_suite (const char* name)
405 {
406   if (!suite_001.name[0])
407     suite_001.name = name;
408   return ccunit_newTestSuiteFromDfn (&suite_001);
409 }
410 $
411 @endcode
412
413 @section post_build_check Post-build check
414
415 Now that we have our unit tests running, how about
416 integrating unit testing to our build process ?
417
418 To do that, the application must returns a value different than 0 to indicate that
419 there was an error.
420
421 @link ccunit_runTestRunner() ccunit_runTestRunner() @endlink returns 
422 a integer indicating if the run was successful.
423
424 Updating our main programm, we obtains:
425 @code
426 #include <ccunit/CCUnitTestRunner.h>
427
428 int main (int argc, char** argv)
429 {
430   CCUnitTestRunner* runner;
431   CCUnitTestSuite* suite;
432   int wasSucessful;
433   runner = ccunit_newTestRunner (stdout);
434   suite = ccunit_suite ();
435   wasSucessful = ccunit_runTestRunner (runner, suite);
436   return wasSucessful;
437 }
438 @endcode
439
440 Now, you need to run your application after compilation.
441
442 */