Authoring a test suite
Test Modules are DLLs, so we need to create a new DLL project. In the 'New Project' Wizard, select 'Win32 Project'. On the following page, choose 'DLL' as application type.
A minimalistic test project could consist of the following code:
#include "stdafx.h" #include <cfix.h> /*++ Routine Description: Test routine -- do the actual testing. --*/ static void __stdcall Test1() { int a = 1; int b = 1; CFIX_ASSERT( a + b == 2 ); } CFIX_BEGIN_FIXTURE( MyMinimalisticFixture ) CFIX_FIXTURE_ENTRY( Test1 ) CFIX_END_FIXTURE()
But let us look at a more interesting example. Open a source file and copy the following code:
// // Always include cfix.h! // #include "stdafx.h" #include <cfix.h> /*++ Routine Description: Setup Routine -- will be called at the very beginning of the testrun. If the setup routine fails, no testcase of this fixture will be executed. If your default calling convention is cdecl (this is the case for Visual Studio projects), be sure to add __stdcall to all routine decarations -- otheriwse you will get the following warning: cannot convert from 'void (__cdecl *)(void)' to 'CFIX_PE_TESTCASE_ROUTINE' As the routine is referenced only by the fixture definition (see below), you may declare this routine as static. --*/ static void __stdcall FixtureSetup() { CFIX_ASSERT( 0 != 1 ); } /*++ Routine Description: Teardown Routine -- will be called at the end of the testrun. --*/ static void __stdcall FixtureTeardown() { CFIX_LOG( L"Tearing down..." ); } /*++ Routine Description: Test routine -- do the actual testing. --*/ static void __stdcall Test1() { DWORD a = 1; DWORD b = 1; CFIX_ASSERT_EQUALS_DWORD( a, b ); CFIX_ASSERT( a + b == 2 ); // // Log a message -- printf-style formatting may be used. // CFIX_LOG( L"a=%d, b=%d", a, b ); } /*++ Routine Description: Another test routine -- one that will trigger a failed assertion. --*/ static void __stdcall Test2() { DWORD a = 17; // // This one will fail. If run in the debugger, it will break here. // if run outside the debugger, the failure will be logged and the // testcase is aborted. // CFIX_ASSERT( a == 42 ); } /*++ Description: These lines define a test fixture. It is best to put this at the end of the file. 'MyFixture' is the name of the fixture. It must be unique across all fixtures of this DLL. The same restrictions as for naming routines apply, i.e. no spaces, no special characters etc. The order of CFIX_FIXTURE_ENTRY, CFIX_FIXTURE_SETUP and CFIX_FIXTURE_TEARDOWN is irrelevant. For the current release, however, (1.0), the order of FIXTURE_ENTRYs defines the execution order. --*/ CFIX_BEGIN_FIXTURE( MyFixture ) // // Define Test1 and Test2 to be test routines. You can define any // number of test routines. // CFIX_FIXTURE_ENTRY( Test1 ) CFIX_FIXTURE_ENTRY( Test2 ) // // Define FixtureSetup to be a setup routine. At most one // CFIX_FIXTURE_SETUP line may be declared per fixture. If the // fixture does not require setup, omit this line. // CFIX_FIXTURE_SETUP( FixtureSetup ) // // Define FixtureTeardown to be a teardown routine. As with // setup routines, you can declare at most one such routine // per fixture. If the fixture does not require teardown, // omit this line. // CFIX_FIXTURE_TEARDOWN( FixtureTeardown ) CFIX_END_FIXTURE() CFIX_BEGIN_FIXTURE( MyOtherFixture ) // // You are free to reuse certain routines in another fixture if // it makes sense. // CFIX_FIXTURE_ENTRY( Test1 ) CFIX_END_FIXTURE()
In order to run the code in the debugger, we have to make some adaptions to the project configuration . Open the project's property page and navigate to the 'Debugging' node. There, add 'cfix32.exe' (or 'cfix64.exe' for the x64 configuration) as Command. Note: do not omit the .exe suffix -- otherwise running without debugger will not work.
As Command Arguments, type -u "$(OutDir)\$(ProjectName).dll". I have used the -u switch in order to break on exceptions. This makes debugging easier, so it is advisable to always use this switch for debugging.
![]() | Note |
---|---|
Do not forget the quotes around the path. |
![]() | Note |
---|---|
When using C++, you shoud use the compiler switch /EHa rather than /EHs. cfix internally uses SEH and using /EHa ensures that your destructors are called properly in case a test case is aborted. |
![]() | Warning |
---|---|
It is strongly recommended to set the Working Directory to $(OutDir) and to use this directory as a conmmon output directory for both your test DLL (i.e. the DLL containing your test cases) and for any (non-system) DLLs referenced by this test DLL. This will make sure that all DLLs will be able to be loaded properly. Please consult the MSDN documentation for details and background information on the Dynamic-Link Library Search Order. |