Unit testing 我的代码真的不可单元测试吗?

Unit testing 我的代码真的不可单元测试吗?,unit-testing,Unit Testing,当前项目中的许多代码都与使用第三方3D渲染引擎显示内容直接相关。因此,很容易说“这是一个特殊情况,您不能对其进行单元测试”。但我想知道这是否是一个合理的借口。。。人们很容易认为“我很特别”,但实际上很少有人会这样认为 有没有真正不适合单元测试的代码类型?所谓合适,我的意思是“不需要花更长的时间来弄清楚如何编写测试,而不需要付出更多的努力”。。。处理大量的3D数学/渲染与只查看渲染的图形相比,要证明函数的输出是正确的可能需要大量的工作。如果可以抓取渲染图像,可以对其进行单元测试 只需使用当前的代码

当前项目中的许多代码都与使用第三方3D渲染引擎显示内容直接相关。因此,很容易说“这是一个特殊情况,您不能对其进行单元测试”。但我想知道这是否是一个合理的借口。。。人们很容易认为“我很特别”,但实际上很少有人会这样认为


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

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

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


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

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

然而这主要只适用于该代码的最高层。通常,“表面”下的1-2个方法调用是易于单元测试的代码

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


确保代码的结构使“不可测试”表面区域与测试完全分离,并为非表面代码编写大量测试。

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

不管你有什么,它都可以分解成可以比较的数字。真正的诀窍是当你在算法中有一些随机数生成器,或者其他一些不确定的部分


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

如果无法将代码分解为单元,则很难进行单元测试。 我猜如果你有3D原子函数(比如平移,旋转, 它们应该是易于测试的——创建一组测试点,并测试转换是否将一个点带到它应该到达的位置。 如果只能通过有限的API访问3D代码,那么就很难进行测试。
请参见和。

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


当然,您可以创建一个模拟版本的渲染器,该渲染器可以生成廉价的ASCII图形或其他东西,然后验证伪图形(如果需要),这会使测试更加清晰,但对于代码的单元测试来说,这并不是严格必要的。

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

我清楚地认为单元可测试的代码显然有错误的空间。示例:

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

  • 毛茸茸的数据结构代码,带有交叉引用、guid、反向指针和增量保持一致的方法。这些测试很容易被破坏,所以单元测试有助于查看它们是否被破坏

另一方面,在低冗余的代码中,如果代码编译了,甚至可能不清楚出错意味着什么。例如,我使用非常复杂的UI,不清楚要测试什么。事件处理、布局和控件的显示/隐藏/更新等所有可能使代码容易出错的事情都在下面经过良好验证的层中简单地处理


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

您不能对某些类型的异常代码进行单元测试,但除此之外

我已经对一些代码进行了真正的单元测试,这些代码看起来甚至不可能附加测试工具,而这些代码看起来应该是可单元测试的,但实际上不是

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


我还拥有大量非单元测试代码,这些代码具有适当的集成测试。

只有在像素对像素的结果“正确”时,这才有效。如果轻微的颜色变化不那么相关,那么它就失败了(或者变得更难测试)。没有那么多。在这种情况下,你需要一个差异,并检查它是否低于一个阈值。在奇妙的3D世界中,不是所有的代码都是代码。。。您也有GPU着色器,它们部分是艺术资产。。。如果艺术家更改着色器,渲染结果可能会发生很大变化(类似于Zen garde中的CSS)