浅尝 cobertura

卫浩瀚
2023-12-01

cobertura 是一个代码覆盖测试工具。

下载

sourceforge

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多。具体实现上有什么不同,要看完代码才能有解答。等有时间再去研究代码实现吧 : )

git clone https://github.com/cobertura/cobertura.git

// TODO

Android 使用

哦,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
 类似资料: