博客原文地址java
在上一个项目上,因为项目成员大部分是新入职的同事,因此对于测试不是很熟悉,
这就致使了在项目前期,项目上的不少测试都不太make sense,虽然没有什么定量的东西来描述,
可是总结起来就2个点:git
对于这一个问题,是由于不少刚开始写测试的开发脑子里不会快就想到given、when、then这三个词,
通常咱们写测试写得比较多的同事,都会使用should_return_xxxx_when(if)_xxxx
。其实就是在脑子中
想到了given、when、then。而新同事照着模仿的时候,极可能就单纯地写了should_xxx
。他们只考虑告终果,
可是没有考虑条件,这就致使了读名字仍是get不到测试想要干什么。github
对于这个问题,我想起了多年前在stackoverflow上面看到的一种写测试名字的模板,他是这样推荐的:
GivenA_WhenB_C
,我以为这中写法挺好的,因此在项目中用了起来,结合实际使用,我又对此提出了两个改进:测试
___
(也就是3个_
),由于通过试验,发现2个_
过短了不容易一眼看出分隔最终的效果是这样的(这是一个例子,来自最近我参加的DDD进阶培训中的训练题):ui
parking_order_is_natural_order___park_cars_by_parking_assistant___car_parked_to_correct_parking_lot_in_turn car_is_already_took___take_back_car_with_used_receipt___exception_is_thrown parking_lot_is_available___park_a_car_by_parking_assistant___receipt_returned car_is_parked___take_back_car_with_invalid_receipt___exception_is_thrown
这里还有一个小技巧,若是一个测试真的没有given的时候,或given不重要的时候,能够省略,可是___
不能省略:code
___xxx_xxx___xxx_xxx
ip
能够总结一下这种命名方式的优势:开发
固然,也是有缺点的:
我用这种方式写出来的测试名字通常都比较长,这个有多是我用词还不够精炼,在given、when的部分可能有时候是有一部分重复的
因此也须要刻意练习,学会精简用词。get
最后,给这种命名方式命个名吧,就叫GWT测试命名法好了。博客
我在项目上发现,不少人习惯在构建fake数据的时候直接将全部信息屏蔽,就提供一个createX()的方法,
在createX的方法里面可能还要构建X的构成部分:
X createX() { Y yyy = new Y; X xxx = new X(YYY, field1, field12); return xxx; }
除了createX外还有createAX、createBX,而后在不一样的测试里面混合调用。
做为看测试的我,我就很难看到到底须要一个怎样的场景,field1究竟是怎么设置的,field2究竟是怎么设置
的,并且在想改一下createX的时候,还会牵扯到其余的测试莫名其妙就挂了。
我目前使用的解决方式是这样的:
先要肯定好测试要涉及到的重要信息,好比上面若是field1,field2都会对测试的逻辑起到做用,
那么,即便冗余,也必定要写在测试方法内。好比:
@Test void ___xxx___xxx() { Y y = createY(); X x = createX(field1, field12, y) // do some thing // assert some thing }
这么作的好处是,当我要看某一个测试的时候,它的前置数据我一眼就能看出来,不须要不停地command+b跟进去才知道须要什么。
在应用第一条原则的时候,必定要记得,只罗列出这个测试所关心的数据。假如field3彻底不参与此次
逻辑的处理,又必需要有值,那么,在createX内部给个默认值便可,不须要放在createX参数列表中。
其实以前也试过用builder,可是看起来太多了,适用create的方式能缩短要写得代码行数,更容易一眼看完测试。