CUnit(3) | CUnit Programmer's Manual | CUnit(3) |
CUnit - A unit testing framework for C
CUnit is a system for writing, administering, and running unit tests in C. It uses a simple framework for building test structures, and provides a rich set of assertions for testing common data types. CUnit is built as a static library which is linked with the user's testing code.
CUnit is a combination of a platform-independent framework with various user interfaces. The core framework provides basic support for managing a test registry, suites, and test cases. The user interfaces facilitate interaction with the framework to run tests and view results.
The basic hierarchichal organization of CUnit is depicted here:
Test Registry
|
-----------------------------
| |
Suite '1' . . . . Suite 'N'
| |
--------------- ---------------
| | | |
Test '11' ... Test '1M' Test 'N1' ... Test 'NM'
Individual test cases are packaged into suites, which are registered with the active test registry. Suites can have setup and teardown functions which are automatically called before and after running the suite's tests. All suites/tests in the registry may be run using a single function call, or selected suites or tests can be run.
The typical usage of CUnit is:
1. Write functions for tests (and suite init/cleanup if necessary).
2. Initialize the test registry using CU_initialize_registry()
3. Add test suites to the registry using CU_add_suite()
4. Add test cases to the suites using CU_add_test()
6. Cleanup the test registry using CU_cleanup_registry()
All public names in CUnit are prefixed with 'CU_'. This helps minimize clashes with names in user code. Note that earlier versions CUnit used different names without this prefix. The older API names are deprecated but still supported. To use the older names, user code must now be compiled with USE_DEPRECATED_CUNIT_NAMES defined.
A "test" is a C function having the signature: void test_func(void). There are no restrictions on the content of a test function, except that it should not modify the CUnit framework (e.g. add suites or tests, modify the test registry, or initiate a test run). A test function may call other functions (which also may not modify the framework). Registering a test will cause it's function to be run when the test is run.
CUnit provides a set of assertions for testing logical conditions. The success or failure of these assertions is tracked by the framework, and can be viewed when a test run is complete. Each assertion tests a single logical condition, and fails if the condition evaluates to CU_FALSE. Upon failure, the test continues unless the user chooses the 'xxx_FATAL' version of an assertion. In that case, the test function returns immediately.
CUnit provides a set of assertions for testing logical conditions. The success or failure of these assertions is tracked by the framework, and can be viewed when a test run is complete.
Each assertion tests a single logical condition, and fails if the condition evaluates to CU_FALSE. Upon failure, the test function continues unless the user chooses the 'xxx_FATAL' version of an assertion. In that case, the test function is aborted and returns immediately. FATAL versions of assertions should be used with caution! There is no opportunity for the test function to clean up after itself once a FATAL assertion fails. The normal suite cleanup function is not affected, however.
There are also special "assertions" for registering a pass or fail with the framework without performing a logical test. These are useful for testing flow of control or other conditions not requiring a logical test.
Other functions called by a registered test function may use the CUnit assertions freely. These assertions will be counted for the calling function. They may also use FATAL versions of assertions - failure will abort the original test function and its entire call chain.
The assertions defined by CUnit are:
#include <CUnit/CUnit.h>
CU_ASSERT(int expression)
CU_ASSERT_FATAL(int expression)
CU_TEST(int expression)
CU_TEST_FATAL(int expression)
CU_ASSERT_TRUE(value)
CU_ASSERT_TRUE_FATAL(value)
CU_ASSERT_FALSE(value)
CU_ASSERT_FALSE_FATAL(value)
CU_ASSERT_EQUAL(actual, expected)
CU_ASSERT_EQUAL_FATAL(actual, expected)
CU_ASSERT_NOT_EQUAL(actual, expected)
CU_ASSERT_NOT_EQUAL_FATAL(actual, expected)
CU_ASSERT_PTR_EQUAL(actual, expected)
CU_ASSERT_PTR_EQUAL_FATAL(actual, expected)
CU_ASSERT_PTR_NOT_EQUAL(actual, expected)
CU_ASSERT_PTR_NOT_EQUAL_FATAL(actual, expected)
CU_ASSERT_PTR_NULL(value)
CU_ASSERT_PTR_NULL_FATAL(value)
CU_ASSERT_PTR_NOT_NULL(value)
CU_ASSERT_PTR_NOT_NULL_FATAL(value)
CU_ASSERT_STRING_EQUAL(actual, expected)
CU_ASSERT_STRING_EQUAL_FATAL(actual, expected)
CU_ASSERT_STRING_NOT_EQUAL(actual, expected)
CU_ASSERT_STRING_NOT_EQUAL_FATAL(actual, expected)
CU_ASSERT_NSTRING_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_EQUAL_FATAL(actual, expected, count)
CU_ASSERT_NSTRING_NOT_EQUAL(actual, expected, count)
CU_ASSERT_NSTRING_NOT_EQUAL_FATAL(actual, expected, count)
CU_ASSERT_DOUBLE_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_EQUAL_FATAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_NOT_EQUAL(actual, expected, granularity)
CU_ASSERT_DOUBLE_NOT_EQUAL_FATAL(actual, expected, granularity)
CU_PASS(message)
CU_FAIL(message)
CU_FAIL_FATAL(message)
The test registry is the repository for suites and associated tests. The user normally only needs to initialize the registry before use and clean up afterwards. However, other functions are provided to manipulate the registry when necessary.
The main functions needed by clients are:
#include <CUnit/TestDB.h> (included automatically by <CUnit/CUnit.h>)
Other registry functions are primarily for internal and testing purposes. However, general users may find use for them and should be aware of them. These include:
In order for a test to be run by CUnit, it must be added to a test collection (suite) which is registered with the test registry.
The first step in setting up a test system is creating and registering one or more test collections (suites). Each suite has a name which may be used to reference the suite. Therefore, it is recommended (but not required) that each registered suite have a unique name. The current implementation does not support the creation of suites independent of the test registry. Suites are simultaneously created and added to the active registry as follows.
#include <CUnit/TestDB.h> (included automatically by <CUnit/CUnit.h>)
Tests are created and added to suites. Each test has a name which may be used to reference the test later. Therefore, it is recommended (but not required) that the name be unique among all tests added to a single suite. The current implementation does not support the creation of tests independent of registered suites. Tests are simultaneously created and added to a suite as follows.
#include <CUnit/TestDB.h> (included automatically by <CUnit/CUnit.h>)
A suite or test must be active to be executed during a test run (all suites and tests are active by default upon creation). The active state of a suite or test is available as pSuite->fActive and pTest->fActive, respectively. The flag will be CU_TRUE when the entity is active, CU_FALSE otherwise. Use the following functions to selectively deactivate suites and tests to choose subsets of tests to run dynamically. Note that it is a framework error to deactivate a test or suite and then specifically request that it be run.
#include <CUnit/TestDB.h> (included automatically by <CUnit/CUnit.h>)
Normally the attributes of suites and tests are set at creation time. In some cases, a client may wish to manipulate these to modify the test structure dynamically. The following functions are provided for this purpose, and should be used instead of directly setting the value of the data structure members. All return CUE_SUCCESS on success, and the indicated error code on failure.
In most cases, clients will have references to registered suites and tests as pointers returned from CU_add_suite() and CU_add_test(). Occassionally, a client may need to be able to retrieve a reference to a suite or test. The following functions are provided to assist clients with this when the client has some information about the entity (name or order of registration). In cases where nothing is known about the suite or test, the client will need to iterate the internal data structures to enumerate the suites and tests. This is not directly supported in the client API.
CUnit supports running all tests in all registered suites, but individual tests or suites can also be run. During each run, the framework keeps track of the number of suites, tests, and assertions run, passed, and failed. Note that the previous results are cleared each time a test run is initiated (even if it fails).
While CUnit provides primitive functions for running suites and tests, most users will want to use one of the user interfaces. These interfaces handle the details of interaction with the framework and provide output of test details and results for the user. For more about the primitive functions, see <CUnit/testRun.h>.
The interfaces present results of test runs, but client code may sometimes need to access the results directly. These results include various run counts, as well as a linked list of failure records holding the failure details. Test results must be retrieved before attempting to run other tests, which resets the result information. Functions for accessing the test results are:
#include <CUnit/TestRun.h> (included automatically by <CUnit/CUnit.h>)
The automated interface is non-interactive. The current implementation only supports running all registered suites. Results are output to an xml file to be viewed by appropriate external tools. Registered tests can also be listed to an xml file for viewing. The following public functions are available:
#include <CUnit/Automated.h>
The basic interface is also non-interactive, with results output to stdout. This interface supports running individual suites or tests, and allows client code to control the type of output displayed during each run. This interface provides the most flexibility to clients desiring simplified access to the CUnit API. The following public functions are provided:
#include <CUnit/Basic.h>
The console interface is interactive. All the client needs to do is initiate the console session, and the user controls the test run interactively. This include selection & running of suites and tests, and viewing test results.
#include <CUnit/Console.h>
The curses interface is interactive. All the client needs to do is initiate the curses session, and the user controls the test run interactively. This include selection & running of suites and tests, and viewing test results. Use of this interface requires linking the ncurses library into the application.
#include <CUnit/CUCurses.h>
Many CUnit functions set a framework error code when an exception occurs. The error codes are an enum named CU_ErrorCode declared in header file <CUnit/CUError.h> (included automatically by <CUnit/CUnit.h> ). The following functions are provided for retrieving the framework error status:
#include <CUnit/CUError.h> (included automatically by <CUnit/CUnit.h>)
By default, CUnit continues running tests when a framework error occurs. In this context, failed assertions are not considered "framework errors". All other error conditions including suite initialization or cleanup failures, inactive suites or tests which are run explicitly, etc. are included. This 'error action' can be changed by the user if desired. The following functions are provided:
#include <CUnit/CUError.h> (included automatically by <CUnit/CUnit.h>)
The error actions are defined in enum CU_ErrorAction in header file <CUnit/CUError.h> (included automatically by <CUnit/CUnit.h> ) as follows:
Anil Kumar <anilsaharan@users.sourceforge.net>
Jerry St.Clair <jds2@users.sourceforge.net>
http://cunit.sourceforge.net
August 2004 | CUnit-2.0-1 |