单元测试高度模板化的库

时间:2016-11-18 16:16:35

标签: c++ unit-testing template-meta-programming

我想知道是否有什么东西作为单元测试模板。让我解释一下我的需求。

我有一个高度模板化的库。我有很多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");
}

我正在考虑测试特征是否正常,以及是否为我的案例抛出了正确的静态断言。如果触发了错误的静态断言,那就是一个错误,我希望能够测试它。试图覆盖所有编译器的所有情况并手动检查每条消息非常耗时且容易出错。

1 个答案:

答案 0 :(得分:2)

参数类型范围的单元测试模板代码的问题是 googletest很好地解决了这个问题 及其TYPED TESTS featureType-Parameterized Tests 特征

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

然而,这对于测试正确性static_assert的进一步问题没有任何帮助 模板代码。当然,这种测试的特殊障碍是 a static_assert因编译失败而触发;所以如果它正确或以其他方式发射, 没有什么可以执行来表明它确实存在。

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

结合这些资源和技术应该可以提供您正在寻找的解决方案。