编译器错误的单元测试

问题描述:

如何在单元测试中测试想要的编译器错误?编译器错误的单元测试

考虑代码:

class ErrorTest 
{ 
    OtherClass& read_write() { 
     return other; 
    } 

    const OtherClass& read_only() const { 
     return other; 
    } 

    private: 
     OtherClass other; 
}; 

我如何测试READ_ONLY()分配?这是非常重要的,应该坚决检查,以正确生成编译器错误:

ErrorTest test; 
OtherClass other = test.read_only(); 
test.read_write() = other.modify(); 
test.read_only() = other.modify(); /* This should error */ 
+0

好问题。我以前也想过。虽然从未真正找到好答案。当然你可以编写一个脚本来尝试编译文件,并验证错误代码或其他东西,但这不是一个优雅的解决方案 – jalf 2009-07-13 22:29:54

我想主要的现在的问题是,你测试你的代码或在这一点上,编译器?

测试编译器并不一定是坏事......我已经让编译器升级屏蔽了过去的错误,所以最好确保您得到您期望的相同安全检查。

但是,你必须做很多工作。您的单元测试必须产生编译器,捕获它的输出,并在正确的行上解析它以获取正确的错误语句。这不是微不足道的,可以说是不值得的。

一个稍微简单的方法可能是保持一个错误代码的目录,并让脚本每次编译一个文件。在那里有一个'#ifdef MAKEFAIL'标志,打开应该失败的确切条件。确保编译器在您未设置该标志时返回0,而在您设置时不返回零。这假定编译器在失败时返回非零值......我不知道MSVC是否遵循该规则。

为了解决可移植性问题,我将抛出第三个选项是autoconf。设置起来可能很痛苦,但其目的之一就是在编译之前确保你有一个健全的开发环境。你可以在其中添加一个像这样的测试,它可以处理查找编译器并尝试它。

+6

他正在测试他的代码是否是const正确的。所以我认为他仍然在测试他的代码,只不过他正在测试它的属性,而这些属性在编译时才是明显的。 – 2009-07-13 22:21:42

+0

我读到,因为他试图确保编译器生成警告,而不是没有警告。有一个单元测试告诉你编译器有抱怨,但似乎有点多余,但是如果你有一个很好的单元测试输出解析器,它也许是有意义的。 – 2009-07-13 22:30:15

这看起来有点像当你在一台* nix机器上从源码构建“./configure”时发生的自动检测。 autoconf脚本构建小程序并尝试编译它们以确定编译器提供和支持的内容。

重复使用任何一种方法可能不切实际,但您可能需要相同的模型。每个测试都有自己的文件或一组文件,以及一个单独的项目文件/ make target/etc。然后,您的测试脚本将尝试制作每个测试用例,并通过grep或通过比较输出到与测试案例一起存储的基线输出。

编译器和平台的有效测试将针对运行时的行为变化。我经常这样做,重现生产代码中存在的一小部分行为,并检查行为是否如预期。

但是对于这种情况,你真正想要的是一个静态分析工具,它检查以确保开发人员编写的代码遵循诸如此类的约定。这当然是一个有效的构建工具。但是,搜索静态分析工具以查找您在此处指定的内容可能很困难。我首先从*文章List of tools for static code analysis开始,在C/C++部分。

请注意,您编写的代码不是“错误”,它只是您的约定。这是一个非常好的约定,但编译器不会也不应该约束你。静态分析工具也不应该。因此,您需要找到一个允许您配置允许和不允许配置的配置。