diff options
Diffstat (limited to 'src/doxy/unittest.dox')
-rw-r--r-- | src/doxy/unittest.dox | 105 |
1 files changed, 104 insertions, 1 deletions
diff --git a/src/doxy/unittest.dox b/src/doxy/unittest.dox index d0ffbd5..24e1de4 100644 --- a/src/doxy/unittest.dox +++ b/src/doxy/unittest.dox | |||
@@ -9,7 +9,110 @@ | |||
9 | *@page howto_unittest Writing Unit Tests For Your Programs | 9 | *@page howto_unittest Writing Unit Tests For Your Programs |
10 | * | 10 | * |
11 | * Libbu++ uses it's own simple and flexible unit testing framework, and you can | 11 | * Libbu++ uses it's own simple and flexible unit testing framework, and you can |
12 | * too! | 12 | * too! Unit testing is a fairly simple concept. You create many small tests |
13 | * that ensure that each individual component of a program is working as it | ||
14 | * should. These make it easy to test code as it's designed, and even helps to | ||
15 | * ensure that your code continues to work as changes are made in the future. | ||
16 | * | ||
17 | * There are two main ways of writing unit test "suites" or pagkages with | ||
18 | * libbu++: Using the mkunit unit test compiler or by using the Bu::UnitSuite | ||
19 | * class directly. Both of these will be dicussed below, but the mkunit method | ||
20 | * is definately recommended. | ||
21 | * | ||
22 | *@section mkunit Using mkunit to create Unit Test Suites | ||
23 | * | ||
24 | * Using mkunit is definately the easiest way to go, the format is very basic, | ||
25 | * and almost all c++ constructs work exactly as you would expect. First, the | ||
26 | * mkunit program itself is included with libbu++ and built when the library is | ||
27 | * built. When you run mkunit on a .unit file it produces a matching .cpp file. | ||
28 | * You should avoid editing the generated .cpp file since it will be overwritten | ||
29 | * by the next run of mkunit. To make debugging easier mkunit takes advantage | ||
30 | * of standard preprocessor macros to make debuggers and compilers treat the | ||
31 | * .unit file as the original source file, all errors will refer to that file. | ||
32 | * | ||
33 | * There are two new constructs that you can take advantage of in a .unit file: | ||
34 | * - suite: This identifier defines a suite of tests, each .unit file needs at | ||
35 | * least one of these. suite is followed by a { } block that may contain | ||
36 | * standard c++ code as well as test identifiers. This becomes the UnitSuite | ||
37 | * child class. | ||
38 | * - test: This identifier defines a test within the suite, and is followed by | ||
39 | * a { } block of code that is run for that test. This becomes a function. | ||
40 | * | ||
41 | * A simple example will help illustrate this: | ||
42 | *@code | ||
43 | #include <stdio.h> | ||
44 | |||
45 | suite Math | ||
46 | { | ||
47 | test arithmetic | ||
48 | { | ||
49 | unitTest( 5*5 == 25 ); | ||
50 | unitTest( 25/5 == 5 ); | ||
51 | unitTest( 5+5 == 10 ); | ||
52 | // etc... | ||
53 | } | ||
54 | } | ||
55 | @endcode | ||
56 | * | ||
57 | * This example creates one test suite named Math, and one test named arithmetic | ||
58 | * which tests the computer's ability to do simple arithmetic. The macro | ||
59 | * unitTest(...) checks the contained code, if the expression evaluetes to true | ||
60 | * then the test continues, if not it fails immediately, exists, and reports | ||
61 | * what expression caused it to fail, and what line number it happened on. | ||
62 | * | ||
63 | * Also available is the macro unitFailed("...") which will cause the test to | ||
64 | * immediately fail, and the reason given will be the textual message provided. | ||
65 | * | ||
66 | * When using the mkunit method, you shouldn't define a main function, this is | ||
67 | * automatically done for you. | ||
68 | * | ||
69 | * Compiling a mkunit style unit test suite is fairly easy too. You basically | ||
70 | * need the following: | ||
71 | *@code | ||
72 | mkunit mysuite.unit mysuite.cpp | ||
73 | g++ mysuite.cpp -o mysuite -lbu++ | ||
74 | @endcode | ||
75 | * This will produce a ready to use executable that will run all tests in the | ||
76 | * suite and report success or failure, and provide a nice summary at the end. | ||
77 | * Each test suite also supports a rich set of command line options to get more | ||
78 | * information, control which tests are run, and control output. | ||
79 | * | ||
80 | *@section unitsuite_features UnitSuite features for everyone | ||
81 | * There are a number of features that you can take advantage of no matter what | ||
82 | * method you used to design your unit test suite. One of them is the progress | ||
83 | * meter. For tests that are going to take a noticable amount of time, or even | ||
84 | * all tests that have more than one step, you can use the functions: | ||
85 | * - Bu::UnitSuite::setStepCount - to set the number of steps that will be | ||
86 | * performed by the test. This is effectively arbitrary and just sets the | ||
87 | * upper limit for the progress indicator. For example, if you're going to | ||
88 | * perform a nested loop with 100 iterations in the outer and 250 on the | ||
89 | * inner you may call setStepCount( 100*250 ) at the begining of the test. | ||
90 | * - Bu::UnitSuite::incProgress - Increment the progress counter by one. | ||
91 | * In the above example if you placed this function call at the end of the | ||
92 | * innermost loop you would get a pleasant progress readout as the test | ||
93 | * proceeded. | ||
94 | * | ||
95 | * Here is a slightly more concrete example of the progress meter functions: | ||
96 | *@code | ||
97 | suite Intensive | ||
98 | { | ||
99 | test LongTest1 | ||
100 | { | ||
101 | setStepCount( 100*250 ); | ||
102 | for( int iOuter = 0; iOuter < 100; ++iOuter ) | ||
103 | { | ||
104 | for( int iInner = 0; iInner < 250; ++iInner ) | ||
105 | { | ||
106 | doSomethingComplex( iOuter, iInner ); | ||
107 | incProgress(); | ||
108 | } | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | @endcode | ||
113 | * To ensure that the progress meter doesn't use up an exorbatant amount of CPU | ||
114 | * time in very tight loops the display will be updated at most every second, | ||
115 | * and only when a call to incProgress is made. | ||
13 | * | 116 | * |
14 | *@todo Finish this page. | 117 | *@todo Finish this page. |
15 | */ | 118 | */ |