| 1 | = Userspace unit testing with PCUT = |
| 2 | |
| 3 | PCUT - plain C unit testing - is (still somewhat experimental) framework/library that ought to simplify writing unit tests in C. Its main advantage is simple usage and integration with HelenOS. |
| 4 | |
| 5 | PCUT itself is a standalone project with [https://github.com/vhotspur/pcut/wiki its own wiki]. This page provides mostly information specific for HelenOS (at least for now). |
| 6 | |
| 7 | |
| 8 | == Building and running PCUT tests |
| 9 | |
| 10 | The PCUT tests are built by default but are not included in the final image unless explicitly enabled. To enable them, turn on the `Include userspace unit tests (PCUT)` option during HelenOS configuration. |
| 11 | |
| 12 | The tests then reside in the `test/` directory, named `test-<component>` where `<component>` may refer to a standalone application or a library. It is possible to run them separately by launching individual binaries or run them all with the following command: |
| 13 | {{{ |
| 14 | batch /test/run_all |
| 15 | }}} |
| 16 | |
| 17 | This batch script also copies the result to `/data/web`, thus making them accessible by simply pointing your browser to [http://localhost:8080/test.html /test.html] (assuming you started the HelenOS web server). |
| 18 | |
| 19 | The tests output their results in a [http://testanything.org/ Test-Anything-Protocol] format that is easy to understand, below is an example from successful run of `test-libc`: |
| 20 | |
| 21 | {{{ |
| 22 | 1..11 |
| 23 | #> Starting suite sprintf. |
| 24 | ok 1 no_formatting |
| 25 | ok 2 string_plain |
| 26 | ok 3 string_dynamic_width |
| 27 | ok 4 string_dynamic_width_align_left |
| 28 | ok 5 string_pad |
| 29 | ok 6 string_pad_but_cut |
| 30 | ok 7 char_basic |
| 31 | ok 8 int_various_padding |
| 32 | ok 9 int_negative_various_padding |
| 33 | ok 10 long_negative_various_padding |
| 34 | ok 11 int_as_hex |
| 35 | #> Finished suite sprintf (failed 0 of 11). |
| 36 | }}} |
| 37 | |
| 38 | |
| 39 | == Writing your own tests == |
| 40 | |
| 41 | The test sources are typically stored in a `test/` subdirectory of the application/library they are testing. If you want to extend already existing test case or add a new test case, open an existing file with the tests and add it there. The file may look like this (example taken from `bdsh`): |
| 42 | |
| 43 | {{{#!c |
| 44 | |
| 45 | /* ... */ |
| 46 | |
| 47 | static tokenizer_t tokenizer; |
| 48 | static token_t tokens[MAX_TOKENS]; |
| 49 | |
| 50 | /* |
| 51 | * Implementation of |
| 52 | * void prepare(const char *input, size_t expected_token_count) |
| 53 | * is omitted. |
| 54 | */ |
| 55 | |
| 56 | #define ASSERT_TOKEN(index, token_type, token_text) \ |
| 57 | do { \ |
| 58 | PCUT_ASSERT_INT_EQUALS(token_type, tokens[index].type); \ |
| 59 | PCUT_ASSERT_STR_EQUALS(token_text, tokens[index].text); \ |
| 60 | } while (0) |
| 61 | |
| 62 | |
| 63 | |
| 64 | PCUT_TEST_SUITE(tokenizer); |
| 65 | |
| 66 | PCUT_TEST_AFTER { |
| 67 | /* Destroy the tokenizer. */ |
| 68 | tok_fini(&tokenizer); |
| 69 | } |
| 70 | |
| 71 | |
| 72 | PCUT_TEST(empty_input) { |
| 73 | prepare("", 0); |
| 74 | } |
| 75 | |
| 76 | PCUT_TEST(only_spaces) { |
| 77 | prepare(" ", 1); |
| 78 | |
| 79 | ASSERT_TOKEN(0, TOKTYPE_SPACE, " "); |
| 80 | } |
| 81 | |
| 82 | PCUT_TEST(two_text_tokens) { |
| 83 | prepare("alpha bravo", 3); |
| 84 | |
| 85 | ASSERT_TOKEN(0, TOKTYPE_TEXT, "alpha"); |
| 86 | ASSERT_TOKEN(1, TOKTYPE_SPACE, " "); |
| 87 | ASSERT_TOKEN(2, TOKTYPE_TEXT, "bravo"); |
| 88 | } |
| 89 | |
| 90 | PCUT_MAIN() |
| 91 | }}} |
| 92 | |
| 93 | Individual test cases are enclosed in `PCUT_TEST(test_name)`, available asserts are [https://github.com/vhotspur/pcut/wiki/Asserts listed here]. You might also want to read how to [https://github.com/vhotspur/pcut/wiki/Suites create test suites] that may share a [https://github.com/vhotspur/pcut/wiki/Suites#set-up-and-tear-down-routines set-up and tear-down code]. It is also possible to split [https://github.com/vhotspur/pcut/wiki/MultipleSources the tests into more files]. |
| 94 | |
| 95 | == Adding tests to previously untested code == |
| 96 | |
| 97 | It is recommended to put the test sources under `test/` directory to separate them from the tested code. |
| 98 | |
| 99 | Add sources with the tests to the `TEST_SOURCES` variable. If your are testing a library, the test executable will be automatically linked with it. For an application (or server), you need to add all the necessary source files by yourself (it is not possible to add all of them automatically because PCUT creates its own `main()` function that would collide with the `main()` of the application). |
| 100 | |
| 101 | Add path to the test to the `RD_TESTS` variable in `boot/Makefile.common`. |
| 102 | |
| 103 | Basically, look how it is done for existing tests (`libc`, `libposix`, `liburi` or `bdsh`) until this how-to is improved. |
| 104 | |