【问题标题】:Verify static_assert in a unit test在单元测试中验证 static_assert
【发布时间】:2016-05-18 15:57:07
【问题描述】:

我想确保 static_assert 在单元测试中正常工作。也就是说,如果我有一个

class MyClass {static_assert(my_type_trait<T>::value, "error"); };

那么在单元测试中MyClass&lt;TypeWithTrait&gt; myClass; 应该“通过”,MyClass&lt;TypeWithoutTrait&gt; myClass; 应该“失败”。

有可能做这样的事情吗?

【问题讨论】:

  • 是的,你试过了吗?
  • @101010 是的,我只是得到一个编译器错误。
  • @DavidDoria:所以?这正是静态断言的用途。如果符合预期则测试通过,否则则失败。
  • @Mat 但我无法构建项目以达到可以运行测试的程度。在这一点上,它不是“单元测试”,而是“我可以手动尝试并查看,但我无法在每次运行测试套件检查回归时自动执行此操作”。你明白我的意思吗?
  • 这是我对典型单元测试库最大的抱怨之一。确保你失败与确保你通过同样重要。我相信 LLVM 的 lit (llvm.org/docs/CommandGuide/lit.html) 具有这种能力。尽管要完全透明,但我从未使用过它(将来可能会)。过去我写过这样的 bash-shell 脚本代码来解决这个问题:github.com/llvm-mirror/libcxx/blob/master/test/testit#L83-L95 这个解决方案一直不受欢迎,主要是因为它无法并行运行测试,并且无法检测到测试因错误原因而失败。

标签: c++ unit-testing c++11 googletest


【解决方案1】:

如果您想检查某些内容是否无法编译,则必须在代码外部进行测试。只需编写一个简单的文件,例如:

#include "MyClass.h"

int main() { 
    MyClass<%T%> m;
}

并编写一个单元测试,用不同的%T% 值编译该文件。验证编译是否按预期成功,或者按预期在失败文本中显示有关static_assert 的内容失败。

【讨论】:

    【解决方案2】:

    Barry 的建议是一种可能,但是如果你有很多东西要测试,你需要创建很多小文件。更重要的是,这些文件可能由于其他原因而无法编译,这会导致您错误地认为您的测试通过了。

    另一种方法是不使用static_assert,而是使用某种SFINAE 来检测某些东西是否有效。对于特征类,这有点棘手,但您可以这样做:

    template <class T>
    using void_t = void;
    
    template <class T>
    struct foo;
    
    template <>
    struct foo <double> {};
    
    template <class T, class = void>
    struct has_foo_trait : std::false_type {};
    
    template <class T>
    struct has_foo_trait<T, void_t<decltype(foo<T>{})>> : std::true_type {};
    
    int main(int, char**) {
      std::cerr << has_foo_trait<int>::value;
      std::cerr << has_foo_trait<double>::value;
      return 0;
    }
    

    这会打印出01。所以现在,您可以在编译时计算特征存在的值,而不是直接从 static_asserting 获得硬失败,然后 static_assert 得到您期望的值。

    请注意,trait 类之所以棘手是因为 trait 被声明为通用模板,只是没有定义。因此,直接在void_t 中使用类型的“通常”元编程是行不通的。为了在has_foo_traittrue 分支中触发软SFINAE 错误,我实际上不得不默认构造一个traits 类的实例。如果你编写你的特征类,所以它们不是默认可构造的,这将不起作用。但总的来说,您不会那样写它们。很想知道是否有更好的方法来做到这一点

    【讨论】:

    • 所以我想我要检查的一种情况是有人没有从类中删除 static_assert 。因此,如果我正确理解了您所说的内容,这将有助于我只是试图检查 static_assert 是否会失败,但是如果我试图检查 static_assert 是否真的存在并且在我应该失败的地方失败不要认为这有帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 2017-05-23
    • 2017-12-21
    • 2022-01-11
    • 2019-12-18
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多