集成测试如何批评设计?


38

我正在JB Rainsberger的博客中阅读有关集成测试的文章,并想知道集成测试对我们的设计而言哪种方式更为苛刻?

我们编写了更多的集成测试,这些测试更大,并且不会像微型测试那样苛刻地批评我们的设计。


3
这个问题令人困惑。“集成测试以哪种方式更加苛刻”……“集成测试更大,并且不会苛刻地批评我们的设计”-现在该怎么办?
AnoE


“集成测试”!=“集成测试”。我知道。我也不喜欢,但这就是这些词的意思。“集成测试” =“检查集成点(不集成事物)的测试”,而“集成测试” =“(集成)事物并将集成整体作为单个事物进行检查的(较大)测试”。这样,这些术语彼此相反。
JB Rainsberger '18年

Answers:


46

微型测试可以帮助您进行良好的设计。通过编写良好的小型测试,您正在刻意测试少量代码,并使用模拟对象填补空白。这导致低耦合(事物之间不相互依赖)和高内聚性(属于一起的事物保持在一起)。这样,当您回去进行更改时,很容易找到造成您所寻找内容的原因,并且在进行更改时不太可能破坏事物。这不能解决您的所有设计,但可以提供帮助。

在这种情况下,JB Rainsberger指出,如果您在编写单元测试时遇到困难,那么您的设计可能会出现问题,从而导致困难,因此测试会隐式批评设计。他认为这是一件好事,因为如果没有小的测试有助于使您的体系结构保持一致,就很容易偏离良好的设计模式-集成测试将无法捕获这些设计模式。

更新:正如Rainsberger在下面指出的那样,他并不打算将微型测试与单元测试同义。他还提供了详细的答案,可以使您更深入地了解他正在交流的内容。


2
我原则上同意您的回答,但不同意您表达的方式。提出这个特定问题的人不太可能知道“嘲笑”,“耦合”和“凝聚力”这两个术语的含义,并且您在答案中还没有定义这些术语。
罗伯特·哈维

3
更好,但是您给单元测试的功劳比我认为的实际值要高。单元测试主要说明代码的可测试性。尽管这肯定是积极的影响,但尚不清楚使代码可自动测试是否具有更好的内聚和耦合特性。另外,我认为您将“高度凝聚力”与“单一责任原则”相混淆;凝聚力意味着“属于在一起的事物”(请参阅Wikipedia文章)。
罗伯特·哈维

10
最后,“微测试”不是首选术语。当博主制定自己的技术术语时,我会喜欢它。
罗伯特·哈维

2
@RubberDuck:微型测试(约16,900个结果)单元测试(约193,000,000个结果)。差远了。即使将单元混在一起并进行测试,您仍然可以获得1400万个结果。
罗伯特·哈维

5
请不要将“微型测试”和“单元测试”等同(请参阅我的答案以获取更多详细信息);否则,我觉得您理解我试图描述的内容。
JB Rainsberger '18年

28

极其简短的版本:较小的测试,因为它们运行系统的较小部分,因此自然会限制程序员可以编写的内容,因此这为获得更清晰(更容易注意到/更难忽略)的反馈创造了机会。让我补充说,这并不一定会导致更好的设计,而是会带来机会,让人们更快地注意到设计风险。

首先,澄清一下,当我说“微测试”时,我的意思是“一个小测试”,仅此而已。我使用这个术语是因为我不是指“单元测试”:我不想陷入有关“单元”是什么的争论中。我不在乎(至少不在这里/现在)。与“单元”相比,两个人可能会更容易同意“小”,因此我逐渐决定采用“微测试”作为该想法的新兴标准术语。

较大的测试(即在系统的“动作”部分中运行较大部分的测试)往往不会像较小的测试那样清晰或完全地批评设计。想象一下可以通过一组给定测试的所有代码库,这意味着我可以重新组织代码,并且仍然可以通过那些测试。对于更大的测试,此设置更大。对于较小的测试,此设置较小。换句话说,较小的测试会更多地约束设计,因此更少的设计可以使它们通过。这样,微测试会更多地批评设计。

我说“更严厉”,以想像一个朋友的形象,该朋友直接告诉您您不想听的但需要听的,并大喊大叫以传达紧迫感,而其他人可能会感到不舒服在做。另一方面,集成测试保持安静,并且通常仅在您没有时间或精力来解决问题时才提示问题。集成测试使在地毯下清除设计问题变得非常容易。

使用更大的测试(例如集成测试),程序员通常会因草率而陷入麻烦:他们有足够的自由编写纠结的代码以某种方式通过测试,但是当他们继续执行下一个任务时,对代码的理解就会迅速消失。 ,而其他人则在阅读纠结的设计时遇到了不必要的困难。这就是依靠集成测试的风险。对于较小的测试(例如微型测试),程序员通常会因过分规范而陷入麻烦:他们通过添加不相关的细节(通常是通过先前测试的复制/粘贴)来过度约束测试,因此他们相对较快地自我绘制陷入一个角落。好消息:我发现,在我编写测试几小时或几天后,从测试中删除多余的细节要比将其纠结的生产代码在编写后数月至数年内拆开要容易和安全得多。随着错误的发生,过度指定会更快地造成越来越明显的损坏,并且警报程序员会更早地看到他们需要修复问题。我认为这是一种优势:我会更早发现问题并在这些问题扼杀我们添加功能的能力之前将其修复。


您对单元测试更多地依赖于其模拟而不是真实代码这一问题怎么办,从而导致测试似乎通过但实际上不起作用的问题,因为没有人将模拟与现实保持一致。
Zan Lynx

@ZanLynx我已经详细介绍了这一点。从这里开始:blog.thecodewhisperer.com/series#integrated-tests-are-a-scam
JB Rainsberger

9

他的意思是,单元测试要比集成测试更好地指导良好的软件设计。

这就是为什么。编写单元测试会迫使您编写可单元测试的代码。与没有单元测试的代码相比,可单元测试的代码往往是更好的设计。

集成测试不会以相同的方式通知您的代码,因为您只是在测试软件的外层,而不是将软件连接在一起的内部接口。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.