关于测试的多样性和异想天开的形状

金字塔,蜂巢,奖杯,以及单元测试的意义

2021年6月02

最近在twitter等网站上出现了团队应该如何分配测试工作的复兴。尤其是蒂姆·布雷认为咄咄逼人地支持认真对待自动化测试。任何熟悉我写作的人都知道我非常赞同他的观点。

他在文章中提到的一个观点是:

这两个“畸形的斑点”都是对老图像的反应测试金字塔

这些图像的重点是指出我们应该在各种类型的测试上花费的精力,特别是单元测试和更广泛的测试之间的平衡。金字塔理论认为,应该将大部分测试作为单元测试来完成,而蜂窝模型则认为,应该使用相对较少的单元测试,并将重点放在集成测试上。

我对这个讨论的第二大问题是,由于人们不清楚单元测试和集成测试之间的区别,这个讨论显得不透明。

术语“单元测试”和“集成测试”一直是相当模糊的,即使按照大多数软件术语的不稳定标准。根据我最初的理解,它们主要是一个组织问题。让我们回到大型瀑布式软件项目的时代。我花了几个月的时间在编写一大堆代码。我可能是一个人,也可能是一个小团队。无论如何,我认为这一大块是一个概念单位,我们可以在相对分离的情况下与它的邻居一起工作。一旦我们完成了编码,我们就可以把它交给单元测试团队,然后由他们自己测试单元。在一两个月后,我们可以将这些测试与它的邻居进行集成,并针对系统的更大一部分,甚至整个系统进行集成测试。关键的区别在于单元测试是独立测试我/我们的代码,而集成测试我们的代码如何与单独开发的代码一起工作。

许多人今天遇到单元测试作为Xunit系列测试工具,由Kent Beck作为极限编程.Kent使用“单元测试”来指示开发人员作为其日常工作的一部分编写的测试。

程序员编写单元测试,这样他们对程序运行的信心就可以成为程序本身的一部分。客户编写功能测试,这样他们对程序运行的信心也可以成为程序的一部分。

--Kent Beck (Extreme Programming Explained,第一版)

请注意,在Kent最初的表述中,“单元测试”指的是由程序员编写的任何内容,而不是单独的测试团队。在C3当我们编写单元测试时,我们通常会关注单个类的行为。但是我们设置了一个测试fixture,它创建了带有所有必要依赖项的对象,以便它可以执行自己的方法。这些其他的对象也会执行,但是对于这个测试,我们假设所有其他代码都能正常工作(通常其他代码都有自己的测试)。

我记得有很多关于“单元测试”的讨论。一位测试专家严厉斥责了肯特的这种用法。我们问他将如何定义单元测试,他的回答类似于“在我的培训课程的第一天早上,我涵盖了24种不同的单元测试定义”。

从xp启发的单元测试的早期开始,就有一些人不喜欢“单元测试”这个词,并建议使用“微测试”或“程序员测试”之类的名称。

对于许多人来说,最大的问题是这些依赖对象。如果我正在测试一个订单对象,并且它与客户对象协作,那么订单对象的测试可能会由于客户对象中的bug而失败。这导致了编写单元测试的不同风格,其中任何协作对象都将被模拟、存根或其他类型的对象取代测试双.我发现描述这些风格是有用的单元测试喜欢交际和孤独。[1]

与这一区别交织在一起的是两种XP单元测试实践学派的发展,我称之为经典和嘲弄.经典的XP单元测试遵循我们最初使用的社交方法,而mock风格倾向于单独的测试。

所以,回到金字塔和蜂巢,当我读到蜂窝和类似形状的拥护者时,我经常听到他们批评过度使用嘲笑,并谈论由此导致的各种问题。由此我推断,他们对“单元测试”的定义就是我所谓的独立单元测试。类似地,他们关于集成测试的概念听起来很像我所说的社交单元测试。这使得金字塔与蜂窝的讨论变得毫无意义,因为我所听到的任何关于测试金字塔的描述都认为单元测试是社会性和/或孤立性的。

定义使语义图更加模糊集成测试,这使得“单元测试”看起来是严格定义的。这里的要点是,当有人开始谈论各种测试类别时,深入挖掘他们的词汇含义,因为他们的使用方式可能与你上次阅读的人不同。

如果您对我的仔细的散文给予了适当的关注,那么您会注意到我之前说过,单元和集成测试缺乏明晰性是我在蜂窝/金字塔讨论中遇到的第二大问题。这条推文很好地总结了我最大的问题。


脚注

1:Jay字段提出了条件“孤独”和“交际”