emma是一个统计代码测试覆盖率的工具,teamcity默认集成了这个工具。
EMMA 是通过向 .class 文件中插入字节码的方式来跟踪记录被运行代码信息的。EMMA 支持两种模式:On the fly 和 Offline 模式。支持的覆盖率指标:EMMA支持class,method,line和basic block coverage指标。
teamcity采用的offline模式。
要teamcity支持代码覆盖率,首先应该在teamcity控制台上设置如下:
Coverage Info |
Enable code coverage Add 'clean' target in your Ant build for this option to work. Do not use the option for production builds since it will result in EMMA-instrumented class files. Include source files in the coverage data |
You may provide a filter for classes included into code coverage. Please see EMMA documentation for details. |
对于单元测试的覆盖率,teamcity集成的emma已经默认给出了支持。但是对于集成测试的代码覆盖率,却需要我们手工在ant脚本里面进行处理。如何来进行处理,首先让我们看一下emma生成覆盖率的原理:
1.向.class文件插入字节码,并生成metadata文件.em,这一步是在ant 执行javac时完成.
2.执行单元测试或集成测试,会生成运行过的采集文件.ec.
3.通过report,联合这两个文件来生成覆盖率报告.
现在的问题是集成测试的.ec如何merge到单元测试的.ec???
因为我用teamcity,单元测试的.ec默认路径是/opt/ci/teamcity4.5.4/buildAgent/work/xxxxx/下面.
解决的办法就是在启动weblogic的时候,将emma.jar放入classpath中,同时设定
-Demma.coverage.out.file=/opt/ci/teamcity4.5.4/buildAgent/work/xxxxx/coverage.ec
-Demma.coverage.out.merge=true
这样就将集成测试的运行类采集merge到了单元测试的运行类采集文件中.最后teamcity通过emma report根据这两个文件来创建最终的代码覆盖率报告.
所以要merge解决问题的ant脚本做法如下:
<target name="startup">
<echo message="-------- Starting Weblogic AdminServer -----"/>
<exec executable="${domain.home}/startWebLogic.sh">
<env key="JAVA_OPTIONS" value=" -Demma.coverage.out.file=${agent.work.dir}/15a5acdc6db7067d/coverage.ec -Demma.coverage.out.merge=true"/>
<env key="MEDREC_WEBLOGIC_CLASSPATH" value="${emma.jar}"/>
</exec>
</target>
下面是生成的覆盖率报告:
all classes | 14% (212/1493) | 6% (1226/19106) | 4% (16676/377144) | 5% (4539.2/87854) |
total packages: | 173 |
total executable files: | 1370 |
total classes: | 1493 |
total methods: | 19106 |
total executable lines: | 87854 |
com.test | 0% (0/18) | 0% (0/85) | 0% (0/4556) | 0% (0/1007) |
com.test.dao | 0% (0/3) | 0% (0/8) | 0% (0/27) | 0% (0/10) |
com.test.dao.ibatis | 0% (0/21) | 0% (0/113) | 0% (0/8655) | 0% (0/1677) |
com.test.jmx | 0% (0/1) | 0% (0/7) | 0% (0/24) | 0% (0/10) |
com.test.service | 0% (0/4) | 0% (0/26) | 0% (0/269) | 0% (0/82) |
com.test1.vo | 49% (28/57) | 31% (399/1294) | 31% (1421/4631) | 31% (613/1962) |
com.test1.test.service | 80% (4/5) | 32% (13/40) | 32% (142/445) | 31% (41/133) |
com.test1.server.store | 60% (6/10) | 47% (28/60) | 35% (452/1290) | 42% (109.6/264) |
com.test1.util.logging | 100% (3/3) | 30% (13/44) | 37% (239/639) | 34% (62.9/184) |
com.test1.tools.beans | 20% (1/5) | 18% (4/22) | 39% (393/1020) | 39% (108/276) |
com.test1.ejb | 67% (2/3) | 54% (14/26) | 39% (233/597) | 43% (67.8/158) |
com.test1.common | 33% (2/6) | 26% (7/27) | 40% (111/275) | 48% (52/109) |
注意:集成测试所运行的.class必须是metadata文件中所描述的.class,否则报CLASS_STAMP_MISMATCH Error。 这个问题产生的原因是metadata在javac相同的.class时,后面的覆盖前面的。