Changes between Initial Version and Version 1 of oss/lolunit/tutorial


Ignore:
Timestamp:
Sep 8, 2011, 3:29:11 PM (8 years ago)
Author:
sam
Comment:

tutorial

Legend:

Unmodified
Added
Removed
Modified
  • oss/lolunit/tutorial

    v1 v1  
     1= LolUnit tutorial =
     2
     3This tutorial is a quick introduction to LolUnit.
     4
     5LolUnit is still in its early development stages. Feel free to send comments, suggestions or questions to sam@hocevar.net.
     6
     7== Getting started ==
     8
     9Only one line is required to start using LolUnit:
     10
     11{{{
     12#!cpp
     13#include <lol/unit.h>
     14}}}
     15
     16== Fixtures ==
     17
     18A '''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:
     19
     20{{{
     21#!cpp
     22LOLUNIT_FIXTURE(MyFirstFixture)
     23{
     24};
     25}}}
     26
     27A '''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:
     28
     29{{{
     30#!cpp
     31LOLUNIT_FIXTURE(MyFirstFixture)
     32{
     33    LOLUNIT_TEST(MyFirstTest)
     34    {
     35    }
     36};
     37}}}
     38
     39== Add checks ==
     40
     41Several macros are provided to perform various checks:
     42 * `LOLUNIT_ASSERT(condition)` will cause the current test to fail if `condition` is not met.
     43 * `LOLUNIT_ASSERT_EQUAL(a, b)` will cause the current test to fail if `a` and `b` are not equal.
     44 * `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`.
     45
     46This is how to populate our fixture:
     47
     48{{{
     49#!cpp
     50LOLUNIT_FIXTURE(MyFirstFixture)
     51{
     52    LOLUNIT_TEST(Addition)
     53    {
     54        LOLUNIT_ASSERT_EQUAL(1 + 1, 2);
     55        LOLUNIT_ASSERT(2 + 2 < 5); /* Check that our value for 2 is not too large */
     56    }
     57
     58    LOLUNIT_TEST(Division)
     59    {
     60        double a = 1.0 / 2;
     61        double b = 1.0 / 3;
     62        double c = 1.0 / 6;
     63        LOLUNIT_ASSERT_DOUBLES_EQUAL(a - b, c, 1e-10);
     64    }
     65};
     66}}}
     67
     68== Run the test ==
     69
     70Fixtures and their tests are automatically registered in a list global to the program. A `TextTestRunner` object can then be used to run all tests:
     71
     72{{{
     73#!cpp
     74int main(void)
     75{
     76    lol::TextTestRunner runner;
     77    return !runner.run();
     78}
     79}}}
     80
     81And this is the output:
     82
     83{{{
     84..
     85
     86OK (2 tests)
     87}}}
     88
     89== Test failures ==
     90
     91Let's add yet another test to `MyFirstFixture`:
     92
     93{{{
     94#!cpp
     95    LOLUNIT_TEST(ExpectedFailure)
     96    {
     97        double a = 0.1;
     98        double b = 0.2;
     99        LOLUNIT_ASSERT_DOUBLES_EQUAL(a, b, 1e-10);
     100    }
     101}}}
     102
     103And running it:
     104
     105{{{
     106..F
     107
     108!!!FAILURES!!!
     109Test Results:
     110Run:  3  Failures: 1  Errors: 0
     111
     1121) test: MyFirstFixture::ExpectedFailure (F) line: 23 tutorial.cpp
     113double equality assertion failed
     114- Expected: a = 0.1
     115- Actual  : b = 0.2
     116- Delta   : 1e-10 = 1e-010
     117}}}
     118
     119
     120== Comparison with CppUnit ==
     121
     122LolUnit is very similar to CppUnit, except it requires fewer user input. This is what we would have done with CppUnit:
     123
     124{{{
     125#!cpp
     126#include <cppunit/extensions/HelperMacros.h>
     127#include <cppunit/extensions/TestFactoryRegistry.h>
     128#include <cppunit/TestCaller.h>
     129#include <cppunit/TestCase.h>
     130#include <cppunit/TestSuite.h>
     131#include <cppunit/TextTestRunner.h>
     132
     133class MyFirstFixture : public CppUnit::TestCase
     134{
     135    CPPUNIT_TEST_SUITE(MyFirstFixture);
     136        CPPUNIT_TEST(Addition);
     137        CPPUNIT_TEST(Division);
     138        CPPUNIT_TEST(ExpectedFailure);
     139    CPPUNIT_TEST_SUITE_END();
     140
     141    void Addition()
     142    {
     143        CPPUNIT_ASSERT_EQUAL(1 + 1, 2);
     144        CPPUNIT_ASSERT(2 + 2 < 5); /* Check that our value for 2 is not too large */
     145    }
     146
     147    void Division()
     148    {
     149        double a = 1.0 / 2;
     150        double b = 1.0 / 3;
     151        double c = 1.0 / 6;
     152        CPPUNIT_ASSERT_DOUBLES_EQUAL(a - b, c, 1e-10);
     153    }
     154
     155    void ExpectedFailure()
     156    {
     157        double a = 0.1;
     158        double b = 0.2;
     159        CPPUNIT_ASSERT_DOUBLES_EQUAL(a, b, 1e-10);
     160    }
     161};
     162CPPUNIT_TEST_SUITE_REGISTRATION(MyFirstFixture);
     163
     164int main(void)
     165{
     166    CppUnit::TextTestRunner runner;
     167    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
     168    return !runner.run();
     169}
     170}}}
     171
     172One 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.