07|TDD中的测试(3):集成测试还是单元测试?
集成测试还是单元测试?
TDD 中的单元测试
在 TDD 的语境下,“单元测试”指的是能提供快速反馈的低成本的研发测试(Developer Test)。TDD 社区希望通过强调“单元测试”,来强调这些特点。但是“单元测试”这个词,并不是由 TDD 社区发明的,而是软件行业中由来已久的一个词汇。在不做任何强调的情况下,它会指针对不涉及进程外组件的单一软件单元的测试。
为了让测试能够聚焦到单一的单元,就需要拆分单元间的依赖,那么最终会得到一组彼此间没有直接耦合关系的小粒度对象。
坏味道通常源自过高认知负载(Cognitive Load)或不易修改,俗称“看不懂改不动”。比如,坏味道过长的方法(Long Method)不是以绝对代码长度来衡量的,而是以“是否超出认知负载或难以改变其中的行为”来衡量的。而将功能上下文切得过于细碎,也会增加认知负载。因而不能单纯地认为,这种风格就一定是好的设计。
在测试驱动开发中,从来没有强调必须是“单元测试”。反而在大多数情况下,都是针对不同单元粒度的功能测试。并通过这一系列不同单元粒度的功能测试。
在 DHH 与 Martin Fowler、Kent Beck 关于 TDD 的圆桌会议中,Kent Beck 也反复强调,他几乎从不写“单元测试”,而主要是通过构造恰当粒度的黑盒功能测试驱动开发。之后 Martin Folwer 也再次写文章谈论单元测试,并在其中阐述了 TDD 社区所谓的单元测试到底是什么。也就是我们前面说的,能提供快速反馈的低成本的研发测试。Martin Fowler 还建议将 TDD 中的测试叫作极限单元测试(Xunit Testing),以区别于行业中的叫法。
“单元级别功能测试”这个名字同时具有“单元”和“功能”。通过这个名字,我想要强调这样几点:
TDD 中的测试是由不同粒度的功能测试构成的;
每一个测试都兼具功能验证和错误定位的功效;
要从发现问题和定位问题的角度,去思考测试的效用与成本;
单元粒度要以独立的功能上下文或变化点为粒度。
无论是“极限单元测试”还是“单元级别功能测试”,从今天起,请停止使用“单元测试”这样源自测试领域的名字。毕竟 TDD 中的测试,并不是一种关于测试的技术,而是通过分解功能以驱动软件开发的技术。