Boost logo

Boost :

From: Noel Llopis (nll_pub_at_[hidden])
Date: 2005-01-11 17:57:16


On Tuesday 11 January 2005 14:03, Gennadiy Rozental wrote:

> > What was the reason behind the choice of using the function
> > init_unit_test_suite() as the initialization point? Why not let the
> > user create
> > main() and use a very simple object to accomplish the same thing.
>
> > Something along these lines:
> >
> > int main ( int /* argc */, char* /* argv */ [] )
> > {
> > test_suite * testsuite = BOOST_TEST_SUITE("Master test suite");
> > testrunner runner(testsuite);
> > return runner.run();
> > }
>
> 1. If you take a look into unit_test_main.cpp you notice that there is
> quire a lot of things that needs to be done before test is initialized
> and run

Nothing that can't be easily wrapped in an object like the example above.

> 4. There may be other things in framework housekeeping that may needs to
> be done pre/post test execution

Right, but you can wrap all that inside a separate function instead of
taking over main().

> Anything you want to do pre/post your test is part of fixure, isn't it?

No. In this case I was thinking of tasks that I might have to do around the
test run myself. For example, I don't think I could use Boost.Test with a
Win32 application (as opposed to a DOS box). Also, I might want to set up
some things conditionally depending on whether the debugger is attached or
not.

In general, it seems like a much better idea to let the user run the tests
from anywhere they want as opposed to taking over main. For example,
sometimes people like to embed the tests themselves into the program
they're building, and running the tests if they pass a command-line
parameter. This setup would allow them to do that without any problem.

The ideal situation would be to wrap the contents of the current main in an
object, and then provide a macro that gives you a main function calling
that object. Those of us who need more control, we can write our own main
and pass all the necessary parameters.

That's one of the areas that I think CppUnit did a really good job. This is
how one possible main looks for them:

int main( int argc, char* argv[] )
{
  // Create the event manager and test controller
  CPPUNIT_NS::TestResult controller;

  // Add a listener that colllects test result
  CPPUNIT_NS::TestResultCollector result;
  controller.addListener( &result );

  // Add the top suite to the test runner
  CPPUNIT_NS::TestRunner runner;
  runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );
  runner.run( controller );

  // Print test in a compiler compatible format.
  CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr );
  outputter.write();

  return result.wasSuccessful() ? 0 : 1;
}

It's very configurable, and it can be called from anywhere. It might be a
bit long, but you're only going to write it once per test project, so it's
not a big deal at all.

--Noel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk