testutil

The testutil package is a test framework that provides facilities for specifying test cases and recording test results.

You would use it to build regression tests for your library.

Description

A package may optionally contain a set of test cases. Test cases are not normally compiled and linked when a package is built; they are only included when the “test” identity is specified. All of a package’s test code goes in its src/test directory. For example, the nffs package’s test code is located in the following directory:

* fs/nffs/src/test/

This directory contains the source and header files that implement the nffs test code.

The test code has access to all the header files in the following directories:

* src
* src/arch/<target-arch>
* include
* src/test
* src/test/arch/<target-arch>
* include directories of all package dependencies

Package test code typically depends on the testutil package, described later in this document.

Some test cases or test initialization code may be platform-specific. In such cases, the platform-specific function definitions are placed in arch subdirectories within the package test directory.

While building the test code (i.e., when the test identity is specified), the newt tool defines the TEST macro. This macro is defined during compilation of all C source files in all projects and packages.

Tests are structured according to the following hierarchy:

           [test]
          /      \
   [suite]        [suite]
  /       \      /       \
[case] [case]  [case] [case]

I.e., a test consists of test suites, and a test suite consists of test cases.

The test code uses testutil to define test suites and test cases.

Regression test can then be executed using ‘newt target test’ command, or by including a call to your test suite from project/test/src/test.c.

Example

This Tutorial shows how to create a test suite for a Mynewt package.

Data structures

struct tu_config {
    int tc_print_results;
    int tc_system_assert;

    tu_case_init_fn_t *tc_case_init_cb;
    void *tc_case_init_arg;

    tu_case_report_fn_t *tc_case_fail_cb;
    void *tc_case_fail_arg;

    tu_case_report_fn_t *tc_case_pass_cb;
    void *tc_case_pass_arg;

    tu_suite_init_fn_t *tc_suite_init_cb;
    void *tc_suite_init_arg;

    tu_restart_fn_t *tc_restart_cb;
    void *tc_restart_arg;
};
extern struct tu_config tu_config;

The global tu_config struct contains all the testutil package’s settings. This should be populated before tu_init() is called.

API

typedef void tu_case_report_fn_t(char *msg, void *arg)
typedef void tu_suite_restart_fn_t(void *arg)
typedef void tu_init_test_fn_t(void *arg)
typedef void tu_pre_test_fn_t(void *arg)
typedef void tu_post_test_fn_t(void *arg)
typedef void tu_testsuite_fn_t(void)
struct ts_testsuite_list g_ts_suites
struct tc_config tc_config
struct tc_config* tc_current_config
struct ts_config ts_config
struct ts_config* ts_current_config
const char* tu_suite_name
const char* tu_case_name
int tu_any_failed
int tu_suite_failed
int tu_case_reported
int tu_case_failed
int tu_case_idx
jmp_buf tu_case_jb
void tu_suite_set_init_cb(tu_init_test_fn_t * cb, void * cb_arg)
void tu_suite_set_complete_cb(tu_init_test_fn_t * cb, void * cb_arg)
void tu_suite_set_pre_test_cb(tu_pre_test_fn_t * cb, void * cb_arg)
void tu_suite_set_post_test_cb(tu_post_test_fn_t * cb, void * cb_arg)
void tu_suite_set_pass_cb(tu_case_report_fn_t * cb, void * cb_arg)
void tu_suite_set_fail_cb(tu_case_report_fn_t * cb, void * cb_arg)
void tu_suite_init(const char * name)
void tu_suite_pre_test(void)
void tu_suite_post_test(void)
void tu_suite_complete(void)
int tu_suite_register(tu_testsuite_fn_t * ts, const char * name)
SLIST_HEAD(ts_testsuite_list, ts_suite)
void tu_restart(void)
void tu_start_os(const char * test_task_name, os_task_func_t test_task_handler)
void tu_case_set_init_cb(tu_init_test_fn_t * cb, void * cb_arg)
void tu_case_set_pre_cb(tu_pre_test_fn_t * cb, void * cb_arg)
void tu_case_set_post_cb(tu_post_test_fn_t * cb, void * cb_arg)
void tu_case_init(const char * name)
void tu_case_complete(void)
void tu_case_pass(void)
void tu_case_fail(void)
void tu_case_fail_assert(int fatal, const char * file, int line, const char * expr, const char * format, ...)
void tu_case_write_pass_auto(void)
void tu_case_pass_manual(const char * file, int line, const char * format, ...)
void tu_case_pre_test(void)
void tu_case_post_test(void)
TEST_SUITE_DECL(suite_name)
TEST_SUITE_REGISTER(suite_name)
TEST_SUITE(suite_name)
TEST_CASE_DECL(case_name)
TEST_CASE_DEFN(case_name, body)
TEST_CASE(case_name)

Defines a test case that runs without the OS.

TEST_CASE_TASK(case_name)

Defines a test case that runs in a task in the OS.

FIRST_AUX(first, ...)
FIRST(...)
NUM(...)
ARG10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, ...)
REST_OR_0(...)
REST_OR_0_AUX(qty, ...)
REST_OR_0_AUX_INNER(qty, ...)
REST_OR_0_AUX_1(first)
REST_OR_0_AUX_N(first, ...)
XSTR(s)
STR(s)
TEST_ASSERT_FULL(fatal, expr, ...)
TEST_ASSERT(...)
TEST_ASSERT_FATAL(...)
TEST_PASS(...)
ASSERT_IF_TEST(expr)