正在对物理模拟进行翻新,我正在尝试为要使用类型参数化测试替换的功能编写单元测试。基本设置如下所示:
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
}
}
由于基类和生成的值的数量很大,所以我想将当前(假定正确)版本的输出写入文件,并将新版本的输出与这些值进行比较。函数(func)随TypeParam的变化而变化,因此我还需要以某种形式保存使用的基类。
但是,我不知道如何识别所使用的基类:一种解决方案是保存和比较typeid,就像保存
typeid(TypeParam).name()
与结果一起使用,但是有人告诉我,这是可以在机器之间更改的值,因此,不能用作要使用的值。我试图在MyTypes中找到相应的条目,即为其中的一个保存
std::is_same<MyTypes[i],TypeParam>::value
是正确的,但对于任何i来说似乎并非如此。使用类型参数化测试有什么好的方法吗?还是我需要完全使用其他东西?
答案 0 :(得分:0)
您可以将base1<1>
,base1<2>
,base2<1>
,base2<2>
,...用一维整数0
,1
,{ {1}},2
,...使用以下类模板3
。
更具体地说,TestsWrapper
返回类型TestsWrapper<...T>::getIdx<U>()
在parameter pack U
中的位置。
例如,
...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
:
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...>();
}
};
是上面的整数标签idx
,0
,1
,2
,...,并保存了当前正在测试的类型。
您可以使用此标签来标识当前测试的类。
我已经检查过这种方法是否可以在我的Windows环境中正常工作:
3