Jafar
Unit Test in Jafar

Overview

In order to implement testing suites in modules we make use of Unit Test Framework from the Boost Test Library. It provides the Unit Test Framework which is a convenient way to write tests, run them and report test failures. It heavily relies on macro to make things simpler and faster for developpers.

The Boost Unit Test Framework relies on three concepts. From bottom to top:

Writing a test suite for your module

The directory test_suite already contains a test_suite_module.cpp file that you will extend. We recommend that you group your test functions and classes in seperate .hpp files you #include in test_suite_module.cpp.

Depending on the size of your module and the number of classes and functions you want to test, we recommend two methods to write a test suite for your module:

There are a lot of other ways to write test case (Test Case).

Most used macros

Among all the macro defined in the Test Tools (Refererences to all test tools), some of them should be of common use:

For floating point values, a special macro must be used :

You should have used exceptions to report errors, and you may want to test functions in order to check if they really throw the correct exception when expected. Test Tools provide several macro which should meet your needs:

Example

Using a single Test Suite per module

This is a very simple example, out of the boost documentation examples (unit_test_example2):

#include <boost/test/unit_test.hpp>
using boost::unit_test_framework::test_suite;

void force_division_by_zero()
{
    // unit test framework can catch operating system signals
    BOOST_CHECKPOINT("About to force division by zero!");
    int i = 1, j = 0;
    i = i / j;
}

void infinite_loop()
{
    // unit test framework can break infinite loops by timeout
#ifdef __unix  // don't have timeout on other platforms
    BOOST_CHECKPOINT("About to enter an infinite loop!");
    while(1);
#else
    BOOST_MESSAGE( "Timeout support is not implemented on your platform" );
#endif
}

test_suite*
init_unit_test_suite( int argc, char * argv[] ) {
    test_suite* test= BOOST_TEST_SUITE( "Unit test example 2" );

    test->add( BOOST_TEST_CASE( &force_division_by_zero ) );
    test->add( BOOST_TEST_CASE( &infinite_loop ), 0, /* timeout  2 );

    return test; 
}

Using multiple Test Suite per module

This particular example comes from helloword module in which there is only one class to test. The test_HelloWorld class comes in a seperate .cpp file.

/* $Id$ */

// boost unit test includes
#define BOOST_TEST_MAIN 
#define BOOST_TEST_DYN_LINK 
#include <boost/test/auto_unit_test.hpp>
using boost::unit_test_framework::test_suite;
using boost::unit_test_framework::test_case;

// jafar debug include
#include "kernel/jafarDebug.hpp"

// include here your defined test suite
#include "test_suite_HelloWorldClass.hpp"

using namespace jafar::helloworld;

BOOST_AUTO_TEST_CASE ( test_hello_world )
{
  test_HelloWorld thw;

  thw.test_init();
  thw.test_setHello();
  thw.test_clearHello();
}

/*
 * standard init_unit_test_suite function
 */

test_suite*
init_unit_test_suite( int, char* [] ) {

  // we set the debug level to Warning
  jafar::debug::DebugStream::setDefaultLevel(jafar::debug::DebugStream::Warning);

  return 0;
}
/* $Id$ */

// test suite specific includes
#include "helloworld/helloWorld.hpp"
#include "helloworld/helloworldException.hpp"

namespace jafar {

  namespace helloworld {

    /* 
     * class HelloWorld test suite 
     */

    class test_HelloWorld {

    public:

      HelloWorld hw;
      HelloWorld hw2;

      test_HelloWorld() : hw(), hw2("Hello world") {}

      void test_init() {
        BOOST_CHECK_EQUAL(hw.getHello().size(), 0);
        BOOST_CHECK_EQUAL(hw2.getHello(), "Hello world");
      }

      void test_setHello() {
        hw.setHello("Hello world");
        BOOST_CHECK_EQUAL(hw.getHello(), "Hello world");

        BOOST_CHECK_THROW(hw.setHello(""), jafar::kernel::JafarException);

        BOOST_CHECK_THROW(hw.setHello("what ever"), HelloworldFormatException);
      }

      void test_clearHello() {
        hw.clearHello();
        BOOST_CHECK_EQUAL(hw.getHello().size(), 0);
      }
    };
  } // namespace helloworld

} // namespace jafar

To go further...

Of course the Boost Unit Test Framework is far more powerfull... You can for example use parameters of your test case function to run a same test on a set of values, use C++ templates to define generic tests,...

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:30 for Jafar by doxygen 1.7.6.1
LAAS-CNRS