UNIXworkcode

1 # Test Framework 2 3 UCX brings its own testing framework, which can also be used by your applications. 4 5 A test new suite is created by `cx_test_suite_new()`. 6 An arbitrary number of test cases can be registered with `cx_test_register()`. 7 8 ```C 9 #include <cx/test.h> 10 11 CxTestSuite *suite = cx_test_suite_new("My Suite"); 12 13 cx_test_register(suite, test_foo); 14 cx_test_register(suite, test_bar); 15 cx_test_register(suite, test_baz); 16 ``` 17 18 A test case needs to be defined with the `CX_TEST` macro. 19 The general structure of a test case is 1) setup code, 2) the actual test, 3) tear down code. 20 In UCX this is realized by the `CX_TEST_DO` macro with which you can define a scope for the actual test. 21 Whenever a test assertion fails, the scope is exited and the tear-down code is executed. 22 23 <tabs> 24 <tab title="Test"> 25 <code-block lang="C"><![CDATA[ 26 CX_TEST(test_foo) { 27 struct mystruct *x = malloc(sizeof(*x)); 28 x->d = 42; 29 CX_TEST_DO { 30 int y = foo(x); 31 32 // auto-generated failure message 33 CX_TEST_ASSERT(y == 42); 34 35 // alternatively: custom failure message 36 CX_TEST_ASSERTM(y == 42, 37 "foo does not return correct value"); 38 } 39 free(x); 40 } 41 ]]></code-block> 42 </tab> 43 <tab title="Implementation"> 44 <code-block lang="C"><![CDATA[ 45 struct mystruct { 46 int d; 47 }; 48 49 int foo(struct mystruct *s) { 50 return s->d; 51 } 52 ]]></code-block> 53 </tab> 54 </tabs> 55 56 Once you have registered all test cases, you can run the test suite with `cx_test_run()` 57 or one of the convenience macros. 58 59 <tabs> 60 <tab title="stdout"> 61 <code-block lang="C"> 62 cx_test_run_stdout(suite); 63 </code-block> 64 </tab> 65 <tab title="FILE*"> 66 <code-block lang="C"> 67 FILE *f = fopen("test-result.txt", "w"); 68 cx_test_run_f(suite, f); 69 fclose(f); 70 </code-block> 71 </tab> 72 <tab title="Other"> 73 <code-block lang="C"> 74 // for example: UCX buffer 75 CxBuffer buf; 76 cxBufferInit(&buf, NULL, 1024, NULL, 0); 77 cx_test_run(suite, &buf, cxBufferWriteFunc); 78 // do something with the buffer 79 cxBufferDestroy(&buf); 80 </code-block> 81 </tab> 82 </tabs> 83 Finally, clean up all resources consumed by the test suite. 84 85 ```C 86 cx_test_suite_free(suite); 87 ``` 88 89 ## Test Subroutines 90 91 For parameterized testing you can define and call test subroutines. 92 It is _not_ possible to call arbitrary functions and use the `CX_TEST_ASSERT` macro. 93 Instead, you define a callable test subroutine with `CX_TEST_SUBROUTINE` and call it with `CX_TEST_CALL_SUBROUTINE`. 94 The following example illustrates this with an adaption of the above test case. 95 96 ```c 97 CX_TEST_SUBROUTINE(test_foo_params, struct mystruct *x, int d) { 98 x->d = d; 99 CX_TEST_ASSERT(foo(x) == d); 100 } 101 102 CX_TEST(test_foo) { 103 struct mystruct *x = malloc(sizeof(*x)); 104 CX_TEST_DO { 105 CX_TEST_CALL_SUBROUTINE(test_foo_params, x, 42); 106 CX_TEST_CALL_SUBROUTINE(test_foo_params, x, -42); 107 CX_TEST_CALL_SUBROUTINE(test_foo_params, x, 1337); 108 } 109 free(x); 110 } 111 ``` 112 113 > Any test function, test case or test subroutine is a normal C function. 114 > As such you can decide to make them `static` when you do not want external linkage. 115 > For example, you can define the test as `static CX_TEST(test_foo)` instead of `CX_TEST(test_foo)`. 116 117 <seealso> 118 <category ref="apidoc"> 119 <a href="https://ucx.sourceforge.io/api/test_8h.html">test.h</a> 120 </category> 121 </seealso> 122