le_test.h

Go to the documentation of this file.
1 /**
2  * @page c_test Unit Testing API
3  *
4  * @subpage le_test.h "API Reference"
5  *
6  * <HR>
7  *
8  * Unit testing is an important aspect of a quantifiable quality assurance methodology. Although
9  * unit testing requires some extra overhead (the writing of the unit tests) during the development
10  * process it can provide enormous benefits during the project life cycle.
11  *
12  * One benefit of writing unit tests is that it gets the developer using the interface to the
13  * unit they designed. This forces the developer to think about, and hopefully design for,
14  * usability of the interface early in the development cycle.
15  *
16  * Another major benefit to unit testing is that it provides a documented and verifiable level of
17  * correctness for the designed unit. This allows the developer to refactor the code more
18  * aggressively and to quickly verify its correctness. Unit tests can also be used to perform
19  * regression testing when adding new features.
20  *
21  * Despite the benefits of unit testing, unit tests are often omitted because of the initial
22  * overhead of writing the tests and the complexity of testing frameworks. Legato's Unit Test
23  * Framework is simple to use and very flexible and lightweight consisting of some
24  * handy macros.
25  *
26  * The Legato test framework outputs test results to the log in TAP format (prefixed by "TAP |")
27  * This allows test results to be processed with many test harnasses.
28  *
29  * @section c_test_setup Setting Up the Test Framework
30  *
31  * To setup the Legato Test Framework, call the @c LE_TEST_PLAN macro, once before any tests
32  * are started. The macro takes the total number of planned tests as single argument.
33  *
34  * @section c_test_testing Performing Tests
35  *
36  * To perform tests, call the @c LE_TEST_OK macro. The first argument is whether the
37  * test passed (true or false). The second argument is the name of the test.
38  *
39  * For example:
40  *
41  * @code
42  * #include "legato.h"
43  *
44  * // Returns true if the test passes, otherwise returns false.
45  * bool ComplexTest(void)
46  * {
47  * int expectedValue;
48  *
49  * // Do some initializations and/or calculations.
50  * ...
51  *
52  * // Call one of the unit-under-test's interface function and check it's return value against
53  * // an expected value that was calculated earlier.
54  * return (unitUnderTest_foo2() == expectedValue);
55  * }
56  *
57  *
58  * int main (void)
59  * {
60  * // Setup the Legato Test Framework.
61  * LE_TEST_PLAN(2);
62  *
63  * // Run the tests.
64  * // Do some initializations and/or calculations.
65  * ...
66  *
67  * LE_TEST_OK(TestFunction(arguments) == EXPECTED_VALUE, "simple test");
68  * LE_TEST_OK(ComplexTest(), "complex test");
69  *
70  * // Exit with the number of failed tests as the exit code.
71  * LE_TEST_EXIT;
72  * }
73  * @endcode
74  *
75  * @section c_test_exit Exiting a Test Program
76  *
77  * When a test program is finished executing tests and needs to exit, it should exit
78  * using the LE_TEST_EXIT macro.
79  *
80  * If a test suite needs to exit early it should use the LE_TEST_FATAL() macro. This will
81  * log a message indicating the test suite has been aborted. LE_ASSERT()
82  * and LE_FATAL() macros should not be used as they will not print this message.
83  *
84  * As a convenience you can also use the LE_TEST_ASSERT() macro which will abort the test suite
85  * if the test fails. This is useful if running further test cases is pointless after this failure.
86  *
87  * @section c_test_result Test Results
88  *
89  * The LE_TEST_EXIT macro will cause the process to exit with the number of failed tests as the exit
90  * code.
91  *
92  * @note The log message format depends on the current log settings.
93  *
94  * @section c_test_multiThread Multi-Threaded Tests
95  *
96  * For unit tests that contain multiple threads run the various tests, these macros can still
97  * be used. However your test program should ensure that only one thread uses the unit test
98  * API at a time.
99  *
100  * <HR>
101  *
102  * Copyright (C) Sierra Wireless Inc.
103  */
104 
105 //--------------------------------------------------------------------------------------------------
106 /** @file le_test.h
107  *
108  * Legato @ref c_test include file.
109  *
110  * Copyright (C) Sierra Wireless Inc.
111  */
112 
113 #ifndef LEGATO_TEST_INCLUDE_GUARD
114 #define LEGATO_TEST_INCLUDE_GUARD
115 
116 
117 //--------------------------------------------------------------------------------------------------
118 /**
119  * @name Local definitions that should not be used directly.
120  *
121  * @{
122  */
123 //--------------------------------------------------------------------------------------------------
124 void _le_test_Init(int testCount);
125 void _le_test_Exit(void) __attribute__((noreturn));
126 bool _le_test_CheckNeedsPlan(void);
127 void _le_test_Fail(void);
128 int _le_test_NumberTest(void);
129 int _le_test_GetNumTests(void);
130 int _le_test_GetNumFailures(void);
131 bool _le_test_SetTodo(bool todo);
132 void _le_test_Skip(int count);
133 bool _le_test_IsSkipping(void);
134 const char* _le_test_GetTag(void);
135 
136 //
137 // Allow overriding LE_TEST_OUTPUT by a frameworkAdaptor
138 //
139 #ifndef LE_TEST_OUTPUT
140 # define LE_TEST_OUTPUT(format, ...) LE_INFO("TAP | " format, ##__VA_ARGS__)
141 #endif
142 // @}
143 
144 //--------------------------------------------------------------------------------------------------
145 /**
146  * Indicate the number of tests is not known in advance.
147  */
148 //--------------------------------------------------------------------------------------------------
149 #define LE_TEST_NO_PLAN -1
150 
151 //--------------------------------------------------------------------------------------------------
152 /**
153  * Initializes a test plan. Must be called once before any tests are performed.
154  *
155  * @param testCount Number of tests expected in this test case.
156  */
157 //--------------------------------------------------------------------------------------------------
158 #define LE_TEST_PLAN(testCount) do { \
159  if (testCount >= 0) { LE_TEST_OUTPUT("1..%d", testCount); } \
160  _le_test_Init(testCount); \
161  } while(0)
162 
163 
164 //--------------------------------------------------------------------------------------------------
165 /**
166  * Initializes the testing framework. Must be called once before any tests are performed.
167  *
168  * Obselete synonym for LE_TEST_PLAN(LE_TEST_NO_PLAN)
169  */
170 //--------------------------------------------------------------------------------------------------
171 #define LE_TEST_INIT LE_TEST_PLAN(LE_TEST_NO_PLAN)
172 
173 
174 //--------------------------------------------------------------------------------------------------
175 /**
176  * Perform the test
177  */
178 //--------------------------------------------------------------------------------------------------
179 #define LE_TEST_OK(test, testName, ...) do { \
180  if (test) \
181  { \
182  LE_TEST_OUTPUT("ok %d - " testName "%s", \
183  _le_test_NumberTest(), \
184  ##__VA_ARGS__, \
185  _le_test_GetTag()); \
186  } \
187  else \
188  { \
189  LE_TEST_OUTPUT("not ok %d - " testName "%s", \
190  _le_test_NumberTest(), \
191  ##__VA_ARGS__, \
192  _le_test_GetTag()); \
193  _le_test_Fail(); \
194  } \
195  } while(0)
196 
197 //--------------------------------------------------------------------------------------------------
198 /**
199  * Performs the test.
200  *
201  * For new tests, LE_TEST_OK is preferred which gives an option to set the test name.
202  */
203 //--------------------------------------------------------------------------------------------------
204 #define LE_TEST(testResult) LE_TEST_OK((testResult), #testResult)
205 
206 
207 //--------------------------------------------------------------------------------------------------
208 /**
209  * Bail out of a test suite early.
210  *
211  * Using this instead of LE_FATAL ensures the test harness is notified the test suite is
212  * exiting abnormally.
213  */
214 //--------------------------------------------------------------------------------------------------
215 #define LE_TEST_FATAL(...) do { \
216  LE_TEST_OUTPUT("Bail out! " __VA_ARGS__); \
217  _le_test_Exit(); \
218  } while(0)
219 
220 //--------------------------------------------------------------------------------------------------
221 /**
222  * Perform a test, and bail out if the test fails.
223  *
224  * This should only be used if a test suite cannot continue if this test fails. Generally
225  * LE_TEST_OK should be used instead.
226  */
227 //--------------------------------------------------------------------------------------------------
228 #define LE_TEST_ASSERT(test, testName, ...) do { \
229  if (test) \
230  { \
231  LE_TEST_OUTPUT("ok %d - " testName "%s", \
232  _le_test_NumberTest(), \
233  ##__VA_ARGS__, \
234  _le_test_GetTag()); \
235  } \
236  else \
237  { \
238  LE_TEST_OUTPUT("not ok %d - " testName "%s", \
239  _le_test_NumberTest(), \
240  ##__VA_ARGS__, \
241  _le_test_GetTag()); \
242  _le_test_Fail(); \
243  LE_TEST_FATAL(); \
244  } \
245  } while(0)
246 
247 
248 //--------------------------------------------------------------------------------------------------
249 /**
250  * Ouptut some diagnostic information. In tests this should be used instead of LE_INFO so
251  * the output appears in the test results
252  */
253 //--------------------------------------------------------------------------------------------------
254 #define LE_TEST_INFO(...) LE_TEST_OUTPUT("# " __VA_ARGS__)
255 
256 //--------------------------------------------------------------------------------------------------
257 /**
258  * Mark a test as not yet implemented. Todo tests will still be run, but are expected to fail.
259  *
260  * Begins a block which must be terminated by LE_TEST_END_TODO()
261  */
262 //--------------------------------------------------------------------------------------------------
263 #define LE_TEST_BEGIN_TODO(cond) do { \
264  bool _le_test_OldTodo = _le_test_SetTodo(cond); \
265 
266 //--------------------------------------------------------------------------------------------------
267 /**
268  * End a block of tests which may not be implemented yet.
269  */
270 //--------------------------------------------------------------------------------------------------
271 #define LE_TEST_END_TODO() \
272  _le_test_SetTodo(_le_test_OldTodo); \
273  } while(0)
274 
275 
276 //--------------------------------------------------------------------------------------------------
277 /**
278  * Mark a test as skipped. Skipped tests will not be run, and will always pass.
279  *
280  * Begins a block which must be terminated by LE_TEST_END_SKIP()
281  */
282 //--------------------------------------------------------------------------------------------------
283 #define LE_TEST_BEGIN_SKIP(cond, count) do { \
284  if (cond) \
285  { \
286  _le_test_Skip(count); \
287  break; \
288  }
289 
290 //--------------------------------------------------------------------------------------------------
291 /**
292  * End a block of tests which may not be implemented yet.
293  */
294 //--------------------------------------------------------------------------------------------------
295 #define LE_TEST_END_SKIP() \
296  } while(0)
297 
298 
299 //--------------------------------------------------------------------------------------------------
300 /**
301  * Exits the process and returns the number of failed tests.
302  */
303 //--------------------------------------------------------------------------------------------------
304 #define LE_TEST_EXIT do { \
305  if (_le_test_CheckNeedsPlan()) \
306  { \
307  LE_TEST_OUTPUT("1..%d", _le_test_GetNumTests()); \
308  } \
309  _le_test_Exit(); \
310  } while(0)
311 
312 /// <b> *DEPRECATED* </b> old name for LE_TEST_EXIT.
313 #define LE_TEST_SUMMARY LE_TEST_EXIT
314 
315 
316 #endif // LEGATO_TEST_INCLUDE_GUARD