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:

    int test_case_MY_TC (u_test_case_t *tc)
    {
        // unit test assertions here
        ...
        return U_TEST_SUCCESS;
    err:
        return U_TEST_FAILURE;
    }

    int test_suite_MY_TS_register (u_test_t *t)
    {
        u_test_suite_t *ts;

        u_test_suite_new("MY_TS", &ts);
        u_test_case_register("MY_TC", test_case_MY_TC, ts);

        return u_test_suite_add(ts, t);
    }

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:

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

anonymous enum
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

int u_test_case_add ( u_test_case_t tc,
u_test_suite_t ts 
)

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.

void u_test_case_free ( u_test_case_t tc  ) 

Free resources allocated to the supplied test case (including its dependencies).

Parameters:
tc handler of the test case that shall be disposed
Returns:
nothing

Definition at line 730 of file test.c.

References u_free().

Referenced by u_test_case_new(), u_test_case_register(), and u_test_suite_free().

int u_test_case_new ( const char *  id,
u_test_f  func,
u_test_case_t **  ptc 
)

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.

int u_test_case_register ( const char *  id,
u_test_f  func,
u_test_suite_t ts 
)

Register a new test case named id to its parent test suite ts. The function func, which must match the u_test_f prototype, contains the test code to be executed.

Parameters:
id the name of the new test case
func the unit test function
ts the parent test suite handler
Return values:
0 on success
~0 on failure
See also:
u_test_case_new, u_test_case_add

Definition at line 442 of file test.c.

References u_test_case_add(), u_test_case_free(), and u_test_case_new().

void u_test_free ( u_test_t t  ) 

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 
)

Create a new test named id and return its handler via the result argument pt

Parameters:
id the name of the test
pt handler for the newly created test as a result argument
Return values:
0 on success
~0 on failure

Definition at line 683 of file test.c.

References u_free(), u_malloc(), u_strlcpy(), U_TEST_MAX_PARALLEL, and U_TEST_OUTFN_DFL.

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.

int u_test_set_u_test_rep ( u_test_t t,
u_test_rep_f  func 
)

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.

int u_test_suite_add ( u_test_suite_t ts,
u_test_t t 
)

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.

void u_test_suite_free ( u_test_suite_t ts  ) 

Free resources allocated to the supplied test suite (including its test cases and related dependencies).

Parameters:
ts handler of the test suite that shall be disposed
Returns:
nothing

Definition at line 530 of file test.c.

References u_free(), and u_test_case_free().

Referenced by u_test_free(), and u_test_suite_new().

int u_test_suite_new ( const char *  id,
u_test_suite_t **  pts 
)

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


←Products
© 2005-2012 - KoanLogic S.r.l. - All rights reserved