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 "contiki.h"
41#include <stdbool.h>
42#include <stdint.h>
43
44/**
45 * The unit_test structure describes the results of a unit test. Each
46 * registered unit test statically allocates an object of this type.
47 */
48typedef struct unit_test {
49 const char * const descr;
50 const char * const test_file;
51 uint32_t assertions;
52 bool passed;
53 unsigned exit_line;
54 clock_time_t start;
55 clock_time_t end;
57
58typedef void (*unit_test_report_function_t)(const unit_test_t *);
59
60/**
61 * Register a unit test.
62 *
63 * This macro allocates unit test descriptor, which is a structure of
64 * type unit_test_t. The descriptor contains information about a unit
65 * test, and the results from the last execution of the test.
66 *
67 * \param name The name of the unit test.
68 * \param description A string that briefly describes the unit test.
69 */
70#define UNIT_TEST_REGISTER(name, description) \
71 static unit_test_t unit_test_##name = \
72 {.descr = (description), \
73 .test_file = __FILE__, \
74 .assertions = 0, \
75 .passed = false, \
76 .exit_line = 0, \
77 .start = 0, \
78 .end = 0 \
79 }
80
81/**
82 * Define a unit test.
83 *
84 * This macro defines the protothread that will be executed when
85 * conducting a unit test. The name that is passed as a parameter must
86 * have been registered with the UNIT_TEST_REGISTER() macro.
87 *
88 * The function defined by this macro must start with a call to the
89 * UNIT_TEST_BEGIN() macro, and end with a call to the UNIT_TEST_END()
90 * macro.
91 *
92 * The standard test function template produced by this macro will
93 * ensure that the unit test keeps track of the result, the time taken
94 * to execute it (in clock ticks), and the exit point of the test. The
95 * latter corresponds to the line number at which the test was
96 * determined to be a success or failure.
97 *
98 * \param name The name of the unit test.
99 */
100#define UNIT_TEST(name) \
101 PT_THREAD(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() PT_BEGIN(&unit_test_pt); \
107 unit_test_ptr->start = clock_time(); \
108 unit_test_ptr->assertions = 0; \
109 unit_test_ptr->passed = true
110
111/**
112 * Mark the ending point of the unit test function.
113 */
114#define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
115 unit_test_end: \
116 unit_test_ptr->end = clock_time(); \
117 PT_END(&unit_test_pt)
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 PROCESS_PT_SPAWN(&unit_test_pt, \
143 unit_test_function_##name( \
144 &unit_test_##name)); \
145 UNIT_TEST_PRINT_REPORT(name); \
146 } while(0)
147
148/**
149 * Report that a unit test succeeded.
150 *
151 * This macro is useful for writing tests that can succeed earlier
152 * than the last execution point of the test, which is specified by a
153 * call to the UNIT_TEST_END() macro.
154 *
155 * Tests can usually be written without calls to UNIT_TEST_SUCCEED(),
156 * since it is implicitly called at the end of the test -- unless
157 * UNIT_TEST_FAIL() has been called.
158 */
159#define UNIT_TEST_SUCCEED() do { \
160 unit_test_ptr->exit_line = __LINE__; \
161 goto unit_test_end; \
162 } while(0)
163
164/**
165 * Report that a unit test failed.
166 *
167 * This macro is used to signal that a unit test failed to execute. The
168 * line number at which this macro was called is stored in the unit test
169 * descriptor.
170 */
171#define UNIT_TEST_FAIL() do { \
172 unit_test_ptr->exit_line = __LINE__; \
173 unit_test_ptr->passed = false; \
174 goto unit_test_end; \
175 } while(0)
176
177/**
178 * Assert an expression, and report a failure if the expression is false.
179 *
180 * \param expr The expression to evaluate.
181 */
182#define UNIT_TEST_ASSERT(expr) do { \
183 unit_test_ptr->assertions++; \
184 if(!(expr)) { \
185 UNIT_TEST_FAIL(); \
186 } \
187 } while(0)
188
189/**
190 * Obtain the result of a certain unit test.
191 *
192 * If the unit test has not yet been executed, this macro returns
193 * false. Otherwise it returns the result of the last
194 * execution of the unit test.
195 *
196 * \param name The name of the unit test.
197 * \return A boolean that tells whether the unit test has passed.
198 */
199#define UNIT_TEST_PASSED(name) (unit_test_##name.passed)
200
201/* The print function. */
202void UNIT_TEST_PRINT_FUNCTION(const unit_test_t *unit_test_ptr);
203
204extern struct pt unit_test_pt;
205
206#endif /* !UNIT_TEST_H */
The unit_test structure describes the results of a unit test.
Definition unit-test.h:48
struct unit_test unit_test_t
The unit_test structure describes the results of a unit test.