1# ulib/unittest 2 3This directory contains a harness, named Unittest, for writing tests 4used by system/utest. 5 6N.B. This library cannot use fdio since system/utest/core uses it 7and system/utest/core cannot use fdio. See system/utest/core/README.md. 8 9**If you want your unit tests to print to standard out, you must link your 10test executable to system/ulib/fdio!** 11 12## Rules for use of printf vs unittest_printf 13 14Tests are expected to *not* call `printf()`. By default we want tests 15to be less verbose, and use of printfs about means the output cannot 16not be disabled. This test harness can call `printf()`, but tests should not. 17Instead tests are expected to either call `unittest_printf()` or 18`unitest_printf_critical()`, the difference being that the former is 19controlled by the verbosity level, and the latter is not. 20Obviously `unittest_printf_critical()` is intended to be used *sparingly*. 21 22## Test verbosity 23 24Verbosity is controlled by passing `v=N` when invoking the test, 25where N has the range 0-9. The default is zero, which means 26`unittest_printf()` output does not appear. Any value above zero enables 27`unittest_printf()` output. 28 29## Rules for parsing argv 30 31Unittest has a set of options that it recognizes. 32All tests are expected to call `unittest_run_all_tests()`, 33which will ensure all tests get these options. 34 35However, tests can also have their own options. Since Unittest does not 36use any kind of general argv parsing library, and each test as well as 37Unittest do their own parsing, one issue is how to support both Unittest 38options and test-specific options without either having to know about the 39other. This becomes important when parsing an option that takes a value and 40the value might begin with "-". E.g., 41 42``` 43$ foo-test --foo -f -f bar 44``` 45 46where the first `-f` is the value for option `--foo` 47and the second `-f` is an option specific to `foo-test`. 48 49Argv processing is first done in the `main()` of the testcase, and 50then again in Unittest when the testcase calls `unittest_run_all_tests()`. 51If `--foo` is a Unittest option, how does the testcase know to 52ignore the first `-f`? The solution we employ is very simple: 53 54*Parse argv one element at a time,* 55*and ignore anything that is not recognized.* 56 57This simple rule makes writing tests easy, but it does have some consequences 58one needs to be aware of. For example, this means that option values cannot 59begin with "-", which makes the above example invalid. 60A second consequence is that there are no positional parameters. 61E.g., 62 63``` 64$ foo-test --foo ./-f a b c -f bar 65``` 66is equivalent to 67``` 68$ foo-test --foo ./-f -f bar a b c 69``` 70 71While not entirely clean, this allows for a simple implementation, 72and preserves the status quo. 73