33 * |
33 * |
34 * Usage of this test framework: |
34 * Usage of this test framework: |
35 * |
35 * |
36 * **** IN HEADER FILE: **** |
36 * **** IN HEADER FILE: **** |
37 * |
37 * |
38 * <pre> |
38 * <code> |
39 * CX_TEST(function_name); |
39 * CX_TEST(function_name); |
40 * CX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional |
40 * CX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional |
41 * </pre> |
41 * </code> |
42 * |
42 * |
43 * **** IN SOURCE FILE: **** |
43 * **** IN SOURCE FILE: **** |
44 * <pre> |
44 * <code> |
45 * CX_TEST_SUBROUTINE(subroutine_name, paramlist) { |
45 * CX_TEST_SUBROUTINE(subroutine_name, paramlist) { |
46 * // tests with CX_TEST_ASSERT() |
46 * // tests with CX_TEST_ASSERT() |
47 * } |
47 * } |
48 * |
48 * |
49 * CX_TEST(function_name) { |
49 * CX_TEST(function_name) { |
52 * // tests with CX_TEST_ASSERT() and/or |
52 * // tests with CX_TEST_ASSERT() and/or |
53 * // calls with CX_TEST_CALL_SUBROUTINE() here |
53 * // calls with CX_TEST_CALL_SUBROUTINE() here |
54 * } |
54 * } |
55 * // cleanup of memory here |
55 * // cleanup of memory here |
56 * } |
56 * } |
57 * </pre> |
57 * </code> |
58 * |
58 * |
59 * @attention Do not call own functions within a test, that use |
59 * @attention Do not call own functions within a test, that use |
60 * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE(). |
60 * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE(). |
61 * |
61 * |
62 * @author Mike Becker |
62 * @author Mike Becker |
85 * <code>__func__</code>. |
85 * <code>__func__</code>. |
86 */ |
86 */ |
87 #define __FUNCTION__ __func__ |
87 #define __FUNCTION__ __func__ |
88 #endif |
88 #endif |
89 |
89 |
90 // |
|
91 #if !defined(__clang__) && __GNUC__ > 3 |
90 #if !defined(__clang__) && __GNUC__ > 3 |
92 #pragma GCC diagnostic ignored "-Wclobbered" |
91 #pragma GCC diagnostic ignored "-Wclobbered" |
93 #endif |
92 #endif |
94 |
93 |
95 /** Type for the CxTestSuite. */ |
94 /** Type for the CxTestSuite. */ |
96 typedef struct CxTestSuite CxTestSuite; |
95 typedef struct CxTestSuite CxTestSuite; |
97 |
96 |
98 /** Pointer to a test function. */ |
97 /** Pointer to a test function. */ |
99 cx_attr_nonnull |
|
100 typedef void(*CxTest)(CxTestSuite *, void *, cx_write_func); |
98 typedef void(*CxTest)(CxTestSuite *, void *, cx_write_func); |
101 |
99 |
102 /** Type for the internal list of test cases. */ |
100 /** Type for the internal list of test cases. */ |
103 typedef struct CxTestSet CxTestSet; |
101 typedef struct CxTestSet CxTestSet; |
104 |
102 |
173 /** |
171 /** |
174 * Registers a test function with the specified test suite. |
172 * Registers a test function with the specified test suite. |
175 * |
173 * |
176 * @param suite the suite, the test function shall be added to |
174 * @param suite the suite, the test function shall be added to |
177 * @param test the test function to register |
175 * @param test the test function to register |
178 * @return zero on success or non-zero on failure |
176 * @retval zero success |
|
177 * @retval non-zero failure |
179 */ |
178 */ |
180 cx_attr_nonnull |
179 cx_attr_nonnull |
181 static inline int cx_test_register(CxTestSuite* suite, CxTest test) { |
180 static inline int cx_test_register(CxTestSuite* suite, CxTest test) { |
182 CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet)); |
181 CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet)); |
183 if (t) { |
182 if (t) { |
200 |
199 |
201 /** |
200 /** |
202 * Runs a test suite and writes the test log to the specified stream. |
201 * Runs a test suite and writes the test log to the specified stream. |
203 * @param suite the test suite to run |
202 * @param suite the test suite to run |
204 * @param out_target the target buffer or file to write the output to |
203 * @param out_target the target buffer or file to write the output to |
205 * @param out_writer the write function writing to \p out_target |
204 * @param out_writer the write function writing to @p out_target |
206 */ |
205 */ |
207 cx_attr_nonnull |
206 cx_attr_nonnull |
208 static inline void cx_test_run(CxTestSuite *suite, |
207 static inline void cx_test_run(CxTestSuite *suite, |
209 void *out_target, cx_write_func out_writer) { |
208 void *out_target, cx_write_func out_writer) { |
210 if (suite->name == NULL) { |
209 if (suite->name == NULL) { |
229 out_writer(total, 1, len, out_target); |
228 out_writer(total, 1, len, out_target); |
230 } |
229 } |
231 |
230 |
232 /** |
231 /** |
233 * Runs a test suite and writes the test log to the specified FILE stream. |
232 * Runs a test suite and writes the test log to the specified FILE stream. |
234 * @param suite the test suite to run |
233 * @param suite (@c CxTestSuite*) the test suite to run |
235 * @param file the target file to write the output to |
234 * @param file (@c FILE*) the target file to write the output to |
236 */ |
235 */ |
237 #define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite) |
236 #define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite) |
238 |
237 |
239 /** |
238 /** |
240 * Runs a test suite and writes the test log to stdout. |
239 * Runs a test suite and writes the test log to stdout. |
241 * @param suite the test suite to run |
240 * @param suite (@c CxTestSuite*) the test suite to run |
242 */ |
241 */ |
243 #define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout) |
242 #define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout) |
244 |
243 |
245 /** |
244 /** |
246 * Macro for a #CxTest function header. |
245 * Macro for a #CxTest function header. |
251 */ |
250 */ |
252 #define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_) |
251 #define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_) |
253 |
252 |
254 /** |
253 /** |
255 * Defines the scope of a test. |
254 * Defines the scope of a test. |
|
255 * |
|
256 * @code |
|
257 * CX_TEST(my_test_name) { |
|
258 * // setup code |
|
259 * CX_TEST_DO { |
|
260 * // your tests go here |
|
261 * } |
|
262 * // tear down code |
|
263 * } |
|
264 * @endcode |
|
265 * |
256 * @attention Any CX_TEST_ASSERT() calls must be performed in scope of |
266 * @attention Any CX_TEST_ASSERT() calls must be performed in scope of |
257 * #CX_TEST_DO. |
267 * #CX_TEST_DO. |
258 */ |
268 */ |
259 #define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\ |
269 #define CX_TEST_DO _writefnc_("Running ", 1, 8, _output_);\ |
260 _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\ |
270 _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\ |
268 /** |
278 /** |
269 * Checks a test assertion. |
279 * Checks a test assertion. |
270 * If the assertion is correct, the test carries on. If the assertion is not |
280 * If the assertion is correct, the test carries on. If the assertion is not |
271 * correct, the specified message (terminated by a dot and a line break) is |
281 * correct, the specified message (terminated by a dot and a line break) is |
272 * written to the test suites output stream. |
282 * written to the test suites output stream. |
273 * @param condition the condition to check |
283 * @param condition (@c bool) the condition to check |
274 * @param message the message that shall be printed out on failure |
284 * @param message (@c char*) the message that shall be printed out on failure |
275 */ |
285 */ |
276 #define CX_TEST_ASSERTM(condition,message) if (!(condition)) { \ |
286 #define CX_TEST_ASSERTM(condition,message) if (!(condition)) { \ |
277 const char *_assert_msg_ = message; \ |
287 const char *_assert_msg_ = message; \ |
278 _writefnc_(_assert_msg_, 1, strlen(_assert_msg_), _output_); \ |
288 _writefnc_(_assert_msg_, 1, strlen(_assert_msg_), _output_); \ |
279 _writefnc_(".\n", 1, 2, _output_); \ |
289 _writefnc_(".\n", 1, 2, _output_); \ |
284 /** |
294 /** |
285 * Checks a test assertion. |
295 * Checks a test assertion. |
286 * If the assertion is correct, the test carries on. If the assertion is not |
296 * If the assertion is correct, the test carries on. If the assertion is not |
287 * correct, the specified message (terminated by a dot and a line break) is |
297 * correct, the specified message (terminated by a dot and a line break) is |
288 * written to the test suites output stream. |
298 * written to the test suites output stream. |
289 * @param condition the condition to check |
299 * @param condition (@c bool) the condition to check |
290 */ |
300 */ |
291 #define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed") |
301 #define CX_TEST_ASSERT(condition) CX_TEST_ASSERTM(condition, #condition " failed") |
292 |
302 |
293 /** |
303 /** |
294 * Macro for a test subroutine function header. |
304 * Macro for a test subroutine function header. |