diff options
Diffstat (limited to '')
| -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 | */ |
