Reputation: 2691
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
Reputation: 3385
There is simply the --list_content command line option, exactly for that purpose.
Upvotes: 6
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
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_MESSAGE
s 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