Unit testing
Overview
The Unit testing module offers a set of interfaces by means of which a programmer can organise its own software validation suite. Basically you define a test suite, which in turn comprises a set of test cases (aka unit tests), and recall it in the main test program. Each test case is associated to a u_test_f routine which takes its own u_test_case_t reference as argument and is requested to return U_TEST_SUCCESS in case the unit test succeeds and U_TEST_FAILURE otherwise. A test case is attached to its "mother" test suite with the u_test_case_register function. On the other hand, a test suite is attached to the main test program with the u_test_suite_add function, as shown in the following example:
To build the main test program (let's call it runtest) you define a main function like the one in the example below, import your test suite invoking the test suites' register functions, and then call the u_test_run function to execute the tests:
int main (int argc, char *argv[])
{
u_test_t *t = NULL;
u_test_new("MY_TESTS", &t);
test_suite_MY_TS_register(t);
return u_test_run(argc, argv, t)
}
The runtest program has a number of built-in command line options to tweak some test execution features, the most important of which are:
-f to specify a format for the test report file: txt or xml
-o to pass a specific name other than the default as report file
-s to force serialization in unit tests' execution (instead of the default which is to parallelize as much as possible). This option (which could be useful when trying to analize a test bug) also turns off the sandboxing mechanism by which tests are executed in safe, isolated bubbles.
An xsl file file - together with its twin css - is provided in contrib/ as an example to automatically build an HTML report page from the xml report file. Let runtest produce an xml ouput and supply it to xsltproc together with the xsl template:
$ ./runtest -f xml -o my_test_report.xml
$ xstlproc test_report.xsl my_test_report.xml
A single html file is produced which gets its style definitions from the test_report.css file (which must be in the same directory).
If in doubt, or in search for inspiration, take a look at LibU test/ directory.
Defines |
|
#define | u_test_err_if(a) do { if (a) { u_test_case_printf(tc, "%s", #a); goto err; } } while (0) |
| | Carpal-like msg_err_if macro.
|
|
#define | u_test_err_ifm(a,...) do { if (a) { u_test_case_printf(tc, __VA_ARGS__); goto err; } } while (0) |
| | Carpal-like msg_err_ifm macro.
|
|
#define | U_TEST_MAX_PARALLEL 32 |
| | Maximum number of running test cases.
|
|
#define | U_TEST_ID_MAX 128 |
| | Maximum length of a test suite/case identifier.
|
|
#define | U_TEST_OUTFN_DFL "./unitest-report.out" |
| | Default test report file name.
|
Typedefs |
|
typedef struct u_test_case_s | u_test_case_t |
| | Test case handler.
|
|
typedef struct u_test_suite_s | u_test_suite_t |
| | Test suite handler.
|
|
typedef struct u_test_s | u_test_t |
| | Test handler.
|
|
typedef int(* | u_test_f )(u_test_case_t *) |
| | Unit test function prototype.
|
|
typedef int(* | u_test_rep_f )(FILE *, u_test_t *, u_test_rep_tag_t) |
| | Report functions' prototypes.
|
Enumerations |
| enum | { U_TEST_SUCCESS = 0,
U_TEST_FAILURE = 1,
U_TEST_ABORTED = 2,
U_TEST_SKIPPED = 3
} |
| | Exit status of unit tests.
More...
|
| enum | u_test_rep_tag_t |
| | Tags used to tell if the reporter routine has been called on element opening or closure.
|
Functions |
| int | u_test_case_new (const char *id, u_test_f func, u_test_case_t **ptc) |
| | Create a new test case.
|
| int | u_test_case_add (u_test_case_t *tc, u_test_suite_t *ts) |
| | Add a test case to its parent test suite.
|
| void | u_test_case_free (u_test_case_t *tc) |
| | Free resources allocated to a test case.
|
| int | u_test_case_register (const char *id, u_test_f func, u_test_suite_t *ts) |
| | Create and register a new test case.
|
| int | u_test_case_dep_register (const char *id, u_test_case_t *tc) |
| | Register a dependency for the given test case.
|
| int | u_test_case_depends_on (const char *tcid, const char *depid, u_test_suite_t *ts) |
| | An alternative way to describe dependencies between test cases.
|
| int | u_test_case_printf (u_test_case_t *tc, const char *fmt,...) |
| | printf-like function to be called from inside the test case function
|
| int | u_test_suite_add (u_test_suite_t *ts, u_test_t *t) |
| | Add a test suite to its parent test.
|
| void | u_test_suite_free (u_test_suite_t *ts) |
| | Free resources allocated to a test suite.
|
| int | u_test_suite_new (const char *id, u_test_suite_t **pts) |
| | Create a new test suite.
|
| int | u_test_suite_dep_register (const char *id, u_test_suite_t *ts) |
| | Register a dependency for the given test suite.
|
| int | u_test_suite_depends_on (const char *tsid, const char *depid, u_test_t *t) |
| | An alternative way to describe dependencies between test suites.
|
| int | u_test_new (const char *id, u_test_t **pt) |
| | Create a new test.
|
| int | u_test_set_outfn (u_test_t *t, const char *outfn) |
| | Set the output file name for the test report.
|
| int | u_test_set_u_test_suite_rep (u_test_t *t, u_test_suite_rep_f func) |
| | Set a custom test suite reporter function.
|
| int | u_test_set_u_test_case_rep (u_test_t *t, u_test_case_rep_f func) |
| | Set a custom test case reporter function.
|
| int | u_test_set_u_test_rep (u_test_t *t, u_test_rep_f func) |
| | Set a custom test reporter function.
|
| void | u_test_free (u_test_t *t) |
| | Free resources allocated to a test.
|
| int | u_test_run (int ac, char *av[], u_test_t *t) |
| | Run tests.
|
Enumeration Type Documentation
- Enumerator:
| U_TEST_SUCCESS |
All test assertions got right.
|
| U_TEST_FAILURE |
Any test assertion has failed.
|
| U_TEST_ABORTED |
Catch any non-regular execution condition (e.g. SIGSEGV).
|
| U_TEST_SKIPPED |
A previous dependency failure prevents test execution.
|
Definition at line 41 of file test.h.
Function Documentation
Add the test case referenced by tc to the test suite ts.
- Parameters:
-
| tc | a test case handler |
| ts | its parent test suite |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 793 of file test.c.
Referenced by u_test_case_register().
| int u_test_case_dep_register |
( |
const char * |
id, |
|
|
u_test_case_t * |
tc | |
|
) |
| | |
Add the test case named id as a dependency for the test case ts
- Parameters:
-
| id | the id of an already u_test_case_add'ed test case |
| tc | handler of the current test case |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 413 of file test.c.
| int u_test_case_depends_on |
( |
const char * |
tcid, |
|
|
const char * |
depid, |
|
|
u_test_suite_t * |
ts | |
|
) |
| | |
Add the test case named depid as a dependency for the test case named tcid in the context of the ts test suite.
- Parameters:
-
| tcid | a test case identified by its name |
| depid | name of the test case on which tcid depends on |
| ts | The parent test suite handler |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
- See also:
- u_test_case_dep_register
Definition at line 376 of file test.c.
Create a new test case named id with func as its unit test procedure, and return its handler via the result argument ptc. The function must match the u_test_f prototype.
- Parameters:
-
| id | the name of the new test case |
| func | the unit test function |
| ptc | the parent test suite handler |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 758 of file test.c.
References u_malloc(), and u_test_case_free().
Referenced by u_test_case_register().
| int u_test_case_printf |
( |
u_test_case_t * |
tc, |
|
|
const char * |
fmt, |
|
|
|
... | |
|
) |
| | |
A printf-like function to be called from inside the test case function
- Parameters:
-
| tc | the test case handler |
| fmt | printf-like format string |
| ... | variable number of arguments that feed fmt |
- Returns:
- the number of characters printed (not including the trailing NUL) or a negative value if an output error occurs
Definition at line 467 of file test.c.
Free resources allocated to the supplied test (including its test suites, test cases and attached dependencies).
- Parameters:
-
| t | handler of the test that shall be disposed |
- Returns:
- nothing
Definition at line 563 of file test.c.
References u_free(), and u_test_suite_free().
| int u_test_new |
( |
const char * |
id, |
|
|
u_test_t ** |
pt | |
|
) |
| | |
| int u_test_run |
( |
int |
ac, |
|
|
char * |
av[], |
|
|
u_test_t * |
t | |
|
) |
| | |
Run tests. It shall be called by the main() function and will return when all tests have been executed or an error occurred.
- Parameters:
-
| ac | main's argc argument |
| av | main's argv argument |
| t | an u_test_t object handler |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 319 of file test.c.
| int u_test_set_outfn |
( |
u_test_t * |
t, |
|
|
const char * |
outfn | |
|
) |
| | |
Set the output file name for the test report to outfn
- Parameters:
-
| t | a test handler |
| outfn | file path name |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 661 of file test.c.
References u_strlcpy().
| int u_test_set_u_test_case_rep |
( |
u_test_t * |
t, |
|
|
u_test_case_rep_f |
func | |
|
) |
| | |
Set func as the test case reporter function for the given test t. The supplied function must match the u_test_case_rep_f prototype.
- Parameters:
-
| t | handler for the test |
| func | the custom test case reporter function |
- Return values:
-
| 0 | on success |
| ~0 | on failure (i.e. a NULL parameter was supplied) |
Definition at line 618 of file test.c.
Set func as the reporter function for the given test t. The supplied function must match the u_test_rep_f prototype.
- Parameters:
-
| t | handler for the test |
| func | the custom reporter function |
- Return values:
-
| 0 | on success |
| ~0 | on failure (i.e. a NULL parameter was supplied) |
Definition at line 596 of file test.c.
| int u_test_set_u_test_suite_rep |
( |
u_test_t * |
t, |
|
|
u_test_suite_rep_f |
func | |
|
) |
| | |
Set func as the test suite reporter function for the given test t. The supplied function must match the u_test_suite_rep_f prototype.
- Parameters:
-
| t | handler for the test |
| func | the custom test suite reporter function |
- Return values:
-
| 0 | on success |
| ~0 | on failure (i.e. a NULL parameter was supplied) |
Definition at line 640 of file test.c.
Add the test suite referenced by ts to the test t.
- Parameters:
-
| ts | a test suite handler |
| t | its parent test |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 816 of file test.c.
| int u_test_suite_dep_register |
( |
const char * |
id, |
|
|
u_test_suite_t * |
ts | |
|
) |
| | |
Add the test suite named id as a dependency for the test suite ts
- Parameters:
-
| id | the id of an already u_test_suite_add'ed test suite |
| ts | handler of the current test suite |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 348 of file test.c.
| int u_test_suite_depends_on |
( |
const char * |
tsid, |
|
|
const char * |
depid, |
|
|
u_test_t * |
t | |
|
) |
| | |
Add the test suite named depid as a dependency for the test suite named tsid in the context of the t test.
- Parameters:
-
| tsid | a test suite identified by its name |
| depid | name of the test suite on which tsid depends on |
| t | The parent test handler |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
- See also:
- u_test_suite_dep_register
Definition at line 397 of file test.c.
Create a new test suite named id and return its handler as a result argument
- Parameters:
-
| id | the name of the new test suite |
| pts | test suite handler as a result argument |
- Return values:
-
| 0 | on success |
| ~0 | on failure |
Definition at line 498 of file test.c.
References u_malloc(), and u_test_suite_free().