我的代码真的不能单元测试吗?

时间:2010-03-25 11:37:46

标签: unit-testing

当前项目中的许多代码与使用第三方3D渲染引擎显示内容直接相关。因此,很容易说“这是一个特例,你无法对它进行单元测试”。但我不知道这是否是一个有效的借口......很容易想到“我很特别”,但事实上并非如此。

是否存在真正不适合单元测试的代码类型?合适的,我的意思是“没有花费更长的时间来弄清楚如何编写测试而不是值得努力”......处理大量的3D数学/渲染它可能需要大量的工作才能证明函数的输出与仅查看渲染图形相比,这是正确的。

7 个答案:

答案 0 :(得分:18)

直接与显示信息,生成图像甚至是一般UI内容相关的代码有时难以进行单元测试。

然而主要仅适用于该代码的最高级别。通常在“表面”下面的1-2个方法调用是容易单元测试的代码。

例如,当验证失败时,测试某些信息是否正确地动画到对话框中可能是非常重要的。但是,检查任何给定输入的验证是否会失败非常容易。

确保以“不可测试”表面区域与测试分开的方式构建代码,并为非表面代码编写大量测试。

答案 1 :(得分:7)

对渲染代码进行单元测试的关键不在于证明第三方代码做了正确的事情(即集成和回归测试)。关键是要证明您的代码为第三方代码提供了正确的指令。换句话说,您只需要控制代码层的输入并验证输出(这将成为渲染器的输入)。

当然,您可以创建渲染器的模拟版本,它可以使用廉价的ASCII图形或其他东西,然后根据需要验证伪图形,如果您愿意,这可以使测试更清晰,但对于 代码的单元测试。

答案 2 :(得分:3)

如果您无法将代码分解为单元,则单元测试非常困难。 我的猜测是,如果你有3D原子功能(比如翻译,旋转, 并设计一个点)它们应该易于测试 - 创建一组测试点并测试转换是否指向它应该的位置。 如果您只能通过有限的API访问3D代码,那么就很难进行测试。 请参阅Misko Hevery's Testability postshis testability guide

答案 3 :(得分:2)

如果您可以抓取渲染图像,则可以对其进行单元测试。

只需使用当前代码库渲染一些图像,看看它们是否“看起来正确”(如果必须,将它们检查到像素),并将它们存储起来进行比较。然后,您的单元测试可以与那些存储的图像进行比较,看看结果是否相同。

这是否值得麻烦,由你来决定。

答案 4 :(得分:1)

通过将每个步骤的帧缓冲区与已知的良好图像进行比较,将渲染分解为步骤并进行测试。

无论您拥有什么,都可以分解为可以比较的数字。真正的诀窍是当你在算法中使用一些随机数生成器或其他一些不确定的部分时。

对于浮点数,您可能需要从预期数据中减去生成的数据,并检查差异是否小于某个误差阈值。

答案 5 :(得分:1)

我认为这是一个很好的问题。我一直在努力解决这个问题,似乎某些类型的代码适合单元测试范例,而其他类型则没有。

我认为明确单元可测试的代码显然有错误的空间。例子:

  • 用于计算毛茸茸数学或线性代数函数的代码。我总是写一个辅助函数来检查答案,并偶尔运行它。

  • 毛茸茸的数据结构代码,带有交叉引用,guid,反向指针和逐步保持一致的方法。这些很容易打破,所以单元测试很适合看它们是否坏了。

另一方面,在冗余度较低的代码中,如果代码编译,则可能并不清楚甚至意味着什么是错误的。例如,我使用dynamic dialogs执行非常复杂的UI,并且不清楚要测试什么。所有类型的事件,如事件处理,布局以及可能使此代码容易出错的控件的显示/隐藏/更新,都可以在下面经过充分验证的层中处理。

我发现自己需要的测试不仅仅是单元测试,而是覆盖测试。我是否尝试过所有可能的功能和功能组合?由于这是一个非常大的空间,并且禁止编写自动化测试来覆盖它,我常常发现自己正在进行蒙特卡罗测试,其中随机选择特征选择并提交给系统。然后以自动和/或手动方式检查结果。

答案 6 :(得分:0)

嗯,你不能单独测试某些类型的异常代码,但除此之外......

我已经获得了一些真正的单元测试代码,这些代码看起来甚至无法将测试工具附加到代码上,而且代码看起来应该是可单元测试但不是。

您知道代码不可单元测试的方法之一是它取决于运行的设备的物理特性。另一种不可单元测试的代码是直接的UI代码(我在直接的UI代码中发现了很多中断)。

我还有大量非单元可测试的代码,它们具有适当的集成测试。

相关问题