Click here to Skip to main content
15,880,608 members
Articles / Programming Languages / C++
Article

Minimal unit test library for C++

Rate me:
Please Sign up or sign in to vote.
3.87/5 (6 votes)
4 Mar 20052 min read 47.3K   354   26   9
Very small (one header) tool to support unit tests in C++

Introduction

Minitest is library to help with unit testing. It provides very small set of features (one macro, two functions):
  • macro (MINITEST) to define a test
  • execute all tests, in random order (to uncover possible dependencies between the tests)
  • execute only tests from last modified source files (to shorten the edit - compile - test cycle)

Example of use:

#include <minitest.hpp>
#include <assert.h>

#ifndef NDEBUG

MINITEST
{
   assert(...);
} 

MINITEST
{
  ...
  assert(...);
  assert(...);
}

#endif //!NDEBUG

int main()
{
  minitest::execute_all_tests(); // execute all tests in random order
}

The tests could be put in many translation units (*.cpp files).

Background

There are quite a few of C++ test frameworks (for overview see e.g. here). The library presented here doesn't offer as many features as others with hope it will be useable without much of learning and will be modifiable easily.

The library could be used when adding *.cpp files of large framework is not possible, as first step in creating battery of tests before going with large framework or to create second, independent set of tests for an application.

Using the code

Create test case:

#include <minitest.hpp>

#ifdef DO_TESTING

// create test(s) on top level in *.cpp file (i.e. not within function)
MINITEST
{
  AClass object; // can be created?
} 

MINITEST
{
  if (pDatabase) {
    pDatabase->do_internal_test();    
  } else {
    assert(false);
  }
}
#endif //DO_TESTING

There's only one macro - definition of test. To do actual checking use assert() or debug tools of your preference.

Execute all tests:

Function minitest::execute_all_tests(bool) runs the tests in random or fixed order and returns information how many tests passed and details about possible faulty one (for details see structure minitest::result in header).

#include <iostream>
#include <minitest.hpp>

int main() 
{
   // run all tests in random order
   minitest::execute_all_tests(); 

   // run all tests in the same order as before 
   // (e.g. if a failure happens and we want to repeat it)
   minitest::execute_all_tests(false); 
   
  // run all tests (randomly) and evaluate result
  minitest::result res = minitest::execute_all_tests();
  if (res.all_tests_succeeded) 
  {
    std::cout << "All " << res.sucessful_tests_count << " tests OK.\n";
  } 
  else 
  {
    std::cout << "Only first " << res.sucessful_tests_count << " test(s) OK\n"
              << "The test in file " << res.failed_test_file << ", line " 
              << res.failed_test_line << " threw an exception.\n";
    // failed test can re re-run again
    res.failed_test();
  }
}

Random order of execution:

rand() is used (internally by std::random_shuffle()) to simulate randomness of testing. In order to repeat the same sequence of tests do one of following

  • call minitest::execute_all_tests(false) and no randomization will be done - last order of execution is preserved
  • set and remember seed for random generator (by srand()) and set it again when needed

Execute only tests from last changed sources:

If running the test takes too long you may wish to run just those that were affected by recent changes in source code. The library provides support for this:

#include <minitest.hpp>

int main() 
{
  // execute tests from 3 source files modified last
  minitest::result res = minitest::test_last_changed_files(3);
  if (res.all_tests_succeeded) {
    // as before
  }
}

The library checks timestamp of all source files, selects the N files modified last and executes only tests from these. This should help to speed up edit-compile-test cycle and keep one in flow.

However running all the tests should be done from time to time: dependecies between modules are not handled here!

Dealing with DLLs:

Calling minitest::execute_all_functions() in main() will not run tests in DLLs. You need to add helper function, like:

// pseudocode
void complete_app_test() 
{
  minitest::execute_all_tests(); // in main executable
  foreach( just_loaded_DLLs ) {
    invoke_execute_all_tests( a_dll );
  }
}

int main() 
{
  complete_app_test();
}

This nuisance is due to header-only implementation of the library.

Dependencies and portability

STL is required. The library uses couple of headers from Boost. If needed, these headers can be replaced with short hand-coded equivalent.

The library was tested with VC6, BCB6 and Intel C++. I expect it to work under Posix systems as well.

History

  • March 2nd, 2005: version 1.0 submitted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Czech Republic Czech Republic
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralSimple Memory Leak Fix Pin
kenearle1-Dec-05 7:32
kenearle1-Dec-05 7:32 
In minitest.hpp within static void remove_test, around line 93 or 96 depending on whether you grab the Boost or no-Boost version, change
if (p) return;
to
if (!p) return;

Then the leaks disappear.

I also tried
if (!p) burst_bladder();
- but then it leaked all over the placeSmile | :)

Cheers,
Ken



GeneralMemory leak Pin
Bob Stanneveld20-Apr-05 4:51
Bob Stanneveld20-Apr-05 4:51 
GeneralVersion not depending on Boost Pin
Pavel Vozenilek13-Mar-05 12:39
Pavel Vozenilek13-Mar-05 12:39 
QuestionRe: The link seems dead out Pin
haogege9-Apr-07 22:23
haogege9-Apr-07 22:23 
GeneralI didn't really follow the article, but... Pin
David Pritchard10-Mar-05 9:53
David Pritchard10-Mar-05 9:53 
GeneralIs it minimal or ... Pin
A899344s5-Mar-05 8:59
sussA899344s5-Mar-05 8:59 
GeneralRe: Is it minimal or ... Pin
Pavel Vozenilek7-Mar-05 7:13
Pavel Vozenilek7-Mar-05 7:13 
GeneralRe: Is it minimal or ... Pin
Ed K9-Mar-05 14:45
Ed K9-Mar-05 14:45 
GeneralRe: Is it minimal or ... Pin
FocusedWolf23-Nov-06 12:58
FocusedWolf23-Nov-06 12:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.