问题
I'm working with CPPUNIT 1.12.1.
It has those macro defined:
#define CPPUNIT_TEST_SUITE_ADD_TEST( test ) \
context.addTest( test )
#define CPPUNIT_TEST( testMethod ) \
CPPUNIT_TEST_SUITE_ADD_TEST( \
( new CPPUNIT_NS::TestCaller<TestFixtureType>( \
context.getTestNameFor( #testMethod), \
&TestFixtureType::testMethod, \
context.makeFixture() ) ) )
I want to add many tests to the same test suite using templates (as CPPUNIT works, every test must be a void
function, so using template makes it possible to call the same void
function with different "parameters"...).
This works perfectly:
class MyTestSuite1 : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(MyTestSuite1);
CPPUNIT_TEST(doTest<false>);
CPPUNIT_TEST(doTest<true>);
CPPUNIT_TEST_SUITE_END();
template<bool param> void doTest() { /* test here */ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite1);
while this does not:
class MyTestSuite2 : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(MyTestSuite2);
CPPUNIT_TEST(doTest<false,false>);
CPPUNIT_TEST(doTest<true,false>);
CPPUNIT_TEST_SUITE_END();
template<bool param1,bool param2> void doTest() { /* test here */ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite2);
Compiler (Visual Studio 2015) reports:
1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(20): warning C4002: too many actual parameters for macro 'CPPUNIT_TEST' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(21): warning C4002: too many actual parameters for macro 'CPPUNIT_TEST' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(20): error C2059: syntax error: ')' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(21): error C2059: syntax error: ')' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(22): error C2143: syntax error: missing ';' before '}' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(22): error C2065: 'namer': undeclared identifier 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(22): error C2065: 'factory': undeclared identifier 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(22): error C2059: syntax error: ')' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(29): error C2143: syntax error: missing ';' before '{' 1>b:\dev\vobs_diabeloop\private\tst\regulation\cppunit\hyper_ftac3\test.cpp(30): error C2143: syntax error: missing ';' before '{'
Why is that? How could the macro handle correctly 1 template parameter, but fails for two? Any idea how I could easily have it compile and work?
Edit:
Already tried CPPUNIT_TEST((doTest<false,false>));
without success (getting error C2143: syntax error: missing ';' before ')'
)
回答1:
CPPUNIT_TEST(doTest<false,false>);
This one doesn't work because macro thinks you are passing 2 macro parameters: doTest<false
and false>
.
CPPUNIT_TEST((doTest<false,false>));
This doesn't work because &TestFixtureType::testMethod
will expand to &TestFixtureType::(doTest<false,false>)
which is invalid.
As mentioned by Piotr in comment, you can use this code:
#define COMMA ,
class MyTestSuite2 : public CPPUNIT_NS::TestFixture
{
CPPUNIT_TEST_SUITE(MyTestSuite2);
CPPUNIT_TEST(doTest<false COMMA false>);
CPPUNIT_TEST(doTest<true COMMA false>);
CPPUNIT_TEST_SUITE_END();
template<bool param1, bool param2> void doTest() { /* test here */ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MyTestSuite2);
Because pre-processor sees that you want to pass 1 parameter
回答2:
,
is parsed as separator in MACRO (except when surrounded by parent).
way of work-around
using intermediate MACRO:
#define COMMA ,
CPPUNIT_TEST(doTest<false COMMA false>);
Or fix your original MACRO to handle comma:
#define CPPUNIT_TEST(testMethod, ...) \
CPPUNIT_TEST_SUITE_ADD_TEST( \
( new CPPUNIT_NS::TestCaller<TestFixtureType>( \
context.getTestNameFor( #testMethod), \
&TestFixtureType::testMethod , ##__VA_ARGS__, \
context.makeFixture() ) ) )
回答3:
does this work?
CPPUNIT_TEST((doTest<false,false>));
CPPUNIT_TEST((doTest<true,false>));
sometimes Macros can be tricky when parsing commas...
来源:https://stackoverflow.com/questions/41565773/why-this-macro-accepts-a-template-with-1-parameter-and-refuses-a-template-with-2