单元测试高度模板化的库

Unit testing highly templated library

本文关键字:高度 单元测试      更新时间:2023-10-16

我想知道如果单元测试模板是一个东西。让我解释一下我的需求。

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

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

对参数类型范围的模板代码进行单元测试的问题是googletest很好地解决了这个问题具有TYPED TESTS特性和Type-Parameterized Tests特性。

这些特性的一个限制是它们只能立即应用于测试只有一个参数的模板。但要解决这个限制并不难:请看这个问题和公认的答案。

这些都没有帮助,然而,测试static_assert的正确性的进一步问题模板代码。当然,这种测试的特殊障碍是static_assert因编译失败而着火;所以如果它触发了,不管正确与否,没有什么可以执行来显示它是这样做的。

几年前这也困扰着我。我张贴了如何编写static_assert的可运行测试?也写出了目前唯一的答案已收到(最近针对c++ 14和当前编译器更新)。

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