Defines | |
#define | PRECISION(a) TEST::precision = (a); |
Define the precision for floating point comparisons. | |
#define | START_TEST(class_name, version) |
Create the test header for a certain class. | |
#define | END_TEST |
Termination of test program. | |
#define | CHECK(test_name) |
Declare subtest name. | |
#define | STATUS(message) |
Print a status message. | |
#define | RESULT |
Check subtest result. | |
#define | NEW_TMP_FILE(filename) |
Create a temporary filename. | |
#define | TEST_REAL_EQUAL(a, b) |
Floating point equality macro. | |
#define | TEST_EQUAL(a, b) |
Generic equality macro. | |
#define | TEST_NOT_EQUAL(a, b) |
Generic inequality macro. | |
#define | TEST_EXCEPTION(exception_type, command) |
Exception test macro. | |
#define | ABORT_IF(condition) if (condition) break; |
Skip remainder of subtest. | |
#define | TEST_FILE(filename, templatename) |
File comparison macro. | |
#define | TEST_FILE_REGEXP(filename, templatename) |
Regular expression file comparison macro. | |
#define | CAPTURE_OUTPUT_LEVEL(level) |
Redirect output to the global logging facility. | |
#define | CAPTURE_OUTPUT_LEVEL_RANGE(minlevel, maxlevel) |
Redirect output to the global logging facility. | |
#define | COMPARE_OUTPUT(text) |
Compare output made to the global logging facility. |
The testprograms reside in the directory source/TEST, they may be built and executed by calling make test.
Each test program prints after execution either "PASSED" or "FAILED". If any of the subtest contained in the test program fails, the whole test failed. The result of the test program can also be checked via its exit code. An exit code of zero means "PASSED", non-zero exit code means "FAILED".
There are several macros defined to simplify the creation of a test program and to provide a common interface. Each test program consists of several subtests which usually test one method or property of the class. Each of this subtests uses a series of elementary tests to check the functionality of the method.
A number of elementary tests has been implemented that is sufficient for most cases:
To create a new test program, use the file source/TEST/Skeleton_test.C
|
Skip remainder of subtest. If the condition is not fulfilled, the remainder of the test is skipped. The status (whether it fails or passes) remains unchanged. |
|
Value: {\ std::ostrstream TEST_strstr;\ Log.remove(std::cout);\ Log.remove(std::cerr);\ Log.insert(TEST_strstr, level, level);
This macro (together with COMPARE_OUTPUT ) can be used to ensure that a function prints an error message to the global logging facility Log . It disables the output to |
|
Value: {\ std::ostrstream TEST_strstr;\ Log.remove(std::cout);\ Log.remove(std::cerr);\ Log.insert(TEST_strstr, minlevel, maxlevel);
This macro (together with COMPARE_OUTPUT ) can be used to ensure that a function prints an error message to the global logging facility Log . It disables the output to |
|
Value: TEST::test = true;\ TEST::newline = false;\ if (TEST::verbose > 0)\ std::cout << "checking " << #test_name << "... " << std::flush;\ try\ {\ while (true)\ {\ This macro is used to declare the name of a subtest. If you want to check e.g. the setName method of a class, insert a line
|
|
Value: Log.remove(TEST_strstr);\ Log.insert(std::cout, LogStream::INFORMATION_LEVEL, LogStream::ERROR_LEVEL - 1);\ Log.insert(std::cerr, LogStream::ERROR_LEVEL);\ TEST::this_test = (::strncmp(TEST_strstr.str(), text, TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0) == 0);\ TEST::test = TEST::test && TEST::this_test;\ \ if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\ {\ /* reserve space for the null-terminated content of the strstrem */\ char* TEST_strstr_contents = new char[TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0 + 1];\ ::strncpy(TEST_strstr_contents, TEST_strstr.str(), TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0);\ TEST_strstr_contents[TEST_strstr.str()!=0?strlen(TEST_strstr.str()):0] = '\0';\ \ if (!TEST::newline)\ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " (line " << __LINE__ << " COMPARE_OUTPUT(" << #text << "): got '" << (TEST_strstr_contents) << "', expected '" << (text) << "') ";\ if (TEST::this_test)\ std::cout << " + " << std::endl;\ else \ std::cout << " - " << std::endl;\ delete [] TEST_strstr_contents;\ }\ }
|
|
Termination of test program.
This macro implements the correct termination of the test program and should therefore be the last macro to call. It determines the exit code based on all previously run subtests and prints out the message "PASSED" or "FAILED". This macro also closes the global |
|
Value: ::File::createTemporaryFilename(filename);\ TEST::tmp_file_list.push_back(filename);\ if (TEST::verbose > 1)\ {\ if (!TEST::newline) \ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " creating new temporary file '" << filename << "' (line " << __LINE__ << ")" << std::endl;\ }\ This macro assigns a new temporary filename to the string variable given as its argument. The filename is created using File::createTemporaryFilename . All temporary files are deleted if END_TEST is called.
|
|
Define the precision for floating point comparisons. The macro TEST_REAL_EQUAL checks whether the floating point number returned by the subtest is close to the expected result by comparing the absolute value of the difference of the two values to PRECISION.
|
|
Check subtest result. Each elementary test macro updates an internal variable (TEST, defined by START_TEST ) that holds the state of the current subtest.
|
|
Create the test header for a certain class. This macro defines the start of the test program for a given classname. The classname is printed together with some information when calling the test program with any arguments (except for #-v# or #-V#).
|
|
Value: if (TEST::verbose > 1)\ {\ if (!TEST::newline) \ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " status (line " << __LINE__ << "): " << message << std::endl;\ }\
If tests require longer preparations,
|
|
Value: {\ TEST::this_test = ((a) == (b));\ TEST::test = TEST::test && TEST::this_test;\ if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\ {\ if (!TEST::newline)\ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " (line " << __LINE__ << " TEST_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\ if (TEST::this_test)\ std::cout << " + " << std::endl;\ else \ std::cout << " - " << std::endl;\ }\ }\ This macro uses the operator == to check its two arguments for equality. Besides handling some internal stuff, it basically evaluates #((a) == (b))#.
|
|
Exception test macro. This macro checks if a given type of exception occured while executing the given command. Example:
|
|
File comparison macro.
This macro is used to test file operations. It compares the file with name
|
|
Regular expression file comparison macro.
This macro is used to test file operations. It compares the file with name |
|
Value: {\ TEST::this_test = !((a) == (b));\ TEST::test = TEST::test && TEST::this_test;\ if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\ {\ if (!TEST::newline)\ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " (line " << __LINE__ << " TEST_NOT_EQUAL(" << #a << ", " << #b << "): got " << (a) << ", forbidden is " << (b) << ") ";\ if (TEST::this_test)\ std::cout << " + " << std::endl;\ else \ std::cout << " - " << std::endl;\ }\ }\ This macro checks for inequality as TEST_EQUAL tests for equality. The only difference between the two macros is that TEST_NOT_EQUAL evaluates #!((a) == (b))#.
|
|
Value: TEST::this_test = BALL_REAL_EQUAL((a), (b), TEST::precision); \ TEST::test = TEST::test && TEST::this_test;\ if ((TEST::verbose > 1) || (!TEST::this_test && (TEST::verbose > 0)))\ {\ if (!TEST::newline)\ {\ TEST::newline = true;\ std::cout << std::endl;\ }\ std::cout << " (line " << __LINE__ << " TEST_REAL_EQUAL("<< #a << ", " << #b << "): got " << (a) << ", expected " << (b) << ") ";\ if (TEST::this_test)\ std::cout << " + " << std::endl;\ else \ std::cout << " - " << std::endl;\ }\ Checks whether the absolute value of the difference of the two floating point values a and b is less or equal to the value defined by PRECISION .
|