青年IT男

个人从事金融行业,就职过易极付、思建科技等重庆一流技术团队,目前就职于某网约车平台负责整个支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、人工智能等领域。

JMockit常见用法 -用JMockit做代码覆盖率

JMockit常见用法 -用JMockit做代码覆盖率

说到代码覆盖率,你肯定会想到Jacoco, 其实JMockit相比Jacoco,做代码覆盖率,一样很强大。如果你关心代码的路径覆盖率,JMockit有,而Jacoco没有!

那我们该如何配置JMockit做覆盖率呢?很简单,只需要在pom.xml给surefire(即mvn test背后的maven插件)配置一些参数即可。

在pom.xml中<project><build><plugins>节点给插件surefire增加一些参数即可。
<plugin>
       <artifactId>maven-surefire-plugin</artifactId>
    <version>2.20</version>
    <configuration>
    <disableXmlReport>true</disableXmlReport>
    <argLine>-Dcoverage-metrics=all</argLine>
    </configuration>
</plugin>

执行mvn test后呢?去哪里看覆盖率呢? target/coverage-report目录下,用浏览器找开index.html,就可以看了。

JMockit给我们提供的行覆盖率,路径覆盖率,数据覆盖率。
行覆盖率是从代码行的维度进行统计,哪些行被测试到了,本文不做详细介绍了。
数据覆盖率是指一个类的哪些非静态属性被修改过了,这个不常用,指导意义也不大。本文也不做详细介绍了。
本文重点介绍一下,JMockit的路径覆盖率和Jacoco的分支覆盖率,这2个是非常容易混淆的概念。

咱们先拿几个简单的类来做测试,并分别看其JMockit的路径覆盖率结果,Jacoco的分支覆盖率结果。

比如要测试这个简单的类,


//打招呼的接口 public interface ISayHello { // 性别:男 int MALE = 0; // 性别:女 int FEMALE = 1; /** * 打招呼 * * @param who 向谁说 * @param gender 对方的性别 * @return 返回打招呼的内容 */ String sayHello(String who, int gender); /** * 向多个人打招呼 * * @param who 向谁说 * @param gender 对方的性别 * @return 返回向多个人打招呼的内容 */ List<String> sayHello(String[] who, int[] gender); } public class SayHello implements ISayHello { @Override public String sayHello(String who, int gender) { // 性别校验 if (gender != FEMALE) { if (gender != MALE) { throw new IllegalArgumentException("illegal gender"); } } // 根据不同性别,返回不同打招呼的内容 switch (gender) { case FEMALE: return "hello Mrs " + who; case MALE: return "hello Mr " + who; default: return "hello " + who; } } @Override public List<String> sayHello(String[] who, int[] gender) { // 参数校验 if (who == null || gender == null) { return null; } if (who.length != gender.length) { throw new IllegalArgumentException(); } //把向每个人打招呼的内容,保存到result中。 List<String> result = new ArrayList<String>(); for (int i = 0; i < gender.length; i++) { result.add(this.sayHello(who[i], gender[i])); } return result; } }

上面2个类,一个是接口,另一个是实现该接口的类。 类的功能十分简单,就是向别人打招呼。 假设现在我们要测试SayHello这个类。

测试代码如下:


//代码覆盖率测试,观察覆盖率的计算方式,去target/coverage-report目录下,查看SayHello这个类的覆盖率 public class CodeCoverageTest { ISayHello sayHello = new SayHello(); @Rule public ExpectedException thrown = ExpectedException.none(); //测试 sayHello(String who, int gender); @Test public void testSayHello1() { Assert.isTrue(sayHello.sayHello("david", ISayHello.MALE).equals("hello Mr david")); Assert.isTrue(sayHello.sayHello("lucy", ISayHello.FEMALE).equals("hello Mrs lucy")); thrown.expect(IllegalArgumentException.class); sayHello.sayHello("david", 3); } //测试 sayHello(String[] who, int[] gender) @Test public void testSayHello2() { String[] who = new String[] { "david", "lucy" }; int[] gender = new int[] { ISayHello.MALE, ISayHello.FEMALE }; List<String> result = sayHello.sayHello(who, gender); Assert.isTrue(result.get(0).equals("hello Mr david")); Assert.isTrue(result.get(1).equals("hello Mrs lucy")); } }

测试代码功能也十分简单,用几种常用的入参做了测试。 测试运行后(mvn test或idea/eclipse运行测试),就在target/coverage-report目录下,生成了覆盖的结果,从结果中,我们可以打开SayHello类的覆盖率结果。

接下来,我们再用Jacoco来做覆盖率的统计(Jacoco的使用方法,本文这里不就介绍了), 其分支覆盖率测试结果如下:

  上图中,已经描述了JMockit路径覆盖率与Jacoco分支覆盖率的区别。 
你更喜欢哪一个呢?反正我比较喜欢JMockit路径覆盖率,因为JMockit的路径覆盖率报告中,清晰了标注了类的方法有哪些执行路径,每一个执行路径不正是我们单元测试的测试目标么?
0
1028826685@qq.com