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().