我想在一系列值和类型上测试一个模板函数。比如
template <class T>
void foo(Bar<T>&);
但问题是我不能得到谷歌测试的值参数化测试与模板测试套件的工作。目前我的大多数测试都是这样的:
TYPED_TEST(FooTest, foo) {
for (int repeats = 0 ...) { // don't want this
Bar<TypeParam> bar;
for (... i < repeats ...)
foo(bar);
EXPECT_EQ(bar, /*...*/);
}
}
所以我正在寻找一种方法来摆脱第一个for循环,并将repeats
传递为const参数。如果您想知道,这里是真正的测试文件。虽然现在不是完全这样,因为我正在重构这段代码。
我已经试过了:
using NumericTypes = ::testing::Types<uint8_t /*...*/ >;
template <class T>
class FooTest
: public ::testing::TestWithParam<const int> { };
TYPED_TEST_SUITE(FooTest,
NumericTypes,
TestingTypenames);
INSTANTIATE_TEST_SUITE_P(SomeFooTest,
FooTest,
testing::Range(0,3));
得到的错误:
foo.cpp: error: template argument 1 is invalid
16 | INSTANTIATE_TEST_SUITE_P(SomeFooTest,
| ^~~~~~~~~~~~~~~~~~~~~~~~
所以这些类型参数化测试为我创造了奇迹,只是for循环让我感到困扰。在我编写的新测试中,将有3层for循环,因为我正在测试嵌套列表,如果它们嵌套,它们的行为将会不同。
如果可以的话,将值作为模板参数传递或将类型作为值传递要容易得多。
使用值作为模板参数的示例:
#include <variant>
#include <gtest/gtest.h>
template<typename T, T value>
struct param1 {
static T get(){ return value; }
};
template <typename >
class example1
: public ::testing::Test { };
using params = ::testing::Types<
param1<uint8_t, 0>,
param1<uint8_t, 1>,
param1<uint16_t, 0>
>;
TYPED_TEST_SUITE(example1, params);
TYPED_TEST(example1, test) {
ASSERT_TRUE(TypeParam::get() < 2);
}
并以类型作为值:
using param2 = std::variant<uint8_t, uint16_t>;
class example2 : public ::testing::TestWithParam<param2> {};
INSTANTIATE_TEST_SUITE_P(foo, example2, testing::Values<param2>(
uint8_t(0),
uint8_t(1),
uint16_t(0)
));
TEST_P(example2, test) {
std::visit([&](auto value){
ASSERT_TRUE(value < 2);
}, GetParam());
}