使用 googletest 在类型参数化测试中识别使用的基数 class
Identifying the used base class in a type-parameterized Test using googletest
正在翻新物理模拟,我正在尝试为要使用类型参数化测试替换的函数编写单元测试。基本设置如下所示:
using MyTypes = ::testing::Types<base1<1>, base1<2>, base2<1>, base2<2>>;
TYPED_TEST_CASE(tests, MyTypes);
TYPED_TEST(tests, testname){
auto obj = clname(TypeParam);
auto parameters = generate_values(TypeParam);
for( auto& p : parameters ){
// Test if obj.func(p) equals the saved values
}
}
由于基础 classes 和生成值的数量很大,我想将当前(假定正确)版本的输出写入文件并将新版本的输出与这些进行比较值。函数 (func) 根据 TypeParam 的不同而变化,因此我还需要以某种形式保存使用的基数 class。
但是,我不知道如何识别使用的基数 class:一种解决方案是保存并比较 typeid,如保存
typeid(TypeParam).name()
连同结果,但有人告诉我,这个值可以在机器之间改变,因此作为一个值没有用处。我试图在 MyTypes 中找到相应的条目,即为
保存 i
std::is_same<MyTypes[i],TypeParam>::value
是对的,但对任何i来说似乎都不是这样。有没有什么好的方法可以通过类型参数化测试来做到这一点?还是我需要完全使用其他东西?
您可以用一维整数标记 base1<1>
、base1<2>
、base2<1>
、base2<2>
、... 0
、1
, 2
, 3
, ... 使用以下 class 模板 TestsWrapper
。
更具体地说,TestsWrapper<...T>::getIdx<U>()
returns 类型 U
在 parameter pack ...T
中的位置。
例如,
TestsWrapper<A,B,C,D,E>::getIdx<A>()
是 0
、
TestsWrapper<A,B,C,D,E>::getIdx<B>()
是 1
、
TestsWrapper<A,B,C,D,E>::getIdx<C>()
是 2
,
等等。
这使我们能够在编译时将测试的 class 识别为 TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>::getIdx<TypeParam>()
:
template<class ...T>
class TestsWrapper
{
template<class U>
static constexpr std::size_t getIdx_impl()
{
return 0;
}
template<class U, class T0, class ...Ts>
static constexpr std::size_t getIdx_impl()
{
return std::is_same<U, T0>::value ? 0 : (getIdx_impl<U, Ts...>() + 1);
}
public:
using Types = ::testing::Types<T...>;
template<class U>
static constexpr std::size_t getIdx()
{
return getIdx_impl<U, T...>();
}
};
此class模板用于类型测试的用法示例如下。
这里idx
就是上面的整数标签0
、1
、2
、3
、……保存当前测试的是哪种类型。
您可以使用此标签来标识当前测试的 class。
我已经检查过这种方法在我的 Windows 环境中运行良好:
using TWrapper = TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>;
template <typename T>
class test : public ::testing::Test {};
TYPED_TEST_CASE(test, TWrapper::Types);
TYPED_TEST(test, testname)
{
constexpr auto idx = TWrapper::getIdx<TypeParam>();
...
}
正在翻新物理模拟,我正在尝试为要使用类型参数化测试替换的函数编写单元测试。基本设置如下所示:
using MyTypes = ::testing::Types<base1<1>, base1<2>, base2<1>, base2<2>>;
TYPED_TEST_CASE(tests, MyTypes);
TYPED_TEST(tests, testname){
auto obj = clname(TypeParam);
auto parameters = generate_values(TypeParam);
for( auto& p : parameters ){
// Test if obj.func(p) equals the saved values
}
}
由于基础 classes 和生成值的数量很大,我想将当前(假定正确)版本的输出写入文件并将新版本的输出与这些进行比较值。函数 (func) 根据 TypeParam 的不同而变化,因此我还需要以某种形式保存使用的基数 class。
但是,我不知道如何识别使用的基数 class:一种解决方案是保存并比较 typeid,如保存
typeid(TypeParam).name()
连同结果,但有人告诉我,这个值可以在机器之间改变,因此作为一个值没有用处。我试图在 MyTypes 中找到相应的条目,即为
保存 istd::is_same<MyTypes[i],TypeParam>::value
是对的,但对任何i来说似乎都不是这样。有没有什么好的方法可以通过类型参数化测试来做到这一点?还是我需要完全使用其他东西?
您可以用一维整数标记 base1<1>
、base1<2>
、base2<1>
、base2<2>
、... 0
、1
, 2
, 3
, ... 使用以下 class 模板 TestsWrapper
。
更具体地说,TestsWrapper<...T>::getIdx<U>()
returns 类型 U
在 parameter pack ...T
中的位置。
例如,
TestsWrapper<A,B,C,D,E>::getIdx<A>()
是0
、TestsWrapper<A,B,C,D,E>::getIdx<B>()
是1
、TestsWrapper<A,B,C,D,E>::getIdx<C>()
是2
,
等等。
这使我们能够在编译时将测试的 class 识别为 TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>::getIdx<TypeParam>()
:
template<class ...T>
class TestsWrapper
{
template<class U>
static constexpr std::size_t getIdx_impl()
{
return 0;
}
template<class U, class T0, class ...Ts>
static constexpr std::size_t getIdx_impl()
{
return std::is_same<U, T0>::value ? 0 : (getIdx_impl<U, Ts...>() + 1);
}
public:
using Types = ::testing::Types<T...>;
template<class U>
static constexpr std::size_t getIdx()
{
return getIdx_impl<U, T...>();
}
};
此class模板用于类型测试的用法示例如下。
这里idx
就是上面的整数标签0
、1
、2
、3
、……保存当前测试的是哪种类型。
您可以使用此标签来标识当前测试的 class。
我已经检查过这种方法在我的 Windows 环境中运行良好:
using TWrapper = TestsWrapper<base1<1>, base1<2>, base2<1>, base2<2>>;
template <typename T>
class test : public ::testing::Test {};
TYPED_TEST_CASE(test, TWrapper::Types);
TYPED_TEST(test, testname)
{
constexpr auto idx = TWrapper::getIdx<TypeParam>();
...
}