Felix
Felix

Reputation: 2691

getting all boost test suites / test cases

As the title says, I want to get all test suites or test cases (name) from a test application, ether in the console or as xml output. Test framework is the boost test library.

Is there an option to achieve this? I did not found anything useful in the documentation.

Upvotes: 6

Views: 4355

Answers (3)

Raffi
Raffi

Reputation: 3385

There is simply the --list_content command line option, exactly for that purpose.

Upvotes: 6

ToniBig
ToniBig

Reputation: 836

This can be done without much intrusion using a global fixture. Assuming you have a translation unit (cpp file) that contains main explicitly or auto generated, you can intercept test execution when a certain command line argument is provided. Then you can traverse the test tree using a customized visitor, which lists all available tests. Here is a small working example, which creates a test runner by compiling and linking files main_test.cpp, a.cpp and b.cpp:

main_test.cpp

#include <string>
#include <iostream>

// --- Boost Includes ---
#define BOOST_TEST_MODULE MyTestSuite
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

using namespace boost::unit_test;

struct Visitor : test_tree_visitor
{
  size_t level = 0;

  void visit( test_case const& test )
  {
    std::string indentation( level, '.' );

    std::cout << indentation << test.p_name << std::endl;
  }

  bool test_suite_start( test_suite const& suite )
  {
    std::string indentation( level, '.' );
    level++;

    std::cout << indentation << "Suite: " << suite.p_name << std::endl;
    return true;
  }

  void test_suite_finish( test_suite const& suite )
  {
    level--;
  }
};

struct GlobalFixture
{
  GlobalFixture( )
  {
    int argc = framework::master_test_suite( ).argc;
    for ( int i = 0; i < argc; i++ )
    {
      std::string argument( framework::master_test_suite( ).argv[i] );

      if ( argument == "list" )
      {
        Visitor visitor;

        traverse_test_tree( framework::master_test_suite( ), visitor );

        exit( EXIT_SUCCESS );
      }
    }
  }

};

BOOST_GLOBAL_FIXTURE( GlobalFixture )

a.cpp

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE ( TestA )

BOOST_AUTO_TEST_CASE ( TestFoo )
{
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE ( TestBar )
{
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_SUITE_END() // TestA

b.cpp

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE ( TestB )

BOOST_AUTO_TEST_CASE ( TestFoo )
{
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_CASE ( TestBar )
{
  BOOST_CHECK(true);
}

BOOST_AUTO_TEST_SUITE_END() // TestA

Invoking the runner without any arguments results in

./somelib_testrunner1 
Running 4 test cases...

*** No errors detected

Passing the argument list used in the fixture defined above results in

Suite: MyTestSuite
.Suite: TestA
..TestFoo
..TestBar
.Suite: TestB
..TestFoo
..TestBar

Upvotes: 4

DeVadder
DeVadder

Reputation: 1404

I am afraid there is no easy way to do this without actually running the tests.

And even then the only thing coming to my mind without touching the code would be --log_level=test_suite and some sort of parsing script that finds the "Entering test suite", "Leaving test suite" and "Entering test case" messages (or parsing the xml given when you also put --log_format=XML, if you have a xml parser at hand).

But even that spoils the log with your added BOOST_TEST_MESSAGEs and of course encountered errors and warnings.

Seeing how the boost test framework is not much more than a bunch of macros, defined in the header, you could of course add the functionality yourself, probably easiest by adding another log format just listing the suites and tests, assuming you are fine with running the tests while finding the list.

Upvotes: 1

Related Questions