我知道倒置的测试金字塔,即端到端测试多于单元测试是一种反模式。



但是,我已经开始想一想,减少单元测试然后进行更高级别的测试,黑盒测试,通过某些API /协议与被测试的组件进行通信(例如, (SOAP,REST等)。

我发现的唯一优势是当我将组件从一种语言迁移到另一种语言却保留了相同的组件API /协议时。

在这种情况下,API的测试覆盖率很高,这使我很有信心迁移会顺利进行。单元测试没有这种信心,因为它们与编程语言紧密绑定,并且当我将被测试的代码从一种语言迁移到另一种语言时,我需要迁移单元测试,这意味着也有可能在单元测试中引入错误。 。再加上更多的努力。

拥有比单元测试更多的集成测试的其他优势?

评论

图片归因:Thoughtworks.com/insights/blog/architecting-continuous-delivery

好的单元测试可以证实应用程序的正确行为,并且应尽可能松散地耦合到实际的实现中。另一方面,集成测试通常需要复杂的设置/安排步骤(例如数据库固定),因此在实现发生更改时通常会中断。两种类型都是必需的,但是集成测试更容易因实现更改而中断,因此从长远来看,维护成本更高。没有答案提到这一点。

#1 楼

是和否

倒金字塔(冰淇淋蛋筒)经常是反模式,但在某些情况下不是。您需要用另一种语言重建API的示例就是这样的示例。

在其他情况下,您可能希望反转金字塔,包括:



您已经集成了第三方API。最低级别的测试确实在那里,以确保您没有更改API。您的大多数测试都将是端到端的,以确保您的应用程序正确格式化API的数据并正确处理API的响应。

您已集成到专用的物理设备。除了许多端到端测试可能都是手动的之外,其他基本原理也适用,因为专用设备(如旋转门,RFID管理的储物柜等)不是自动化的理想选择,并且模拟器不一定会提供完全准确的响应。

您正在测试不同应用程序/系统/ api之间的通信。如果您的主要重点是不同系统之间的通信,那么金字塔将被倒置。

您正在使用旧代码。如果您使用的是旧代码,则自动化方式可能别无选择。任何稳定的旧系统都可能将UI和处理逻辑紧密地交织在一起,如果不是不可能的话,使单元测试成为一项艰巨的任务。


#2 楼

确实,您的观察是正确的。
每个检查级别旨在使您对要检查的内容充满信心:代码单元,服务合同,系统等...。

两个常规观察使用测试金字塔可以得到的是:


当金字塔“下降”时,精度会提高:如果单元测试失败,您可能确切知道代码在代码中的哪个位置问题-但是您不知道这如何影响您的系统。


当您“上金字塔”时,可靠性会提高:如果端到端测试失败,则您肯定有这是系统上的错误-但您不知道在哪里。


假设您有一个链表结构,该结构在处理大量元素时会出现错误。如果添加单位检查,您将立即发现此问题。但是,如果UI永远不允许您的用户遇到这种情况,则您可能永远也不会拥有可以应用它的端到端检查。
另一方面,如果您添加了端到端检查,您间接地在进行各种可能的单元检查。如果发现端到端检查存在问题,则必须逐一解决代码中可能存在的多个问题-要通过单元检查对它进行“镜像”,则必须创建许多单元检查​​。
我要说的是,当您的产品面市时间减少时,建立坚实的单元检查基础的重要性就会增加。如果您必须每天发货两次,则不能依靠每天添加新的端到端支票-您必须尝试使用​​单元级支票来弥补自己的不足,并尽快解决差距。

#3 楼

要小心你的信念。

我要看一个项目,Visual Studio上的单元测试插件向我展示了38个单元测试,5个完整的模块测试(我们期望很多)以及将来的更多此类)和27个跨模块测试(这些测试不适合JoãoFarias图),其中测试工具加载三个模块并将它们与一个模拟后端缝合在一起,该后端可将内容持久保存在RAM中,以便内部API实际上会更改数据,并且测试工具本身会实际调用读取的API并验证结果。

这有其优点和缺点。最明显的好处是由于割点的位置,与典型的单元测试相比,这最终使其重构起来稍微容易一些,并且覆盖率极高。不利之处在于,单个错误很容易产生混乱,开发人员很可能会调试测试以找出原因。
我们实际上是围绕交换持久性存储而设计的。这从未真正发生过,但是这样做的能力使编写这些模块拼接测试变得容易得多。它们覆盖了大约三分之一的集成测试所需的三分之二的东西,而且安装成本也低得可笑。

