]>
Commit | Line | Data |
---|---|---|
fc2171bd | 1 | How to write unit tests for wxWidgets |
4f09729d VZ |
2 | ===================================== |
3 | ||
e3778b4d | 4 | Unit tests for wxWidgets are written using small cppunit framework. To compile |
4f09729d | 5 | (but not to run) them you need to have it installed. Hence the first part of |
670ec357 | 6 | this note explains how to do it while the second one explains how to write the |
4f09729d VZ |
7 | test. |
8 | ||
9 | I. CppUnit Installation | |
10 | ----------------------- | |
11 | ||
12 | 1. Get it from http://www.sourceforge.net/projects/cppunit | |
232fdc63 | 13 | (latest version as of the time of this writing is 1.10.2) |
4f09729d VZ |
14 | |
15 | 2. Build the library: | |
232fdc63 | 16 | a) Under Windows using VC++ (versions 6, 7, 8 & 9 work): |
4f09729d VZ |
17 | - build everything in CppUnitLibraries.dsw work space |
18 | - add include and lib subdirectories of the directory | |
19 | where you installed cppunit to the compiler search path | |
e3778b4d | 20 | using "Tools|Options" menu in VC IDE |
4f09729d VZ |
21 | |
22 | b) Under Unix: run configure && make && make install as usual | |
23 | ||
24 | ||
25 | II. Writing tests with CppUnit | |
26 | ------------------------------ | |
27 | ||
28 | 1. Create a new directory tests/foo | |
29 | ||
670ec357 | 30 | 2. Write a cpp file for the test copying, if you want, |
4f09729d VZ |
31 | from one of the existing tests. The things to look for: |
32 | a) #include "wx/cppunit.h" instead of directly including CppUnit headers | |
33 | b) don't put too many things in one test case nor in one method of a test | |
34 | case as it makes understanding what exactly failed harder later | |
670ec357 VS |
35 | c) 'register' your tests as follows so that the test program will find and |
36 | execute them: | |
37 | ||
38 | // register in the unnamed registry so that these tests are run by default | |
39 | CPPUNIT_TEST_SUITE_REGISTRATION(MBConvTestCase); | |
40 | ||
e3778b4d | 41 | // also include in its own registry so that these tests can be run alone |
670ec357 | 42 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(MBConvTestCase, "MBConvTestCase"); |
4f09729d | 43 | |
232fdc63 VZ |
44 | Read CppUnit documentation for more. |
45 | d) wxUIActionSimulator can be used when user input is required, for example | |
46 | clicking buttons or typing text. A simple example of this can be found | |
47 | in controls/buttontest.cpp. After simulating some user input always | |
48 | wxYield to allow event processing. When writing a test using | |
49 | wxUIActionSimulator always add the test using WXUISIM_TEST rather than | |
50 | CPPUNIT_TEST as then it won't run on unsupported platforms. The test itself | |
51 | must also be wrapped in a #if wxUSE_UIACTIONSIMULATOR block. | |
52 | e) There are a number of classes that are available to help with testing GUI | |
53 | elements. Firstly throughout the test run there is a frame of type | |
54 | wxTestableFrame that you can access through wxTheApp->GetTopWindow(). This | |
55 | class adds two new functions, GetEventCount, which takes an optional | |
56 | wxEventType. It then returns the number of events of that type that it has | |
57 | received since the last call. Passing nothing returns the total number of | |
58 | event received since the last call. Also there is OnEvent, which counts the | |
59 | events based on type that are passed to it. To make it easy to count events | |
60 | there is also a new class called EventCounter which takes a window and event | |
61 | type and connects the window to the top level wxTestableFrame with the specific | |
62 | event type. It disconnects again once it is out of scope. It simply reduces | |
63 | the amount of typing required to count events. | |
4f09729d | 64 | |
62d3301b VZ |
65 | 3. add a '<sources>' tag for your source file to tests/test.bkl. Make sure it's |
66 | in the correct section: the one starting '<exe id="test_gui"' for a gui test, | |
67 | the one starting '<exe id="test" template="wx_sample_console' otherwise. | |
670ec357 VS |
68 | |
69 | ||
70 | III. Running the tests | |
71 | ---------------------- | |
72 | ||
73 | 1. Regenerate the make/project files from test.bkl using bakefile_gen, e.g.: | |
3e0a7f68 VS |
74 | cd build/bakefiles |
75 | bakefile_gen -b ../../tests/test.bkl | |
670ec357 VS |
76 | and if you're on a unix system re-run configure. |
77 | ||
78 | 2. Build the test program using one of the make/project files in the tests | |
79 | subdirectory. | |
80 | ||
62d3301b VZ |
81 | 3. Run the test program by using the command 'test' for the console tests, |
82 | 'test_gui' for the gui ones. With no arguments, all the default set of tests | |
83 | (all those registered with CPPUNIT_TEST_SUITE_REGISTRATION) are run. | |
8dae9169 | 84 | Or to list the test suites without running them: |
62d3301b | 85 | test -l or test_gui -l |
670ec357 VS |
86 | |
87 | 4. Tests that have been registered under a name using | |
88 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION can also be run separately. For | |
89 | example: | |
62d3301b VZ |
90 | test_gui ButtonTestCase |
91 | or to list the tests done by a particular testcase: | |
8dae9169 | 92 | test -L MBConvTestCase |
670ec357 | 93 | |
51c432b7 MW |
94 | 5. Fault navigation. |
95 | VC++ users can run the programs as a post build step (Projects/Settings/ | |
96 | Post-build step) to see the test results in an IDE window. This allows | |
97 | errors to be jumped to in the same way as for compiler errors, for | |
98 | example by pressing F4 or highlighting the error and pressing return. | |
99 | ||
100 | Similarly for makefile users: makefiles can be modified to execute the | |
101 | test programs as a final step. Then you can navigate to any errors in the | |
102 | same way as for compiler errors, if your editor supports that. | |
103 | ||
104 | Another alternative is to run the tests manually, redirecting the output | |
105 | to a file. Then use your editor to jump to any failures. Using Vim, for | |
106 | example, ':cf test.log' would take you to the first error in test.log, and | |
107 | ':cn' to the next. | |
108 | ||
109 | If you would like to set a breakpoint on a failing test using a debugger, | |
110 | put the breakpoint on the function 'CppUnit::Asserter::fail()'. This will | |
111 | stop on each failing test. | |
112 | ||
670ec357 VS |
113 | |
114 | IV. Notes | |
115 | --------- | |
116 | ||
117 | 1. You can register your tests (or a subset of them) just under a name, and not | |
118 | in the unnamed registry if you don't want them to be executed by default. | |
119 | ||
8dae9169 VS |
120 | 2. If you are going to register your tests both in the unnamed registry |
121 | and under a name, then use the name that the tests have in the 'test -l' | |
122 | listing. | |
123 | ||
124 | 3. Tests which fail can be temporarily registered under "fixme" while the | |
125 | problems they expose are fixed, instead of the unnamed registry. That | |
126 | way they can easily be run, but they do not make regression testing with | |
127 | the default suite more difficult. E.g.: | |
128 | ||
129 | // register in the unnamed registry so that these tests are run by default | |
130 | //CPPUNIT_TEST_SUITE_REGISTRATION(wxRegExTestCase); | |
131 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestCase, "fixme"); | |
132 | ||
e3778b4d | 133 | // also include in its own registry so that these tests can be run alone |
8dae9169 VS |
134 | CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(wxRegExTestCase, "wxRegExTestCase"); |
135 | ||
136 | 4. Tests which take a long time to execute can be registered under "advanced" | |
137 | instead of the unnamed registry. The default suite should execute reasonably | |
138 | quickly. To run the default and advanced tests together: | |
139 | test "" advanced | |
670ec357 | 140 | |
4f09729d VZ |
141 | |
142 | === EOF === | |
143 | ||
51c432b7 | 144 | Author: VZ & MW |