单元测试在工作中是非常重要的,不过也不能太多的钻牛角尖,有时候项目进度非常赶,就需要放弃一些单元测试,覆盖率就不是非常高了,只要求保证功能正常就可以。
通常情况,还是要求尽量覆盖到单元测试的每一个角落,这样才能让我们的程序更加完美的运行。
单元测试工具使用
我工作中常使用 jacoco 做单元测试,它也是非常常见和常用的一个java单元测试覆盖率的工具。
- pom .xml文件中的import
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
</plugin>
一个plugin通常有很多的excute,都有什么呢?可以使用下面命令先看下jacoco的信息
mvn help:describe -Dplugin=org.jacoco:jacoco-maven-plugin -Ddetal
看到有很多的goals、executions等等各种信息,大家感兴趣可以自己看看。
接下来再配置executions
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.5.201505241946</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<!–打包阶段–>
<phase>prepare-package</phase>
<goals>
<!–打报告–>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-check</id>
<phase>prepare-package</phase>
<goals>
<goal>check</goal>
</goals>
<!–check的规则,排除实体类等不需要单测的类–>
<configuration>
<rules>
<rule>
<!–以类为单位测试–>
<element>CLASS</element>
<!–哪些类–>
< include s>
<include>com.gongsi.service.*.*</include>
<include>com.gongsi.repository.*.*</include>
</includes>
<!–测查的限定–>
<limits>
<limit>
<!–以代码行为单位–>
< counter >LINE</counter>
<!–覆盖率–>
<value>COVEREDRATIO</value>
<!–覆盖的最低比率–>
< minimum >0.80</minimum>
</limit>
</limits>
</rule>
</rules>
</configuration>
</execution>
</executions>
</plugin>
- 在终端运行mvn clean package,通过测试会生成测试报告“site”目录,不通过就只有“surefire-reports”目录
查看测试报告
- 浏览器打开测试报告,在“site”目录中的“jacoco”目录的index.html文件
- 从上图中最后一行看到通过率99%(如下图),点击进入该包
- 可以看到在包中每个类都通过了(如下图),继续点击某个类
- 可以看到该类的方法(如下图),点击某个方法
- 可以看到代码页(如下图),绿色的代表走过了单测,红色代表没有单测没有覆盖
我们使用jacoco的目标在哪里呢?是用它爆出的一些红色,就是单测没有通过的地方或者没有覆盖的地方。
如何覆盖到呢?鼠标移动到红色代码上,会出现具体提示
上图中爆红的代码:
if(rentSearch.getPriceBlock()!=null&&!”*”.equals(rentSearch.getPriceBlock())){
RentValueBlock priceBlock= RentValueBlock.matchPrice(rentSearch
.getPriceBlock());
int min=priceBlock.getMin();
int max=priceBlock.getMax();
if(min!=-1){
predicate=criteriaBuilder.and(predicate,criteriaBuilder
.greaterThanOrEqualTo
( root .get(“price”),min));
}
if(max!=-1){
predicate=criteriaBuilder.and(predicate,
criteriaBuilder.lessThanOrEqualTo
(root.get(“price”),max));
}
}
如何改正爆红呢?比如这段代码的第一行,”!=null”的条件,那还有个跟它相对应的“==null”的条件也要考虑到,就是单测要写各种各样的条件,覆盖代码。
需要注意的是我们并不是一味的追求覆盖率报告,不是必须要达到100%的,通常以我在工作中的经验是80%就基本上非常好了。然后还可以设定具体的包,排除一些不需要测试的包。