Contiki-NG
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  */
49 typedef 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;
57 } unit_test_t;
58 
59 typedef 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. */
200 void UNIT_TEST_PRINT_FUNCTION(const unit_test_t *unit_test_ptr);
201 
202 #endif /* !UNIT_TEST_H */
struct unit_test unit_test_t
The unit_test structure describes the results of a unit test.
The unit_test structure describes the results of a unit test.
Definition: unit-test.h:49