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 software.
33  * \author
34  * Nicolas Tsiftes <nvt@sics.se>
35  */
36 
37 #ifndef UNIT_TEST_H
38 #define UNIT_TEST_H
39 
40 #include "sys/rtimer.h"
41 
42 typedef enum unit_test_result {
43  unit_test_failure = 0,
44  unit_test_success = 1
45 } unit_test_result_t;
46 
47 /**
48  * The unit_test structure describes the results of a unit test. Each
49  * registered unit test statically allocates an object of this type.
50  */
51 typedef struct unit_test {
52  const char * const descr;
53  const char * const test_file;
54  unit_test_result_t result;
55  unsigned exit_line;
56  rtimer_clock_t start;
57  rtimer_clock_t end;
58 } 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 descr A string that briefly describes the unit test.
69  */
70 #define UNIT_TEST_REGISTER(name, descr) static unit_test_t unit_test_##name = {descr, __FILE__, unit_test_success, 0, 0, 0}
71 
72 /**
73  * Define a unit test.
74  *
75  * This macro defines the function that will be executed when conducting
76  * a unit test. The name that is passed as a parameter must have been
77  * registered with the UNIT_TEST_REGISTER() macro.
78  *
79  * The function defined by this macro must start with a call to the
80  * UNIT_TEST_BEGIN() macro, and end with a call to the UNIT_TEST_END()
81  * macro.
82  *
83  * The standard test function template produced by this macro will
84  * ensure that the unit test keeps track of the result, the time taken to
85  * execute (in rtimer ticks), and the exit point of the test. The
86  * latter corresponds to the line number at which the test was
87  * determined to be a success or failure.
88  *
89  * \param name The name of the unit test.
90  */
91 #define UNIT_TEST(name) static void unit_test_function_##name(unit_test_t *utp)
92 
93 /**
94  * Mark the starting point of the unit test function.
95  */
96 #define UNIT_TEST_BEGIN() do { \
97  utp->start = RTIMER_NOW(); \
98  utp->result = unit_test_success; \
99  } while(0)
100 
101 /**
102  * Mark the ending point of the unit test function.
103  */
104 #define UNIT_TEST_END() UNIT_TEST_SUCCEED(); \
105  unit_test_end: \
106  utp->end = RTIMER_NOW()
107 
108 /*
109  * The test result is printed with a function that is selected by
110  * defining UNIT_TEST_PRINT_FUNCTION, which must be of the type
111  * "void (*)(const unit_test_t *)". The default selection is
112  * unit_test_print_report, which is available in unit-test.c.
113  */
114 #ifndef UNIT_TEST_PRINT_FUNCTION
115 #define UNIT_TEST_PRINT_FUNCTION unit_test_print_report
116 #endif /* !UNIT_TEST_PRINT_FUNCTION */
117 
118 /**
119  * Print a report of the execution of a unit test.
120  *
121  * \param name The name of the unit test.
122  */
123 #define UNIT_TEST_PRINT_REPORT(name) UNIT_TEST_PRINT_FUNCTION(&unit_test_##name)
124 
125 /**
126  * Execute a unit test and print a report on the results.
127  *
128  * \param name The name of the unit test.
129  */
130 #define UNIT_TEST_RUN(name) do { \
131  unit_test_function_##name(&unit_test_##name); \
132  UNIT_TEST_PRINT_REPORT(name); \
133  } while(0)
134 
135 /**
136  * Report that a unit test succeeded.
137  *
138  * This macro is useful for writing tests that can succeed earlier than
139  * the last execution point of the test, which is specified by a call to
140  * the UNIT_TEST_END() macro.
141  *
142  * Tests can usually be written without calls to UNIT_TEST_SUCCEED(),
143  * since it is implicitly called at the end of the test---unless
144  * UNIT_TEST_FAIL() has been called.
145  *
146  */
147 #define UNIT_TEST_SUCCEED() do { \
148  utp->exit_line = __LINE__; \
149  goto unit_test_end; \
150  } while(0)
151 
152 /**
153  * Report that a unit test failed.
154  *
155  * This macro is used to signal that a unit test failed to execute. The
156  * line number at which this macro was called is stored in the unit test
157  * descriptor.
158  */
159 #define UNIT_TEST_FAIL() do { \
160  utp->exit_line = __LINE__; \
161  utp->result = unit_test_failure; \
162  goto unit_test_end; \
163  } while(0)
164 
165 /**
166  * Report failure if an expression is false.
167  *
168  * \param expr The expression to evaluate.
169  */
170 #define UNIT_TEST_ASSERT(expr) do { \
171  if(!(expr)) { \
172  UNIT_TEST_FAIL(); \
173  } \
174  } while(0)
175 
176 /**
177  * Obtain the result of a certain unit test.
178  *
179  * If the unit test has not yet been executed, this macro returns
180  * unit_test_failed. Otherwise it returns the result of the last
181  * execution of the unit test.
182  *
183  * \param name The name of the unit test.
184  */
185 #define UNIT_TEST_RESULT(name) (unit_test_##name.result)
186 
187 /* The print function. */
188 void UNIT_TEST_PRINT_FUNCTION(const unit_test_t *utp);
189 
190 #endif /* !UNIT_TEST_H */
struct unit_test unit_test_t
The unit_test structure describes the results of a unit test.
Header file for the real-time timer module.
The unit_test structure describes the results of a unit test.
Definition: unit-test.h:51