Spock 单元测试框架实战指南三 - f esle 多分支场景测试
一. Expect + Where
如果业务比较复杂,对应的代码实现会有不同的分支逻辑,类似下面的伪代码:
这样的 if else
嵌套代码因为业务的原因很难避免,如果要测试这样的代码,保证覆盖到每一个分支逻辑的话,使用传统的Junit单元测试代码写起来会很痛苦和繁琐,虽然可以使用Junit的@parametered
参数化注解或者dataprovider的方式,但还是不够直观,调试起来也不方便
下面就结合具体业务代码讲解Spock如何解决这种问题,还是先看下业务代码逻辑:
根据输入的身份证号码识别出生日期、性别、年龄等信息,逻辑不复杂,就是分支多,我们来看下Spock代码是如何测试这种情况:
在测试方法体的第一行使用了expect
标签,它的作用是when
+ then
标签的组合,即 "什么时候做什么 + 然后验证什么结果" 组合起来
即当调用IDNumberUtils.getBirAgeSex(idNo)
方法时,验证结果是result,result如何验证对应的就是where里的result一列的数据,当输入参数idNo是"310168199809187333"时,返回结果是: ["birthday": "1998-09-18", "sex": "男", "age": "22"]
expect
可以单独使用,可以不需要where
,只是在这个场景需要
@Unroll
注解表示展开where标签下面的每一行测试,作为单独的case跑,再加上方法体"身份证号:#idNo 的生日,性别,年龄是:#result",使用了groovy的字面量特性,动态替换字符串变量,这样每次跑的单测结果展示也很容易区分,方便理解,如下:
每个测试结果对应where标签里的一行
另外在intellij idea里可以run with coverage的运行方式查看单测覆盖率情况:
左边圈出的绿色柱子表示单测已覆盖的代码,红色柱子是单测还没有覆盖到的分支,如果需要进一步提高覆盖率,只需在where表格中再添加一行测试条件即可
二. Jacoco
Jacoco是统计单元测试覆盖率的一种工具,当然Spock也自带了覆盖率统计的功能,这里使用第三方Jacoco的原因主要是国内公司使用的比较多一些,包括我们公司现在使用的也是Jacoco,所以为了兼容就以Jacoco来查看单测覆盖率
当然你也可以使用Spock自带的单测覆盖率工具,在后面的文章里会介绍具体如何配置,本篇主要说下如何通过Jacoco确认分支是否完全覆盖到
在pom文件里引用jacoco的插件: jacoco-maven-plugin
, 然后执行mvn test
命令,成功后会在target目录下生成单元测试覆盖率的报告:
(具体生成路径可以设置)
使用浏览器打开index.html,就能看到所有的单测覆盖率统计指标:
点击包名找到我们刚才测试的IDNumberUtils类,打开后可以看到具体的覆盖情况:
绿色背景表示完全覆盖,黄色是部分覆盖,红色没有覆盖到
比如第45行黄色背景的else if()
判断,提示有4分之2的分支缺失,虽然它下面的代码也被覆盖了(显示为绿色),但是因为我们的单测代码没有测试flag为false,以及certificateNo.length()!=18
的场景,所以只能算覆盖了一半(2/4)
讲这个的原因是因为如果公司设置的分支覆盖率要求大于50%,那么你就要在单元测试代码里额外增加这种情况的测试,即使业务代码里没有这样例外情况的处理
这种情况跟具体使用哪种单测框架没关系,因为这只是分支覆盖率统计的规则,只不过使用Spock的话,解决起来会更简单,只需在where下增加一行针对的测试数据即可
评论