cobertura 是一个代码覆盖测试工具。
wget https://jaist.dl.sourceforge.net/project/cobertura/cobertura/2.1.1/cobertura-2.1.1-bin.zip
7z x cobertura-2.1.1-bin.zip
还是用之前分析的方法,用命令行的方式执行之后做对比
cobertura也有提供了命令行的方式
不过发现是window下的 :(
我做了一点转化。
brew install dos2unix
chmod +x cobertura-instrument.sh && \
chmod +x cobertura-report.sh && \
dos2unix cobertura-instrument.sh && \
dos2unix cobertura-report.sh
vim Test.java
public final class Test{
public String me = "Yeshen";
public static void main(String[] args){
Test t = new Test();
System.out.println(t.me);
if(args != null && args.length > 0){
System.out.println(args[0]);
}else{
t.hi();
}
}
public void hi(){
System.out.println("hi");
}
public void nonono(){
System.out.println("nonono");
}
}
javac Test.java
# modify class file
./cobertura-instrument.sh Test.class
# exec class after modify
java -cp .:cobertura-2.1.1.jar:./lib/slf4j-api-1.7.5.jar -Dnet.sourceforge.cobertura.datafile=cobertura.ser Test
# create html report in dir 'out'
./cobertura-report.sh --format html --datafile cobertura.ser --destination out ./
然后在out文件夹下就有html的报告了
接下来还是从字节码看起
javap -c -v Test.class
发现方法长了不少,首先常量池就从原来的41行变成102行
以hi为栗子
修改前
public void hi();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #9 // String hi
5: invokevirtual #7 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 15: 0
line 16: 8
修改后
public void hi();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=4, locals=2, args_size=1
0: ldc #12 // int 0
2: istore_1
3: getstatic #14 // Field __cobertura_counters:[I
6: ldc #54 // int 13
8: dup2
9: iaload
10: ldc #15 // int 1
12: iadd
13: iastore
14: getstatic #36 // Field java/lang/System.out:Ljava/io/PrintStream;
17: ldc #55 // String hi
19: invokevirtual #42 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: getstatic #14 // Field __cobertura_counters:[I
25: ldc #56 // int 14
27: dup2
28: iaload
29: ldc #15 // int 1
31: iadd
32: iastore
33: return
LineNumberTable:
line 15: 3
line 16: 22
看起来是比jacoco做了更多的插入。
从结果来看,可以安全的说cobertura比jacoco慢,依赖比jacoco多。具体实现上有什么不同,要看完代码才能有解答。等有时间再去研究代码实现吧 : )
// TODO
哦,cobertura android gradle可以这样配置使用
build.gradle
repositories {
mavenLocal()
}
dependencies {
classpath 'net.saliman:gradle-cobertura-plugin:2.5.4'
}
app/build.gradle
apply plugin: 'net.saliman.cobertura'
./gradlew cobertura
# cd ./app/build/reports/cobertura