= LolUnit tutorial = This tutorial is a quick introduction to LolUnit. LolUnit is still in its early development stages. Feel free to send comments, suggestions or questions to sam@hocevar.net. == Getting started == Only one line is required to start using LolUnit: {{{ #!cpp #include }}} '''No library and no compiler or linker flags are required''' as long as the `` file is copied in a place where the compiler can find it, for instance in `/usr/include/lol/unit.h`. == Fixtures and tests == A '''fixture''' is a container class for tests that allows optional setup and teardown methods. To declare and automatically register a fixture, use the `LOLUNIT_FIXTURE` macro: {{{ #!cpp LOLUNIT_FIXTURE(MyFirstFixture) { }; }}} A '''test''' is a method within a fixture that runs a series of checks. To declare and automatically register a test within a fixture, use the `LOLUNIT_TEST` macro: {{{ #!cpp LOLUNIT_FIXTURE(MyFirstFixture) { LOLUNIT_TEST(MyFirstTest) { } }; }}} == Add checks == Several macros are provided to perform various checks: * `LOLUNIT_ASSERT(condition)` will cause the current test to fail if `condition` is not met. * `LOLUNIT_ASSERT_EQUAL(a, b)` will cause the current test to fail if `a` and `b` are not equal. * `LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, t)` will cause the current test to fail if the floating point values `a` and `b` are not equal, with a tolerance of `t`. * all other comparison checks and their negations are available: `LOLUNIT_ASSERT_GREATER`, `LOLUNIT_ASSERT_NOT_GREATER`, etc. This is how to populate our fixture: {{{ #!cpp LOLUNIT_FIXTURE(MyFirstFixture) { LOLUNIT_TEST(Addition) { LOLUNIT_ASSERT_EQUAL(1 + 1, 2); LOLUNIT_ASSERT_LESS(2 + 2, 5); /* Check that our value for 2 is not too large */ LOLUNIT_ASSERT_NOT_GEQUAL(2 + 2, 5); } LOLUNIT_TEST(Division) { double a = 1.0 / 2; double b = 1.0 / 3; double c = 1.0 / 6; LOLUNIT_ASSERT_DOUBLES_EQUAL(a - b, c, 1e-10); } }; }}} == Run the test == Fixtures and their tests are automatically registered in a list global to the program. A `TextTestRunner` object can then be used to run all tests: {{{ #!cpp int main(void) { lol::TextTestRunner runner; return !runner.run(); } }}} And this is the output: {{{ .. OK (2 tests) }}} == Test failures == Let's add yet another test to `MyFirstFixture`: {{{ #!cpp LOLUNIT_TEST(ExpectedFailure) { double a = 0.1; double b = 0.2; LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, 1e-10); } }}} And running it: {{{ ...F !!!FAILURES!!! Test Results: Run: 3 Failures: 1 Errors: 0 1) test: MyFirstFixture::ExpectedFailure (F) line: 23 tutorial.cpp double equality assertion failed - Expected: a = 0.1 - Actual : b = 0.2 - Delta : 1e-010 }}} The test failure is properly spotted and information is given on where and how it happened. == Comparison with CppUnit == LolUnit is very similar to CppUnit, except it requires significantly less user input. This is what we would have done with CppUnit: {{{ #!cpp #include #include #include #include #include #include class MyFirstFixture : public CppUnit::TestCase { CPPUNIT_TEST_SUITE(MyFirstFixture); CPPUNIT_TEST(Addition); CPPUNIT_TEST(Division); CPPUNIT_TEST(ExpectedFailure); CPPUNIT_TEST_SUITE_END(); void Addition() { CPPUNIT_ASSERT_EQUAL(1 + 1, 2); CPPUNIT_ASSERT(2 + 2 < 5); /* Check that our value for 2 is not too large */ CPPUNIT_ASSERT(!(2 + 2 >= 5)); } void Division() { double a = 1.0 / 2; double b = 1.0 / 3; double c = 1.0 / 6; CPPUNIT_ASSERT_DOUBLES_EQUAL(a - b, c, 1e-10); } void ExpectedFailure() { double a = 0.1; double b = 0.2; CPPUNIT_ASSERT_DOUBLES_EQUAL(a, b, 1e-10); } }; CPPUNIT_TEST_SUITE_REGISTRATION(MyFirstFixture); int main(void) { CppUnit::TextTestRunner runner; runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); return !runner.run(); } }}} One major problem I have with this system is that `Addition` needs to be declared and defined at two different places. Similarly, `MyFirstFixture` needs to be declared, then given as an argument to `CPPUNIT_TEST_SUITE`, and finally as an argument to `CPPUNIT_TEST_SUITE_REGISTRATION`. There is no reason the user should have to duplicate this information. And this is the output: {{{ ...F !!!FAILURES!!! Test Results: Run: 3 Failures: 1 Errors: 0 1) test: MyFirstFixture::ExpectedFailure (F) line: 34 tutorial.cpp double equality assertion failed - Expected: 0.1 - Actual : 0.2 - Delta : 1e-10 }}}