jacoco覆盖率实战(十一)
在敏捷的测试金字塔模型中,我们经常谈到最底层是单元测试层面,那么编写的一个类以及一个方法被测试后,是否把所有的
点都考虑点了,或者更加具体的说在测试的角度上,更加想清楚的知道,把一个逻辑测试结束后,是否把所有的测试点都覆盖到了
,这是比较关心的,因为很多的时候,测试点是覆盖到了很多的场景,但是并不代表把程序里面所有的逻辑都测试覆盖到了,所以
就需要来引入覆盖率,它能够清晰的告诉我们一个被测试的类的方法里面,那些逻辑被覆盖到了,那些并没有覆盖到。这地方我们
会使用到jacoco。我们需要在pom.xml文件中加入它,然后执行maven install对它进行下载,这地方我们选择的jacoco的版本是
0.8.6,pom.xml的文件具体如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>ngApp</artifactId> <version>1.0-SNAPSHOT</version> <properties> <!--编译编码--> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <aspectj.version>1.8.10</aspectj.version> </properties> <dependencies> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.10</version> <scope>compile</scope> </dependency> <!--WebDriver的测试框架--> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.141.59</version> </dependency> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-server</artifactId> <version>3.141.59</version> </dependency> <!--引入Allure的框架--> <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-testng</artifactId> <version>2.0-BETA14</version> <scope>test</scope> </dependency> <!--log4的模块--> <!-- https://mvnrepository.com/artifact/log4j/log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!--fastjson库--> <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.75</version> </dependency> <!--单元测试覆盖率信息--> <!-- https://mvnrepository.com/artifact/org.jacoco/jacoco-maven-plugin --> <dependency> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.6</version> <scope>test</scope> </dependency> <!--mockito框架--> <!-- https://mvnrepository.com/artifact/org.mockito/mockito-all --> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> <!--Alure测试报告插件--> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.20</version> <configuration> <argLine> -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" </argLine> <!--生成allure-result的目录--> <systemProperties> <property> <name>allure.results.directory</name> <value>./target/allure-results</value> </property> </systemProperties> </configuration> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>${aspectj.version}</version> </dependency> </dependencies> </plugin> <!--检查代码覆盖率的插件配置--> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.6</version> <executions> <execution> <id>prepare-agent</id> <goals> <goal>prepare-agent</goal> </goals> <configuration> <!--指定jacoco.exec的目录--> <destFile>target/jacoco.exec</destFile> <propertyName>jacocoArgLine</propertyName> </configuration> </execution> <execution> <id>check</id> <goals> <goal>check</goal> </goals> </execution> <execution> <id>report</id> <phase>prepare-package</phase> <goals> <goal>report</goal> </goals> </execution> </executions> <!-- Configuration 里面写配置信息 --> <configuration> <!-- rules里面指定覆盖规则 --> <rules> <rule implementation="org.jacoco.maven.RuleConfiguration"> <element>BUNDLE</element> <limits> <!-- 指定方法覆盖到80% --> <limit implementation="org.jacoco.report.check.Limit"> <counter>METHOD</counter> <value>COVEREDRATIO</value> <minimum>0.80</minimum> </limit> <!-- 指定指令覆盖到80% --> <limit implementation="org.jacoco.report.check.Limit"> <counter>INSTRUCTION</counter> <value>COVEREDRATIO</value> <minimum>0.80</minimum> </limit> <!-- 指定行覆盖到80% --> <limit implementation="org.jacoco.report.check.Limit"> <counter>LINE</counter> <value>COVEREDRATIO</value> <minimum>0.80</minimum> </limit> <!-- 指定类覆盖到100%,不能遗失任何类 --> <limit implementation="org.jacoco.report.check.Limit"> <counter>CLASS</counter> <value>MISSEDCOUNT</value> <maximum>0</maximum> </limit> </limits> </rule> </rules> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.14.1</version> <configuration> <!--testng配置文件名称--> <suiteXmlFiles> <suiteXmlFile>testng.xml</suiteXmlFile> </suiteXmlFiles> <threadCount>1</threadCount> <parallel>tests</parallel> <!--测试失败后忽略继续执行--> <testFailureIgnore>true</testFailureIgnore> <skipTests>false</skipTests> <argLine>-Xmx256M ${jacocoArgLine}</argLine> </configuration> </plugin> </plugins> </build> </project>
我们编写一个简单的案例代码来演示覆盖率这部分的应用,被测试的类的源码为:
package codeCoverage; public class Work { public int getWorkTime(String weather) { switch (weather) { case "星期一": return 1; case "星期二": return 2; case "星期三": return 3; case "星期四": return 4; case "星期五": return 5; default: return 6; } } }
被测试的代码为:
import codeCoverage.Work; import org.testng.*; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class WorkCodeCoverage { private Work work; @BeforeClass public void init() { work=new Work(); } @Test public void testCaseOne() { Assert.assertEquals(work.getWorkTime("星期一"),1); } @Test public void testCaseTwo() { Assert.assertEquals(work.getWorkTime("星期二"),2); } @Test public void testCaseThree() { Assert.assertEquals(work.getWorkTime("星期三"),3); } @Test public void testCaseFour() { Assert.assertEquals(work.getWorkTime("星期四"),4); } @Test public void testCaseOther() { Assert.assertEquals(work.getWorkTime("星期六"),6); } }
testng.xml配置文件的内容为:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"> <!--<suite name="UnitSuite">--> <suite name="Simple Logger Suite" thread-count="1"> <listeners> <listener class-name="test.logger.CustomerLogger"></listener> <listener class-name="test.logger.CustomerReporter"></listener> </listeners> <test name="Run All Tests"> <classes> <class name="WorkCodeCoverage"></class> </classes> </test> </suite>
下来我们具体执行代码,在项目的路径下执行mvn clean test命令后,就会输出如下的信息,具体内容如下:
[INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for org.example:ngApp:jar:1.0-SNAPSHOT [WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-surefire-plugin @ line 194, column 21 [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] [INFO] -------------------------< org.example:ngApp >-------------------------- [INFO] Building ngApp 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ ngApp --- [INFO] Deleting /Applications/code/workSpace/ngApp/target [INFO] [INFO] --- jacoco-maven-plugin:0.8.6:prepare-agent (prepare-agent) @ ngApp --- [INFO] jacocoArgLine set to -javaagent:/Users/liwangping/.m2/repository/org/jacoco/org.jacoco.agent/0.8.6/org.jacoco.agent-0.8.6-runtime.jar=destfile=/Applications/code/workSpace/ngApp/target/jacoco.exec [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ ngApp --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ ngApp --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 5 source files to /Applications/code/workSpace/ngApp/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ ngApp --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Applications/code/workSpace/ngApp/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ ngApp --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 39 source files to /Applications/code/workSpace/ngApp/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:2.14.1:test (default-test) @ ngApp --- [INFO] Surefire report directory: /Applications/code/workSpace/ngApp/target/surefire-reports ------------------------------------------------------- T E S T S ------------------------------------------------------- Running TestSuite SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementation SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details. 执行测试套件内容 Run All Tests 执行时间22:38:11:071 测试方法开始前 testCaseFour 开始时间22:38:11:108 执行成功的测试方法 testCaseFour 执行时间22:38:11:167 测试方法开始前 testCaseOne 开始时间22:38:11:276 执行成功的测试方法 testCaseOne 执行时间22:38:11:278 测试方法开始前 testCaseOther 开始时间22:38:11:281 执行成功的测试方法 testCaseOther 执行时间22:38:11:283 测试方法开始前 testCaseThree 开始时间22:38:11:284 执行成功的测试方法 testCaseThree 执行时间22:38:11:286 测试方法开始前 testCaseTwo 开始时间22:38:11:287 执行成功的测试方法 testCaseTwo 执行时间22:38:11:289 执行完成的测试套件 Run All Tests 执行时间22:38:11:319 通过的测试套件 Simple Logger Suite is 5 失败的测试套件 Simple Logger Suite is 0 忽略的测试套件 Simple Logger Suite is 0 Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.032 sec Results : Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 3.772 s [INFO] Finished at: 2021-01-19T22:38:11+08:00 [INFO] ------------------------------------------------------------------------
如上可以看到,执行完了所有的测试点,同时也是显示了测试结果的概要信息,我们就能够看到执行的耗时以及结果数,也会在target的
目录下生成jacoco.exec的文件,再次执行命令mvn jacoco:report,就会在target的当天目录下生成site的文件夹,里面显示了覆盖率的
测试报告的信息,命令mvn jacoco:report执行后输出的信息:
[INFO] Scanning for projects... [WARNING] [WARNING] Some problems were encountered while building the effective model for org.example:ngApp:jar:1.0-SNAPSHOT [WARNING] 'build.plugins.plugin.(groupId:artifactId)' must be unique but found duplicate declaration of plugin org.apache.maven.plugins:maven-surefire-plugin @ line 194, column 21 [WARNING] [WARNING] It is highly recommended to fix these problems because they threaten the stability of your build. [WARNING] [WARNING] For this reason, future Maven versions might no longer support building such malformed projects. [WARNING] [INFO] [INFO] -------------------------< org.example:ngApp >-------------------------- [INFO] Building ngApp 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- jacoco-maven-plugin:0.8.6:report (default-cli) @ ngApp --- [INFO] Loading execution data file /Applications/code/workSpace/ngApp/target/jacoco.exec [INFO] Analyzed bundle 'ngApp' with 5 classes [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 0.698 s [INFO] Finished at: 2021-01-19T22:38:30+08:00 [INFO] ------------------------------------------------------------------------
我们打开target下的site文件夹下的index.html的内容,就会显示本次测试执行后的覆盖率的情况,打开后的内容如下所示:

打开index.html文件后的信息:

我们点击codeCoverage的包,主要查看Work类的覆盖情况,Work类的覆盖率具体如下所示:

依据如上的信息可以看到,在编写的自动化测试脚本中并没有覆盖到17和18行的代码逻辑,事实上,在我们的测试用例里面确实没有
这个逻辑的验证场景,依据覆盖率测试报告的情况,我们可以继续完善我们的测试点,把我们没有覆盖到的逻辑完善到我们的测试用
例里面,从而协助我们完善测试场景。
感谢您的阅读,后续会持续更新!

浙公网安备 33010602011771号