单元测试可以依赖于环境吗



我有一个关于单元测试的非常一般的问题。我们应该编写依赖于环境的单元测试吗?单元测试可能取决于文件系统、特定连接或文件的存在。我不确定是否有答案。但我发现将单元测试与环境解耦需要时间。这是否意味着可以创建依赖于环境的单元测试?或者它总是指出,当我们需要编写依赖环境的单元测试时,存在设计问题?

TL;DR

依赖环境的测试是否确实是一个设计缺陷在很大程度上取决于您的应用程序、编程语言和特定问题。请记住,测试从来都不是"测试";完整的";或";完美的";尽量不要以牺牲越来越多的时间来达到完美。使用现代框架,使您的测试可重用,并模拟您的环境,可以减轻测试的很多痛苦。


较长的答案

IMHO,这个问题没有完美的答案。单元测试应尽可能通用和可重复使用,而不必试图以任何价格覆盖环境边缘情况。

示例:现在大多数环境都应该有AMD64处理器(与手机无关),所以在大多数情况下,不需要为X32或ARM环境创建单元测试。。。

您的问题与技术无关,因此很难说是否需要依赖环境的单元测试是设计缺陷。如果你正在使用Java(见下文),我宁愿认为它是,使用C++,它可能不是…

根据我的经验,我可以给出一些经验法则(因此也有一些基于意见的):

遵循帕累托原则

不要试图实现理论上100%的可能,而是总结可能遇到的大约80%。比方说,您希望您的应用程序在Windows客户端上运行。因此,您的测试可能应该涵盖Windows 10和11的环境特征。旧的Windows版本,Linux,Mac OS。。。不应该被需要。

或者,如果你的应用程序主要是西班牙语受众,你不应该太关心它如何处理汉字或加拿大的数据保护规则。

在对应用程序进行编码时,尽可能排除环境专业

如果你能设法使你的应用程序代码基本上独立于你的环境;自动地";应用于你的测试。(另外,请参阅下面关于不要重新发明轮子的要点)

由于您没有要求特定的编程语言,我将在这里参考Java,但在大多数现代语言中都存在类似的概念。

E。g.Java从您的环境中提取了很多内容,所以如果您不知道您的应用程序是在Windows(作为分隔符)还是Linux(/)上运行,则可以使用File.separator

不使用特定于操作系统的API(如Java NI)也可以避免与环境相关的问题。如果不密切处理硬件访问,就不需要使用它们。

调整测试

就像";真实的";应用程序,通常你的测试从来都不是";完成";。您的软件出现了新问题?修复它为这种bug添加一个特定的测试用例(尽量是通用的)。如果这是一个与你以前没有考虑过的20%的案例或环境有关的问题,请高兴——现在你也掌握了一些。

将测试数据与应用程序打包

再次参考Java,您可以将测试文件放在resources文件夹中,并在测试时动态加载它们,而不需要麻烦测试机的真实文件系统。

此外,如果您使用的是数据库,您可以在测试期间启动内存中的实例(如H2)。这不会完全反映您的生产数据库系统,但会使测试变得非常容易,而不会破坏某些东西。无论如何,如今数据库抽象也非常复杂,因此尽管存在一些边缘情况,但如果您使用一个好的数据库抽象层(这本身会减少对环境的依赖),则不应该看到任何行为上的差异。

使您的测试可重复使用

使用像Maven或Gradle这样的工具,您可以使您的测试在更大范围的环境中运行,如果它们像刚才指出的那样打包的话。对特定测试环境的需求将减少。

嘲笑是你的朋友

与";假的";前面提到的数据库,您可以模拟很多东西。有一些像Mockito这样的框架允许使用模拟对象进行白盒和黑盒测试"帮助者";像WireMock,你甚至可以模拟你从外部服务得到的答案。还有更多的可能性!

不要重新发明轮子

如果您使用当今的高级应用程序框架(如Spring、Symfony、Boost…),如果您正确使用它们,它们将为您做很多工作。你必须阅读并深入研究这些文档,但之后你会意识到它们会让你的生活变得多么轻松。这不仅适用于框架,也适用于库、服务、组件。。。好的是,当涉及到测试时,所有这些都会到位!如果你使用一个好的软件基础,你的大部分环境依赖可能会消失。

最新更新