小时候经常听语文老师教我们,好的文章要“凤头、猪肚、豹尾”。
听起来是个非常怪胎的形象,其实是指
文章要开头精致简短,内容丰富,结尾收束有力。
最近在学习写BDD风格的测试用例时,略有一些心得。虽然在测试用例编写的层面,BDD相当简单,看起来只是用Give,When,Then把测试分为三部分而已。但真正要用好还是有一些需要注意的点的。因此不吝浅薄也诌了个口诀,难以做到完全贴切,但求易于记忆吧。
羊头
从顺序来看,Given部分是测试用例的头部,但是如果按照这个顺序从头书写用例的话,却往往会有些迷茫。 原因很简单,Given是服务于后面测试主旨部分的。
所谓挂羊头卖狗肉,对于单元测试来说,典型的Given部分是在设置各种mock为真正要测试的代码设置好交互输入;而对于集成测试,Given可以用来清理环境,初始化数据,确保用例执行在预期的环境之中。
反模式
- 头重脚轻
大的不成比例的Given部分,往往是目标代码设计失误的一个征兆。一般来说,原因都在于被测试的实现代码。内聚力不足却与外部高度耦合,职责模糊繁杂,有过多不必要的依赖…… 这时候就不要苦苦的让测试用例委屈求全了,重构实现代码吧。
蜂腰
理想的When语句应该只有一行代码,即被测试的操作。它应该成为测试用例的一条分界线,之前是假定,发生了某事,之后是验证。
这也许是Given-When-Then风格注释或者DSL最实际的一个目的,标出目前测试的对象。否则,孤零零的一行调用很容易被淹没在各种初始化,mock和验证代码之中了。
反模式
- 大肚皮
如果发现不能干净利落的用一个调用完成测试用例中的操作。很可能是实现代码没有给它的使用者提供合适的接口。特别的,如果必须把多个动作纠结在一起完成一次有意义的操作,这段代码很可能有时序耦合的问题。重构吧。 - 蜈蚣用例
如果出现"当我做aaa,则xxx,然后当我做bbb,则yyy,接下来做ccc,则……“这样多个When Then的情况,会导致测试的主旨不清。这样的用例在描述How而非what。很难通过阅读这样的用例来理解系统的行为。
蝎尾
一个测试用例,可以没有Given部分,甚至可以没有When部分,却不能没有Then。Then部分体现了测试的目的所在。就像蝎子尾巴一样,是真正见血的地方。在采用TDD开发的时候,可以先写Then部分再倒推补充出用例的其它必要部分。
另一方面,也像蝎尾伸向前方一样,Then应该与Given首尾呼应,mock了某个协作接口,就应该有相应的verify去检验交互;设置了一些环境变量,就应该在体现出它们与最终执行结果之间的关系。
反模式
- 无尾熊用例
在现实工程中并不是很少见,一个初始化了目标代码,执行了操作,却毫无验证的用例。测试用例唯一管用的时刻,就是它失败的时候。不会失败的测试是无用的,或者说除了给测试覆盖率注水以外毫无用处。
网友评论