2 <title>Writing Conformance tests</title>
5 Note: This part of the documentation is still very much a work in
6 progress and is in no way complete.
9 <sect1 id="testing-intro">
10 <title>Introduction</title>
12 With more The Windows API follows no standard, it is itself a defacto
13 standard, and deviations from that standard, even small ones, often
14 cause applications to crash or misbehave in some way. Furthermore
15 a conformance test suite is the most accurate (if not necessarily
16 the most complete) form of API documentation and can be used to
17 supplement the Windows API documentation.
20 Writing a conformance test suite for more than 10000 APIs is no small
21 undertaking. Fortunately it can prove very useful to the development
22 of Wine way before it is complete.
26 The conformance test suite must run on Windows. This is
27 necessary to provide a reasonable way to verify its accuracy.
28 Furthermore the tests must pass successfully on all Windows
29 platforms (tests not relevant to a given platform should be
33 A consequence of this is that the test suite will provide a
34 great way to detect variations in the API between different
35 Windows versions. For instance, this can provide insights
36 into the differences between the, often undocumented, Win9x and
40 However, one must remember that the goal of Wine is to run
41 Windows applications on Linux, not to be a clone of any specific
42 Windows version. So such variations must only be tested for when
43 relevant to that goal.
48 Writing conformance tests is also an easy way to discover
49 bugs in Wine. Of course, before fixing the bugs discovered in
50 this way, one must first make sure that the new tests do pass
51 successfully on at least one Windows 9x and one Windows NT
55 Bugs discovered this way should also be easier to fix. Unlike
56 some mysterious application crashes, when a conformance test
57 fails, the expected behavior and APIs tested for are known thus
58 greatly simplifying the diagnosis.
63 To detect regressions. Simply running the test suite regularly
64 in Wine turns it into a great tool to detect regressions.
65 When a test fails, one immediately knows what was the expected
66 behavior and which APIs are involved. Thus regressions caught
67 this way should be detected earlier, because it is easy to run
68 all tests on a regular basis, and easier to fix because of the
69 reduced diagnosis work.
74 Tests written in advance of the Wine development (possibly even
75 by non Wine developpers) can also simplify the work of the
76 futur implementer by making it easier for him to check the
77 correctness of his code.
82 Conformance tests will also come in handy when testing Wine on
83 new (or not as widely used) architectures such as FreeBSD,
84 Solaris x86 or even non-x86 systems. Even when the port does
85 not involve any significant change in the thread management,
86 exception handling or other low-level aspects of Wine, new
87 architectures can expose subtle bugs that can be hard to
88 diagnose when debugging regular (complex) applications.
96 <sect1 id="testing-what">
97 <title>What to test for?</title>
99 The first thing to test for is the documented behavior of APIs
100 and such as CreateFile. For instance one can create a file using a
101 long pathname, check that the behavior is correct when the file
102 already exists, try to open the file using the corresponding short
103 pathname, convert the filename to Unicode and try to open it using
104 CreateFileW, and all other things which are documented and that
105 applications rely on.
108 While the testing framework is not specifically geared towards this
109 type of tests, it is also possible to test the behavior of Windows
110 messages. To do so, create a window, preferably a hidden one so that
111 it does not steal the focus when running the tests, and send messages
112 to that window or to controls in that window. Then, in the message
113 procedure, check that you receive the expected messages and with the
117 For instance you could create an edit control and use WM_SETTEXT to
118 set its contents, possibly check length restrictions, and verify the
119 results using WM_GETTEXT. Similarly one could create a listbox and
120 check the effect of LB_DELETESTRING on the list's number of items,
121 selected items list, highlighted item, etc.
124 However, undocumented behavior should not be tested for unless there
125 is an application that relies on this behavior, and in that case the
126 test should mention that application, or unless one can strongly
127 expect applications to rely on this behavior, typically APIs that
128 return the required buffer size when the buffer pointer is NULL.
133 <sect1 id="testing-wine">
134 <title>Running the tests in Wine</title>
136 The simplest way to run the tests in Wine is to type 'make test' in
137 the Wine sources top level directory. This will run all the Wine
141 The tests for a specific Wine library are located in a 'tests'
142 directory in that library's directory. Each test is contained in a
143 file (e.g. <filename>dlls/kernel/tests/thread.c</>). Each
144 file itself contains many checks concerning one or more related APIs.
147 So to run all the tests related to a given Wine library, go to the
148 corresponding 'tests' directory and type 'make test'. This will
149 compile the tests, run them, and create an '<replaceable>xxx</>.ok'
150 file for each test that passes successfully. And if you only want to
151 run the tests contained in the <filename>thread.c</> file of the
152 kernel library, you would do:
154 <prompt>$ </>cd dlls/kernel/tests
155 <prompt>$ </>make thread.ok
159 Note that if the test has already been run and is up to date (i.e. if
160 neither the kernel library nor the <filename>thread.c</> file has
161 changed since the <filename>thread.ok</> file was created), then make
162 will say so. To force the test to be re-run, delete the
163 <filename>thread.ok</> file, and run the make command again.
166 You can also run tests manually using a command similar to the
169 <prompt>$ </>../../../tools/runtest -q -M kernel32.dll -p kernel32_test.exe.so thread.c
170 <prompt>$ </>../../../tools/runtest -p kernel32_test.exe.so thread.c
171 thread.c: 86 tests executed, 5 marked as todo, 0 failures.
173 The '-P wine' options defines the platform that is currently being
174 tested. Remove the '-q' option if you want the testing framework
175 to report statistics about the number of successful and failed tests.
176 Run <command>runtest -h</> for more details.
181 <sect1 id="testing-windows">
182 <title>Building and running the tests on Windows</title>
184 <title>Using pre-compiled binaries</title>
186 Unfortunately there are no pre-compiled binaries yet. However if
187 send an email to the Wine development list you can probably get
188 someone to send them to you, and maybe motivate some kind soul to
189 put in place a mechanism for publishing such binaries on a regular
194 <title>With Visual C++</title>
200 Run msvcmaker to generate Visual C++ project files for the tests.
201 'msvcmaker' is a perl script so you may be able to run it on
204 <prompt>$ </>./tools/winapi/msvcmaker --no-wine
208 If the previous steps were done on your Linux development
209 machine, make the Wine sources accessible to the Windows machine
210 on which you are going to compile them. Typically you would do
211 this using Samba but copying them altogether would work too.
214 On the Windows machine, open the <filename>winetest.dsw</>
215 workspace. This will load each test's project. For each test there
216 are two configurations: one compiles the test with the Wine
217 headers, and the other uses the Visual C++ headers. Some tests
218 will compile fine with the former, but most will require the
222 Open the <menuchoice><guimenu>Build</> <guimenu>Batch
223 build...</></> menu and select the tests and build configurations
224 you want to build. Then click on <guibutton>Build</>.
227 To run a specific test from Visual C++, go to
228 <menuchoice><guimenu>Project</> <guimenu>Settings...</></>. There
229 select that test's project and build configuration and go to the
230 <guilabel>Debug</> tab. There type the name of the specific test
231 to run (e.g. 'thread') in the <guilabel>Program arguments</>
232 field. Validate your change by clicking on <guibutton>Ok</> and
233 start the test by clicking the red exclamation mark (or hitting
234 'F5' or any other usual method).
237 You can also run the tests from the command line. You will find
238 them in either <filename>Output\Win32_Wine_Headers</> or
239 <filename>Output\Win32_MSVC_Headers</> depending on the build
240 method. So to run the kernel 'path' tests you would do:
242 <prompt>C:\></>cd dlls\kernel\tests\Output\Win32_MSVC_Headers
243 <prompt>C:\dlls\kernel\tests\Output\Win32_MSVC_Headers></>kernel32_test thread
249 <title>With MinGW</title>
251 This needs to be documented. The best may be to ask on the Wine
252 development mailing list and update this documentation with the
253 result of your inquiry.
257 <title>Cross compiling with MinGW on Linux</title>
259 Here is how to generate Windows executables for the tests straight
260 from the comfort of Linux.
264 First you need to get the MinGW cross-compiler. On Debian all
265 you need to do is type <command>apt-get install mingw32</>.
268 If you had already run <command>configure</>, then delete
269 <filename>config.cache</> and re-run <command>configure</>.
270 You can then run <command>make crosstest</>. To sum up:
272 <prompt>$ </><userinput>rm config.cache</>
273 <prompt>$ </><userinput>./configure</>
274 <prompt>$ </><userinput>make crosstest</>
278 If you get an error when compiling <filename>winsock.h</> then
279 you probably need to apply the following patch:
280 <ulink url="http://www.winehq.com/hypermail/wine-patches/2002/12/0157.html">http://www.winehq.com/hypermail/wine-patches/2002/12/0157.html</>
287 <sect1 id="testing-test">
288 <title>Inside a test</title>
291 When writing new checks you can either modify an existing test file or
292 add a new one. If your tests are related to the tests performed by an
293 existing file, then add them to that file. Otherwise create a new .c
294 file in the tests directory and add that file to the
295 <varname>CTESTS</> variable in <filename>Makefile.in</>.
298 A new test file will look something like the following:
300 #include <wine/test.h>
301 #include <winbase.h>
303 /* Maybe auxiliary functions and definitions here */
307 /* Write your checks there or put them in functions you will call from
314 The test's entry point is the START_TEST section. This is where
315 execution will start. You can put all your tests in that section but
316 it may be better to split related checks in functions you will call
317 from the START_TEST section. The parameter to START_TEST must match
318 the name of the C file. So in the above example the C file would be
319 called <filename>paths.c</>.
322 Tests should start by including the <filename>wine/test.h</> header.
323 This header will provide you access to all the testing framework
324 functions. You can then include the windows header you need, but make
325 sure to not include any Unix or Wine specific header: tests must
328 <!-- FIXME: Can we include windows.h now? We should be able to but currently __WINE__ is defined thus making it impossible. -->
329 <!-- FIXME: Add recommendations about what to print in case of a failure: be informative -->
331 You can use <function>trace</> to print informational messages. Note
332 that these messages will only be printed if 'runtest -v' is being used.
334 trace("testing GlobalAddAtomA");
339 Then just call functions and use <function>ok</> to make sure that
340 they behaved as expected:
342 ATOM atom = GlobalAddAtomA( "foobar" );
343 ok( GlobalFindAtomA( "foobar" ) == atom, "could not find atom foobar" );
344 ok( GlobalFindAtomA( "FOOBAR" ) == atom, "could not find atom FOOBAR" );
346 The first parameter of <function>ok</> is an expression which must
347 evaluate to true if the test was successful. The next parameter is a
348 printf-compatible format string which is displayed in case the test
349 failed, and the following optional parameters depend on the format
353 It is important to display an informative message when a test fails:
354 a good error message will help the Wine developper identify exactly
355 what went wrong without having to add too many other printfs. For
356 instance it may be useful to print the error code if relevant, or the
357 expected value and effective value. In that respect, for some tests
358 you may want to define a macro such as the following:
360 #define eq(received, expected, label, type) \
361 ok((received) == (expected), "%s: got " type " instead of " type, (label),(received),(expected))
365 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
374 <sect1 id="testing-platforms">
375 <title>Handling platform issues</title>
377 Some checks may be written before they pass successfully in Wine.
378 Without some mechanism, such checks would potentially generate
379 hundred of known failures for months each time the tests are being run.
380 This would make it hard to detect new failures caused by a regression.
381 or to detect that a patch fixed a long standing issue.
384 Thus the Wine testing framework has the concept of platforms and
385 groups of checks can be declared as expected to fail on some of them.
386 In the most common case, one would declare a group of tests as
387 expected to fail in Wine. To do so, use the following construct:
390 SetLastError( 0xdeadbeef );
391 ok( GlobalAddAtomA(0) == 0 && GetLastError() == 0xdeadbeef, "failed to add atom 0" );
394 On Windows the above check would be performed normally, but on Wine it
395 would be expected to fail, and not cause the failure of the whole
396 test. However. If that check were to succeed in Wine, it would
397 cause the test to fail, thus making it easy to detect when something
398 has changed that fixes a bug. Also note that todo checks are accounted
399 separately from regular checks so that the testing statistics remain
400 meaningful. Finally, note that todo sections can be nested so that if
401 a test only fails on the cygwin and reactos platforms, one would
410 <!-- FIXME: Would we really have platforms such as reactos, cygwin, freebsd & co? -->
411 But specific platforms should not be nested inside a todo_wine section
412 since that would be redundant.
415 When writing tests you will also encounter differences between Windows
416 9x and Windows NT platforms. Such differences should be treated
417 differently from the platform issues mentioned above. In particular
418 you should remember that the goal of Wine is not to be a clone of any
419 specific Windows version but to run Windows applications on Unix.
422 So, if an API returns a different error code on Windows 9x and
423 Windows NT, your check should just verify that Wine returns one or
426 ok ( GetLastError() == WIN9X_ERROR || GetLastError() == NT_ERROR, ...);
430 If an API is only present on some Windows platforms, then use
431 LoadLibrary and GetProcAddress to check if it is implemented and
432 invoke it. Remember, tests must run on all Windows platforms.
433 Similarly, conformance tests should nor try to correlate the Windows
434 version returned by GetVersion with whether given APIs are
435 implemented or not. Again, the goal of Wine is to run Windows
436 applications (which do not do such checks), and not be a clone of a
437 specific Windows version.
440 FIXME: What about checks that cause the process to crash due to a bug?
445 <!-- FIXME: Strategies for testing threads, testing network stuff,
446 file handling, eq macro... -->
450 <!-- Keep this comment at the end of the file
453 sgml-parent-document:("wine-doc.sgml" "set" "book" "part" "chapter" "")