admin管理员组

文章数量:1336632

In Boost.Test, I'd like to test a function for different values, each value associated to an expected result.

Something like (I know, the test is stupid):

void SquareTest(int expectedResult, int input)
{
    BOOST_CHECK_EQUAL(expectedResult, MySquareFunctionToTest(input));
}

BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest,  4, 2);
BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest,  9, 3);
BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest, 16, 4);

Is there a way to do that with Boost.Test ? The parametrized section int the documentation doesn't seem to match to my need.

In Boost.Test, I'd like to test a function for different values, each value associated to an expected result.

Something like (I know, the test is stupid):

void SquareTest(int expectedResult, int input)
{
    BOOST_CHECK_EQUAL(expectedResult, MySquareFunctionToTest(input));
}

BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest,  4, 2);
BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest,  9, 3);
BOOST_AUTO_FUNCTION_TEST_CASE(SquareTest, 16, 4);

Is there a way to do that with Boost.Test ? The parametrized section int the documentation doesn't seem to match to my need.

Share Improve this question asked Nov 19, 2024 at 16:49 OodiniOodini 1,3471 gold badge9 silver badges19 bronze badges 2
  • why do you want a macro for this? Instead of the macro why not just BOOST_CHECK_EQUAL(4,MySquareFunctioNToTest(2)) and same for the other 2 cases – 463035818_is_not_an_ai Commented Nov 19, 2024 at 20:00
  • BOOST_CHECK_EQUAL() must be then inside a test case. – Oodini Commented Nov 19, 2024 at 21:30
Add a comment  | 

1 Answer 1

Reset to default 1

I would suggest the simple:

Live On Coliru

#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>

int MySquareFunctionToTest(int x) { return x * x; }

void SquareTest(int expectedResult, int input) {
    BOOST_CHECK_EQUAL(expectedResult, MySquareFunctionToTest(input));
}

BOOST_AUTO_TEST_CASE(SquareTest1) { SquareTest(4, 2); }
BOOST_AUTO_TEST_CASE(SquareTest2) { SquareTest(9, 3); }
BOOST_AUTO_TEST_CASE(SquareTest3) { SquareTest(16, 4); }

If you really feel like getting the Enterprise(TM) version on:

Data Driven Test Cases

These were added for very good rationale, that probably resonate with you, since you were asking this question:

The approach above has several drawbacks:

  • the logic for running the tests is inside a test itself: single_test in the above example is run from the test case combined_test while its execution would be better handled by the Unit Test Framework
  • in case of fatal failure for one of the values in param array above (say a failure in BOOST_TEST_REQUIRE), the test combined_test is aborted and the next test-case in the test tree is executed.
  • in case of failure, the reporting is not accurate enough: the test should certainly be reran during debugging sessions by a human or additional logic for reporting should be implemented in the test itself.

(and much more)

Example:

#include <boost/test/data/test_case.hpp>
namespace bdata = boost::unit_test::data;

BOOST_DATA_TEST_CASE(SquareDataDrivenTest, bdata::make({2, 3, 4}), input) {
    SquareTest(input * input, input);
}

Of course, that's cheating. While

bdata::make({std::pair{2, 4}, {3, 9}, {4, 16}})

will work, it would require you to add printability to std::pair. To avoid that, consider:

struct Params {
    int a, a_squared;

    friend std::ostream& operator<<(std::ostream& os, const Params& p){
        return os << "a=" << p.a << ", a_squared=" << p.a_squared;
    }
};

BOOST_DATA_TEST_CASE(SquareDataDrivenTest2,                        //
                     bdata::make({Params{2, 4}, {3, 9}, {4, 16}}), //
                     input) {
    auto [a, a2] = input;
    SquareTest(a2, a);
}

Live On Coliru

https://coliru.stacked-crooked/a/8cbcc9f6bfb967b1

#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_parameters.hpp>

int MySquareFunctionToTest(int x) { return x * x; }

void SquareTest(int expectedResult, int input) {
    BOOST_CHECK_EQUAL(expectedResult, MySquareFunctionToTest(input));
}

