TESTMAN User's Manual -------------------------------------------------------- TESTMAN 1.1 - copyright 1996 by Jim Langseth To register your copy of TESTMAN send correspondence to: Jim Langseth PO Box 44078 Eden Prairie, MN 55344 Single User: $25 10 User Site License: $200 Comments may be emailed to: jlangseth1@aol.com This document describes the use of TESTMAN with various Microsoft products including Windows NT, Visual C++, and MFC. These products are trademarks of Microsoft Corporation. Neither the registered version of TESTMAN nor the unregistered version are warrantied in any way. The author cannot be held responsible for any consequence related to the use of this software package. -------------------------------------------------------- TESTMAN processes a text file containing test case descriptions and generates a single source file that when compiled exercise your C/C++ code and check conditions you specify. Failures are recorded and are listed in the output of the executable. The purpose of this utility is to allow a C/C++ developer to apply various data and sequence scenarios to software modules that produce quantifiable results. This utility is geared toward non-GUI modules and classes; other software packages are available to test GUI code. The key advantages to the TESTMAN approach are: o Ease of testcase definition o Batch style testing After defining a series of testcases, the driver may be compiled and linked to an executable. Running the executable will apply the testcases and summarize the success or failure. Whenever your code changes, simply recompile, link, and execute to verify the integrity of your work. TESTMAN's batch oriented test execution method does not lend itself well to testing GUI modules since the GUI by definition requires interaction in real/time with the user. Having said this, the author is investigating the idea of integrating a "batch" approach to GUI testing. Comments or suggestions in this regard may be sent to the email address listed above. -------------------------------------------------------- CONTENTS 0.0 System Requirements 1.0 TESTMAN driver definition syntax 1.1 TESTING string 1.2 SETTINGS 1.3 CREATE string 1.4 INCLUDE string 1.5 CHECK_DELTA number 1.6 GLOBAL string 1.7 TEST [testidentifier] [LIKE testidentifier] : ... END 1.7.1 LIKE testidentifier 1.8 DECLARE id AS string 1.9 DO string 1.A CHECK string ... 1.B CLEANUP string [string...] 1.C Comments in the test driver definition 1.D TESTFLAGS - driver run/time customziation 2.0 Test Driver Example - ARRYST.TST -------------------------------------------------------- 0.0 System Requirements TESTMAN was developed and tested under Windows NT, versions 3.51 and 4.0. Although Windows95 was not used, I believe it should also work. Versions are not available for 16 bit Windows, UNIX, or DEC VMS. If demand exists I may port it. -------------------------------------------------------- 1.0 TESTMAN driver definition syntax TESTING string SETTINGS MFC or ANSI optional CREATE string INCLUDE string [INCLUDE str...] optional CHECK_DELTA number optional GLOBAL string [string...] optional TEST [testidentifier] [LIKE testidentifier] : DECLARE id AS string [DECLARE...] optional DO string [string...] optional CHECK string IS string optional CHECK string IS {expression] CHECK string NONE CHECK ... CLEANUP string [string...] optional END [TEST...] optional -------------------------------------------------------- 1.1 TESTING string The TESTING construct requires the user to provide a string describing the module being tested. This string is included in the output of the test executable. Example: TESTING "PROJECT: myproject MODULE: mymodule.cpp" Any string may be used but you should use something that describes specifically what is being tested. 1.2 SETTINGS The SETTINGS construct allows the user to change the target environment for the test driver. Currently, the environment is either ANSI or MFC. Specifying ANSI generates ANSI compatible code. Specifying MFC generates code compatible with Microsoft Visual C++ and the Microsoft Foundation Classes; this includes the use of INT, UINT, BOOL, CString as well as tchar.h. The SETTING construct is optional. The default SETTING is ANSI. Example: SETTING MFC 1.3 CREATE string The CREATE construct requires the user to specify the test driver file name that is generated by TESTMAN. When TESTMAN is invoked, the result is a single file containing the test driver code matching the test cases defined in the input file. Example: CREATE "mymodule_tst.cpp" 1.4 INCLUDE string The INCLUDE construct allows the user the specify files in the test driver. TESTMAN allows none, one, or more INCLUDE constructs in the input file: Example: INCLUDE "" INCLUDE "myincl.hpp" 1.5 CHECK_DELTA number The CHECK_DELTA construct allows the user to specify the amount by which floating point numbers may differ and yet be recognized as equal. Since two "doubles" may be similar in value but deviate by a very small amount due to roundoff, this method allows some leeway when comparing floating point values. The value effects the CHECK construct (see below). Example: CHECK_DELTA 0.00001 Note that the CHECK_DELTA construct is optional with a default value of 0.001. The example changes the value to 1E-005, a value that may be more appropriate for testing some high precision math routines. Also note that in cases where a different delta (or no delta) is required you may simply modify the CHECK construct from CHECK "double_result" IS {other_number} to CHECK "double_result==other_number" IS {TRUE} 1.6 GLOBAL string The GLOBAL construct allows the user to provide global definitions to the test driver. This includes both data definitions as well as global functions and procedures. This construct is optional. Example: GLOBAL "int aflagvalue;" "SOMECLASS *globalobject;" Presumably, one or more testcases will somehow use these values for testing. 1.7 TEST [testidentifier] [LIKE testidentifier] : ... END The TEST construct allows the user to define a single testcase. A testcase may be given a name which is included in any failures detected during test execution. The LIKE construct references a previously defined testcase. The new testcase (currently being defined) inherits characteristics from the earlier testcase. The inherited characteristics may then be overridden in the body of the testcase definition. A test identifier is not required for a testcase. However, including one is useful for two reasons. One, so the test may be referenced later in a LIKE construct. Two, so that if failures occur in the testcase, the test output will include the name of the test making it easier to find the testcase definition when investigating the failure. 1.7.1 LIKE testidentifier The following sections describe the DECLARE, DO, CHECK, and CLEANUP constructs that are used to define a testcase. The LIKE clause causes the new test to inherit the previous testcase characteristics of these constructs. In the sections below you can see that the DECLARE and CHECK constructs may be multiply defined and each has a unique name. The DO and CLEANUP constructs however do not have names and consist of one or more strings. You may selectively override DECLARE and CHECK constructs by referencing the correct name. Overriding the DO and CLEANUP constructs is all-or-nothing. In other words, when specifying a DO construct in a testcase that inherited a DO construct, all inherited strings are lost. 1.8 DECLARE id AS string The DECLARE construct allows the user to declare data (and make functions calls; TESTMAN doesn't care). The key is that each DECLARE construct is named and thus may be selectively overridden in subsequest testcases that inherit. Example: DECLARE iandn AS "int i,n=list.Size();" DECLARE max AS "double max=1.0;" DECLARE str AS "char *str=\"hello world\";" DECLARE calls AS "myfunc(a,b); for(i=0;i arryst 255 would pass the value 255 to the test driver and store in TESTFLAGS. Use TESTFLAGS to customize the sequence of events in during the test execution. For example, in a test driver I used, I wanted to allow interaction with the user: TEST atest: "int param=10;" "if (TESTFLAGS&1) { printf(\"Param? \"); scanf(\"%d\",¶m); }" ... END While the use of TESTFLAGS should probably be limited, it may be useful in some applications. -------------------------------------------------------- 2.0 Test Driver Example - ARRYST.TST The sample test driver (ARRYST.TST) tests the module ARRYST.HPP and ARRYST.CPP. The simple module defines a class that investigates the min, max, and mean of an array of double precision numbers: class ArrayStatistics { private: double minimum; double maximum; double mean; int min_occurred_at; int max_occurred_at; int status; public: ArrayStatistics( double *array, int narray ); int Reset( double *array, int narray ); double Minimum() { return(minimum); } double Maximum() { return(maximum); } double Mean() { return(mean); } int MinOccurredAt() { return(min_occurred_at); } int MaxOccurredAt() { return(max_occurred_at); } int Status() { return(status); } }; There are 7 tests defined in the TESTMAN test driver definition file, ARRYST.TST. Build the test driver file by: C:> testman arryst.tst This creates the file, ARRY_TST.CPP. Compile and link this file along with ARRYST.CPP. The executable will produce the following output: ARRYST.CPP - class ArrayStatistics 7 Test 32 Checks 0 failures There is a build flag "ENABLEBUGS" that you uncomment in ARRYST.CPP to enable a buggy implementation of ArrayStatistics. Recompile, link, and execute the test executable. The output should be: ARRYST.CPP - class ArrayStatistics Test 1 (positive_array), FAIL: stats.Minimum() == sign*1.0 Test 1 (positive_array), FAIL: stats.MinOccurredAt() == 0 Test 2 (negative_array), FAIL: stats.Maximum() == sign*1.0 Test 2 (negative_array), FAIL: stats.MaxOccurredAt() == 0 Test 5 (count_is_1), FAIL: stats.Minimum() == value Test 5 (count_is_1), FAIL: stats.MinOccurredAt() == 0 Test 6 (count_is_1b), FAIL: stats.Maximum() == value Test 6 (count_is_1b), FAIL: stats.MaxOccurredAt() == 0 7 Tests 32 Checks 8 Failures