代码覆盖率
代码覆盖率是软件测试中一个重要的评价指标,主要是指程序运行过程中,被执行到的代码在总代码中的占比程度。
现在有很多插件可以实现这个功能,应用比较广的就是JaCoCo,虽然好久没更新了,类似Jetbrain旗下的IDE。默认提供了三种获得代码覆盖率的方式:Intellij IDEA、JaCoCo、Emma。
功能测试代码覆盖率
常规的代码覆盖率通常是在单元测试中,通过编写测试用例,然后执行对应的单元测试,获得代码覆盖率。当然,现在也有挺多自动化生成单元测试的工具,比如EvoSuite,Randoop等。
但是,对于用户交互性比较强的应用,比如Android应用,这种单纯的单元测试显然是满足不了需要的。功能测试就是在真实的使用环境下,人工或者模拟真人对应用进行测试,在这种场景下,生成的代码覆盖率定义其为功能覆盖率。
JaCoCo与Gradle获取功能测试代码覆盖率
常见获取覆盖率的方法分两种,一种是在源码中,以打桩的形式,收集覆盖率数据,针对性较强,但是需要深入源码,另一种是改写应用入口,通过instrument启动应用,记录应用执行期间全局的代码覆盖率。这里,主要针对第二种,主要内容分为两个主要部分:
-
覆盖率数据获取
-
覆盖率数据解析
具体实现
入口文件改写
这里需要添加一个新的入口,接收instrument指令,启动代码覆盖率记录功能,并启动原始应用的入口Activity。涉及的一些代码,网上到处都是,我找了一些改写了一下,除去了一些冗余的代码,也去掉了一些bug。
这里主要包括2个java文件,为了方便管理,我们就单独创建一个package、test,避免和原始代码混淆。
一个Instrument启动器,目的是方便通过instrument指令启动带有coverage记录功能的activity。
package test;
import android.app.Instrumentation;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import java.io.File;
import java.io.IOException;
public class JacocoInstrumentation extends Instrumentation {
public static String TAG = "JacocoInstrumentation:";
private Intent mIntent;
@Override
public void onCreate(Bundle bundle) {
Log.d(TAG, "onCreate(" + bundle + ")");
super.onCreate(bundle);
String DEFAULT_COVERAGE_FILE_PATH = getContext().getFilesDir().getPath() + "/coverage.ec";
File file = new File(DEFAULT_COVERAGE_FILE_PATH);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
Log.d(TAG, "异常 : " + e);
e.printStackTrace();
}
}
mIntent = new Intent(getTargetContext(), InstrumentedActivity.class);
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
start();//调用onStart
}
@Override
public void onStart() {
Log.d(TAG, "onStart()");
super.onStart();
startActivitySync(mIntent);
}
//adb shell am instrument com.ta