2016-11-18 62 views
1

我想知道单元测试模板是否是一件事情。让我解释我的需求。单元测试高度模板化库

我有一个高度模板化的库。我有很多sfinae类型的特征,还有一些static_assert。

我想测试的是sfinae类型特征的有效性,并测试我的static_assert是否投掷正确的东西。知道我的报道会很棒。

这里有一个例子我的代码如下所示:

template<typename T> 
using false_v = !std::is_same<T, T>::value; 

// Here are my types traits 
template<typename T, typename... Args> 
struct SomeCondition1 { /* ... */ }; 

template<typename T, typename... Args> 
struct SomeCondition2 { /* ... */ }; 

// This is a master type trait, that test every others 
template<typename T, typename... Args> 
using Conditions = std::integral_constant<bool, 
    SomeCondition1<T, Args...>::value && SomeCondition2<T, Args...>::value 
>; 

// This is the function that is call when everything is okay. 
template<typename T, typename... Args, 
    std::enable_if_t<Conditions<T, Args...>::value, int> = 0> 
void doThing(Args...) {} 

// These function are called only to trigger 
// static asserts to give the user a diagnostic to explain what's wrong. 
template<typename T, typename... Args, 
    std::enable_if_t<SomeCondition1<T, Args...>::value && !SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, SomeCondition2 not met"); 
} 

template<typename T, typename... Args, 
    std::enable_if_t<!SomeCondition1<T, Args...>::value && SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, SomeCondition1 not met"); 
} 

template<typename T, typename... Args, 
    std::enable_if_t<!SomeCondition1<T, Args...>::value && !SomeCondition2<T, Args...>::value, int> = 0> 
void doThing(Args...) { 
    static_assert(false_v<T>, "Error, both conditions not met"); 
} 

我在想,如果测试的特点是ok了,如果有合适的静态断言抛出了我的情况。如果触发了错误的静态断言,那是一个错误,我希望能够对它进行测试。试图覆盖所有编译器的情况并手动检查每条消息是非常耗时且容易出错的。

回答

1

的为参数类型的范围的单元测试模板代码的问题是 相当好由googletest 以其TYPED TESTS featureType-Parameterized Tests 特征解决。

这些功能的局限性在于它们仅适用于仅使用一个参数测试 模板。但是,解决此限制并不难: 请参阅this question以及接受的答案。

但是,没有任何帮助,因为在 模板代码中测试static_assert s的正确性的问题更加严重。那种测试的特殊障碍当然是 a static_assert由于编译失败而引发;所以如果它正确或以其他方式触发, 没有什么可以执行来表明它确实如此。

几年前这让我感到困扰。我发布了How to write runnable tests of static_assert?,并且还写了迄今为止唯一的答案 (最新更新为C++ 14和当前编译器)。

结合这些资源和技术应该会产生您正在寻找的解决方案。