但是您的里程会有所不同。对于我们来说,我们选择了这个怪异的测试水平,因为我们相信它会带来更多的收益。每个项目都是不同的。在较旧的项目中,所有尚存的测试都是集成测试,在该测试中,它实际上创建了一个实例,然后将其启动,并且测试工具实际驱动了该软件。这既昂贵又脆弱又缓慢,但是比尝试翻新所有东西便宜并且确实涵盖了一些SQL代码。有人为该项目编写了单元测试。他们现在走了。没有人会想念他们。他们没有涵盖任何重要内容。

评论


“盲目遵循最佳实践不是最佳实践。”

–vsz
19年2月5日在7:34

@vsz:我的话:“最佳实践还没有完成。”

–约书亚
19年2月5日14:30在

#4 楼

争论某事是否是反模式就像在争论一个政客是愚蠢的,还是一个宗教比另一个宗教更好:很少有一个正确的答案。相反,您应该考虑不同形状的测试金字塔之间的权衡以及它们如何适用于您的情况。我会提到一些权衡。

用户相关性与诊断价值。端到端测试对实际的用户交互进行建模,因此与单元测试相比,它们可以感觉到整个系统是否正常运行。但是,如果端到端测试失败,则您几乎不了解导致问题的原因。因此,端到端测试无法提供很多诊断价值。

由于单元测试涵盖了非常具体的内容,因此您可以使用维恩图,通过该维恩图可以得出哪些测试通过了哪些测试,而哪些未能推断出根本原因。单元测试具有很大的诊断价值。另一方面,如果您的组件依赖于其他组件,则需要模拟或模拟组件及其依赖项之间的交互。这就需要对其他组件的行为做出假设。如果您的假设是错误的,则您的测试将变得不那么相关。因此,您不能仅仅依靠单元测试来告诉您系统是否真正起作用。

运行成本。端到端测试的运行时间可能比整套单元测试要长得多。这是因为端到端测试通常涉及冗长,复杂的设置和拆卸,并且,如果系统中的任何内容都是异步的,则需要等待很多时间。单元测试运行很快。在其他条件相同的情况下,运行速度快的测试比运行速度慢的测试更有可能被使用。

维护成本。端到端测试往往比单元测试更脆弱,需要更多维护。在考虑如何投资有限的测试预算时,您需要考虑端到端测试的覆盖范围是否足以证明其较高的维护成本。

评论


我再次了解到,选择IT解决方案就是要了解各种折衷方案。在所有情况下都没有通用的模式。感谢您提醒我有关此事。

– dzieciou
19年2月15日在15:02

#5 楼


与单元测试相比,拥有更多的集成测试还有其他优势吗?


像金字塔一样的菱形在我眼中已经存在了很长时间。主要原因是,在方法级别进行单元测试通常会导致大量的模拟和对实现细节的测试。很多单元测试似乎使重构变得困难而不是容易。

我赞成更高级别的“开发人员测试”,即测试代码行为的测试。可能会组合多个类/组件,更多是集成级别测试。它们仍然应该像毫秒一样快速!

您的测试是否能帮助您保持代码库的适应性和较高的结构质量?如果是,那么您来个好地方。如果不是,那么……是时候重新考虑您的测试自动化策略了。

反模式是大量的手动和端到端测试,而不是集成测试。它们缓慢,昂贵且易碎。如果您想保持产品的敏捷性,并迅速缩短反馈周期,则无济于事。对于大多数迭代产品开发模型来说可能就是这种情况,其中需要快速连续的交付周期才能保持竞争优势。可能在某些情况下冰锥金字塔是完全有效的。

测试钻石上的一些文章:


https://leeorengel.com/testing -part-1 /
https://labs.spotify.com/2018/01/11/testing-of-microservices/


#6 楼

我不会说减少单元测试是有好处的,但是拥有更多的手动/端到端测试以及不过度依赖单元测试可能有好处。显然,这是有限的时间,这意味着更少的单元测试可以确保更好的手动/端到端覆盖。

单元测试非常适合进行回归测试,但是它们都可以通过100%的覆盖率,并且应用程序仍然会失败。

单元测试无法覆盖的大事是测试设计。我开发的应用程序的软件功能完全按设计要求进行,但不按预期进行。这发生在设计中存在例如错误或错误假设的地方。

在某些情况下,单元测试也会通过,但由于竞争等原因,系统在现实世界中会失效。

也很容易想到每个案例都包含在单元测试中,但是无法涵盖边缘案例或失败场景。在这些情况下,单元测试可能会给人以错误的信心。

此外,单元测试不会测试UX问题-如果应用可以运行,但界面会导致问题,则没有用。这甚至可能发生在非UI情况下,例如如果API规范编写不当导致API用户滥用它。