作者:牛小宝
在做性能测试时,需要考虑被测系统的真实使用场景,通过模拟真实的使用场景去压测才能得出具有参考意义的性能指标。而实际的测试中,有些场景却隐藏的很深,比如说下单,虽然下单接口只有一个,但是会根据入参商品的不同类型进行不同的处理逻辑,商品可能是普通商品,也可能是团购商品等,因此接口压测完之后,我们需要分析一下有没有覆盖到预期场景的代码逻辑,或者有没有遗漏的场景未覆盖。这时我们考虑到引入代码覆盖率,可以根据代码的覆盖情况分析出已测场景和未覆盖场景,从而针对性进行补测。所以在测试过程中不能只取关注代码覆盖率这个数值,而是通过代码的覆盖情况增加重要场景的覆盖度,提升性能测试的质量。
获取代码覆盖率的工具很多,比较流行的有Jacoco,Emma,Cobertura等,使用什么样的方式获取当然是取决于我们的需求:
综上考虑,采用Jenkins+jacoco获取代码覆盖率,sonar进行覆盖率的展示,Jenkins和sonar公司是有平台的,使用起来更方便;
-javaagent:/home/qaperf/jenkinsJacoco/lib/jacocoagent.jar=includes=com.netease.*,output=tcpserver,port=8893,address=127.0.0.1
Jacoco获取代码覆盖率的方式有多种,这里采用Ant构建脚本来生成代码覆盖率的二进制文件,Ant构建脚本build.xml的内容如下:
<?xml version="1.0" ?>
<project name="jacoco" xmlns:jacoco="antlib:org.jacoco.ant">
<!--Jacoco的安装路径-->
<property name="jacocoantPath" value="./lib/jacocoant.jar"/>
<!--最终生成.exec文件的路径,Jacoco就是根据这个文件生成最终的报告的-->
<property name="jacocoexecPath" value="./jacoco.exec"/>
<!--生成覆盖率报告的路径-->
<property name="reportfolderPath" value="./report"/>
<!--远程tomcat服务的ip地址,这里使用的是本地服务器-->
<property name="server_ip1" value="127.0.0.1"/>
<!--前面配置的远程tomcat服务打开的端口,要跟上面配置的一样-->
<property name="server_port" value="8893"/>
<!--源代码路径-->
<property name="Srcpath" value="/home/qaperf/jenkinsJacoco/src/global-online/online-war/src/main/java" />
<!--.class文件路径-->
<property name="Classpath" value="/home/qaperf/haitaoTest/performance/webroot-online-Ins1/WEB-INF/classes" />
<!--让ant知道去哪儿找Jacoco-->
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
<classpath path="${jacocoantPath}" />
</taskdef>
<!--dump任务:
根据前面配置的ip地址,和端口号,
访问目标tomcat服务,并生成.exec文件。-->
<target name="dump">
<jacoco:dump address="${server_ip1}" destfile="${jacocoexecPath}" port="${server_port}" append="false" reset="true"/>
</target>
</project>
#ant的构建文件build.xml所在路径
cd /home/qaperf/jenkinsJacoco
#ant所在路径,若已配置环境变量执行执行 ant dump即可
/home/qaperf/jenkinsJacoco/lib/apache-ant-1.9.9/bin/ant dump
# required metadata
#指定唯一key和name
sonar.projectKey=global-online
sonar.projectName=global-online
sonar.projectVersion=1.0
#指定基础路径
sonar.projectBaseDir=/home/qaperf/jenkinsJacoco
#源码路径
sonar.sources=src/global-online/online-war/src/main/java
#class文件路径
sonar.java.binaries=/home/qaperf/haitaoTest/performance/webroot-online-Ins1/WEB-INF/classes
sonar.sourceEncoding=UTF-8
sonar.language=java
#由于只需要展示代码覆盖率,无需静态代码检查,这里为false节省构建时间
sonar.profile=None
sonar.scm.enabled=false
#指定代码覆盖率插件未jacoco
sonar.java.coveragePlugin=jacoco
#指定代码覆盖率二进制文件的路径
sonar.jacoco.reportPath=/home/qaperf/jenkinsJacoco/jacoco.exec
完成以上操作后点击构建,构建完成后就可以去sonar查看结果。
问题一: jacoco获取代码覆盖率时需要工程的源码和class文件,工程部署之后应用服务器上只有编译过的class文件,没有源码,需要自动拉取代码,并且我们在实际使用过程中需要代码分支与omad保持一致;
解决方法:与omad代码保持一致可以通过调用omad的api获取相关代码分支,之后git拉取代码,但是git拉代码时需要输入密码,解决方案是将秘钥添加至ssh-agent后可免密登录,参考 http://cobain-li.iteye.com/blog/2318080, 但是经实际使用,仍然会有让输入密码的情况,所以我们可以把添加ssh-agent的过程写入脚本,每次构建先添加一次,这样后续的pull,checkout之类的操作就不需要密码了,如下:
#!/bin/bash
ssh_path=/home/qaperf/.ssh
git_path=/home/qaperf/jenkinsJacoco/src
#use git without password
cd ${ssh_path}
eval "$(ssh-agent -s)"
/usr/bin/expect << EOF
spawn ssh-add /home/qaperf/.ssh/id_rsa
expect "passphrase"
send "****\r" #此处为ssh密码
expect eof
EOF
问题二:Sonar进行覆盖率展示的时候,并不能直接看出代码覆盖率,而是要点开某一个方法后才能看到,操作繁琐;
解决方案:sonar提供了获取代码覆盖率的api,可以将其中类名和覆盖率数值过滤出来,在Jenkins console中打印出来,这样查看就很直观了,也可以加上类方法的sonar链接,可以直接点击查看源码;
/api/measures/component_tree?baseComponentKey=%s&metricKeys=coverage
获取到代码覆盖率数据之后,重点是对代码覆盖情况进行分析,根据未覆盖的分支梳理出有哪些场景没有覆盖到,然后对这些场景进行评估,根据重要程度决定是否加入用例集或者是否补测,从而提高用例覆盖度和性能测试的质量,如下图:
目前对代码覆盖率的应用还处于摸索阶段,所以需要继续打开脑洞,从日常测试中寻找可以用代码覆盖率辅助解决的痛点。
网易云产品免费体验馆,无套路试用,零成本体验云计算价值。
本文来自网易实践者社区,经作者牛小宝授权发布