c++unit-testingboostboost-test

Disabling specific test instance defined from a dataset


Let's say I have the following test code:

struct MyData
{
    MyData( int in_, double out_ )
    : m_in{ in_ }
    , m_out{ out_ }
    {}

    int    m_in;
    double m_out;
};

std::ostream& operator<<( std::ostream& os_, MyData data_ )
{
    os_ << data_.m_in << " " << data_.m_out << std::endl;
    return os_;
}

std::vector< MyData > DataSetGet()
{
    return
        {
            { 1, 1.0 },
            { 2, 2.0 }, // I would like to disable this...
            { 3, 3.0 },
        };
}

BOOST_DATA_TEST_CASE( CastIntToDouble, DataSetGet() )
{
    BOOST_TEST( static_cast< double >( sample.m_in ) == sample.m_out );
}

I would like to disable the second test instance. I could just comment out the second case, like this:

std::vector< MyData > DataSetGet()
{
    return
        {
            { 1, 1.0 },
            //{ 2, 2.0 }, // I would like to disable this...
            { 3, 3.0 },
        };
}

but then this case would no longer be compiled, which is not what I am looking for. In my real scenario, test cases are more complex and I would like them compiled, but not run.

I have searched the boost documentation on this topic and I came across the disable decorator, which looks like what I need. However, I have found no way to use it in data test cases. Is this possible?


Solution

  • You can supply a command line argument, like:

    ./sotest -l all -t "!*/*_1"
    

    Which outputs:

    enter image description here

    More Advanced/Dynamic

    You could also supply your own decorator based on enable_if, which you could make to use your own custom command line options (you'll need to supply your own test_main to parse those).

    For an example of such custom decorator: https://www.boost.org/doc/libs/1_78_0/libs/test/doc/html/boost_test/tests_organization/enabling.html#boost_test.tests_organization.enabling.runtime_run_status

    Live Demo

    Live On Coliru

    #define BOOST_TEST_MODULE StackOverflow
    #include <boost/test/unit_test.hpp>
    #include <boost/test/data/dataset.hpp>
    #include <boost/test/data/test_case.hpp>
    #include <boost/test/unit_test_parameters.hpp>
    
    namespace but = boost::unit_test;
    namespace utf = boost::unit_test_framework;
    
    struct MyData {
        MyData(int in_, double out_) : m_in{in_}, m_out{out_} {}
    
        int    m_in;
        double m_out;
    };
    
    std::ostream& operator<<(std::ostream& os_, MyData data_) {
        return os_ << data_.m_in << " " << data_.m_out << std::endl;
    }
    
    std::vector<MyData> DataSetGet()
    {
        return {
            {1, 1.0},
            {2, 2.0}, // I would like to disable this...
            {3, 3.0},
        };
    }
    
    BOOST_DATA_TEST_CASE(CastIntToDouble, DataSetGet())
    {
        BOOST_TEST( static_cast< double >( sample.m_in ) == sample.m_out );
    }
    

    Run with

    g++ -std=c++20 -O2 -Wall -pedantic -pthread main.cpp -lboost_unit_test_framework
    ./a.out -l all -t "!*/*_1" --no_color_output
    

    Prints

    Running 2 test cases...
    Entering test module "StackOverflow"
    main.cpp(30): Entering test suite "CastIntToDouble"
    main.cpp(30): Entering test case "_0"
    main.cpp(32): info: check static_cast< double >( sample.m_in ) == sample.m_out has passed
    Assertion occurred in a following context:
        sample = 1 1
    ; 
    main.cpp(30): Leaving test case "_0"; testing time: 443us
    main.cpp(30): Test case "CastIntToDouble/_1" is skipped because disabled
    main.cpp(30): Entering test case "_2"
    main.cpp(32): info: check static_cast< double >( sample.m_in ) == sample.m_out has passed
    Assertion occurred in a following context:
        sample = 3 3
    ; 
    main.cpp(30): Leaving test case "_2"; testing time: 404us
    main.cpp(30): Leaving test suite "CastIntToDouble"; testing time: 967us
    Leaving test module "StackOverflow"; testing time: 1016us
    
    *** No errors detected