Contiki-NG
Loading...
Searching...
No Matches
unit-test.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010, Swedish Institute of Computer Science
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30/**
31 * \file
32 * A tool for unit testing Contiki-NG software.
33 * \author
34 * Nicolas Tsiftes <nicolas.tsiftes@ri.se>
35 */
36
37#ifndef UNIT_TEST_H
38#define UNIT_TEST_H
39
40#include <stdbool.h>
41#include <stdint.h>
42
43#include <sys/clock.h>
44
45/**
46 * The unit_test structure describes the results of a unit test. Each
47 * registered unit test statically allocates an object of this type.
48 */
49typedef struct unit_test {
50 const char * const descr;
51 const char * const test_file;
52 uint32_t assertions;
53 bool passed;
54 unsigned exit_line;
55 clock_time_t start;
56 clock_time_t end;
58
59typedef void (*unit_test_report_function_t)(const unit_test_t *);
60
61/**
62 * Register a unit test.
63 *
64 * This macro allocates unit test descriptor, which is a structure of
65 * type unit_test_t. The descriptor contains information about a unit
66 * test, and the results from the last execution of the test.
67 *
68 * \param name The name of the unit test.
69 * \param description A string that briefly describes the unit test.
70 */
71#define UNIT_TEST_REGISTER(name, description) \
72 static unit_test_t unit_test_##name = \
73 {.descr = (description), \
74 .test_file = __FILE__, \
75 .assertions = 0, \
76 .passed = false, \
77 .exit_line = 0, \
78 .start = 0, \
79 .end = 0 \
80 }
81
82/**
83 * Define a unit test.
84 *
85 * This macro defines the function that will be executed when
86 * conducting a unit test. The name that is passed as a parameter must
87 * have been registered with the UNIT_TEST_REGISTER() macro.
88 *
89 * The function defined by this macro must start with a call to the
90 * UNIT_TEST_BEGIN() macro, and end with a call to the UNIT_TEST_END()
91 * macro.
92 *
93 * The standard test function template produced by this macro will
94 * ensure that the unit test keeps track of the result, the time taken
95 * to execute it (in clock ticks), and the exit point of the test. The
96 * latter corresponds to the line number at which the test was
97 * determined to be a success or failure.
98 *
99 * \param name The name of the unit test.
100 */
101#define UNIT_TEST(name) static void unit_test_function_##name(unit_test_t *unit_test_ptr)
102
103/**
104 * Mark the starting point of the unit test function.
105 */
106#define UNIT_TEST_BEGIN() do { \
107 unit_test_ptr->start = clock_time(); \
108 unit_test_ptr->assertions = 0; \
109 unit_test_ptr->passed = true; \
110 } while(0)
111
112/**
113 * Mark the ending point of the unit test function.
114 */
115#define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
116 unit_test_end: \
117 unit_test_ptr->end = clock_time()
118
119/*
120 * The test result is printed with a function that is selected by
121 * defining UNIT_TEST_PRINT_FUNCTION, which must be of the type
122 * unit_test_report_function_t. The default selection is
123 * unit_test_print_report, which is available in unit-test.c.
124 */
125#ifndef UNIT_TEST_PRINT_FUNCTION
126#define UNIT_TEST_PRINT_FUNCTION unit_test_print_report
127#endif /* !UNIT_TEST_PRINT_FUNCTION */
128
129/**
130 * Print a report of the execution of a unit test.
131 *
132 * \param name The name of the unit test.
133 */
134#define UNIT_TEST_PRINT_REPORT(name) UNIT_TEST_PRINT_FUNCTION(&unit_test_##name)
135
136/**
137 * Execute a unit test and print a report on the results.
138 *
139 * \param name The name of the unit test.
140 */
141#define UNIT_TEST_RUN(name) do { \
142 unit_test_function_##name(&unit_test_##name); \
143 UNIT_TEST_PRINT_REPORT(name); \
144 } while(0)
145
146/**
147 * Report that a unit test succeeded.
148 *
149 * This macro is useful for writing tests that can succeed earlier
150 * than the last execution point of the test, which is specified by a
151 * call to the UNIT_TEST_END() macro.
152 *
153 * Tests can usually be written without calls to UNIT_TEST_SUCCEED(),
154 * since it is implicitly called at the end of the test -- unless
155 * UNIT_TEST_FAIL() has been called.
156 */
157#define UNIT_TEST_SUCCEED() do { \
158 unit_test_ptr->exit_line = __LINE__; \
159 goto unit_test_end; \
160 } while(0)
161
162/**
163 * Report that a unit test failed.
164 *
165 * This macro is used to signal that a unit test failed to execute. The
166 * line number at which this macro was called is stored in the unit test
167 * descriptor.
168 */
169#define UNIT_TEST_FAIL() do { \
170 unit_test_ptr->exit_line = __LINE__; \
171 unit_test_ptr->passed = false; \
172 goto unit_test_end; \
173 } while(0)
174
175/**
176 * Assert an expression, and report a failure if the expression is false.
177 *
178 * \param expr The expression to evaluate.
179 */
180#define UNIT_TEST_ASSERT(expr) do { \
181 unit_test_ptr->assertions++; \
182 if(!(expr)) { \
183 UNIT_TEST_FAIL(); \
184 } \
185 } while(0)
186
187/**
188 * Obtain the result of a certain unit test.
189 *
190 * If the unit test has not yet been executed, this macro returns
191 * false. Otherwise it returns the result of the last
192 * execution of the unit test.
193 *
194 * \param name The name of the unit test.
195 * \return A boolean that tells whether the unit test has passed.
196 */
197#define UNIT_TEST_PASSED(name) (unit_test_##name.passed)
198
199/* The print function. */
200void UNIT_TEST_PRINT_FUNCTION(const unit_test_t *unit_test_ptr);
201
202#endif /* !UNIT_TEST_H */
The unit_test structure describes the results of a unit test.
Definition unit-test.h:49
struct unit_test unit_test_t
The unit_test structure describes the results of a unit test.