BOOST_AUTO_TEST_CASE(SquareTest1) { SquareTest(4, 2); }
BOOST_AUTO_TEST_CASE(SquareTest2) { SquareTest(9, 3); }
BOOST_AUTO_TEST_CASE(SquareTest3) { SquareTest(16, 4); }

// Now doing these with Data-Driven test cases:

#include <boost/test/data/test_case.hpp>
namespace bdata = boost::unit_test::data;

BOOST_DATA_TEST_CASE(SquareDataDrivenTest, bdata::make({2, 3, 4}), input) {
    SquareTest(input * input, input);
}

struct Params {
    int a, a_squared;

    friend std::ostream& operator<<(std::ostream& os, const Params& p){
        return os << "a=" << p.a << ", a_squared=" << p.a_squared;
    }
};

BOOST_DATA_TEST_CASE(SquareDataDrivenTest2,                        //
                     bdata::make({Params{2, 4}, {3, 9}, {4, 16}}), //
                     input) {
    auto [a, a2] = input;
    SquareTest(a2, a);
}

Printing:

Running 9 test cases...

*** No errors detected

Or, -l all:

Running 9 test cases...
Entering test module "MyTest"
/home/sehe/Projects/stackoverflow/test.cpp(11): Entering test case "SquareTest1"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
/home/sehe/Projects/stackoverflow/test.cpp(11): Leaving test case "SquareTest1"; testing time: 21us
/home/sehe/Projects/stackoverflow/test.cpp(12): Entering test case "SquareTest2"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
/home/sehe/Projects/stackoverflow/test.cpp(12): Leaving test case "SquareTest2"; testing time: 18us
/home/sehe/Projects/stackoverflow/test.cpp(13): Entering test case "SquareTest3"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
/home/sehe/Projects/stackoverflow/test.cpp(13): Leaving test case "SquareTest3"; testing time: 18us
/home/sehe/Projects/stackoverflow/test.cpp(20): Entering test suite "SquareDataDrivenTest"
/home/sehe/Projects/stackoverflow/test.cpp(20): Entering test case "_0"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = 2; 
/home/sehe/Projects/stackoverflow/test.cpp(20): Leaving test case "_0"; testing time: 20us
/home/sehe/Projects/stackoverflow/test.cpp(20): Entering test case "_1"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = 3; 
/home/sehe/Projects/stackoverflow/test.cpp(20): Leaving test case "_1"; testing time: 18us
/home/sehe/Projects/stackoverflow/test.cpp(20): Entering test case "_2"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = 4; 
/home/sehe/Projects/stackoverflow/test.cpp(20): Leaving test case "_2"; testing time: 17us
/home/sehe/Projects/stackoverflow/test.cpp(20): Leaving test suite "SquareDataDrivenTest"; testing time: 62us
/home/sehe/Projects/stackoverflow/test.cpp(32): Entering test suite "SquareDataDrivenTest2"
/home/sehe/Projects/stackoverflow/test.cpp(32): Entering test case "_0"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = a=2, a_squared=4; 
/home/sehe/Projects/stackoverflow/test.cpp(32): Leaving test case "_0"; testing time: 19us
/home/sehe/Projects/stackoverflow/test.cpp(32): Entering test case "_1"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = a=3, a_squared=9; 
/home/sehe/Projects/stackoverflow/test.cpp(32): Leaving test case "_1"; testing time: 18us
/home/sehe/Projects/stackoverflow/test.cpp(32): Entering test case "_2"
/home/sehe/Projects/stackoverflow/test.cpp(8): info: check expectedResult == MySquareFunctionToTest(input) has passed
Assertion occurred in a following context:
    input = a=4, a_squared=16; 
/home/sehe/Projects/stackoverflow/test.cpp(32): Leaving test case "_2"; testing time: 18us
/home/sehe/Projects/stackoverflow/test.cpp(32): Leaving test suite "SquareDataDrivenTest2"; testing time: 60us
Leaving test module "MyTest"; testing time: 193us

*** No errors detected

Note how the data driven test cases report context with their invocations.

本文标签: cBoost test how to parametrize a test with input and outputStack Overflow