一、什么是代码覆盖率?
简单来说就是: app运行跑一遍,就能统计出什么类什么方法执行了。说到作用,我感觉没什么卵用。。
看看大牛的解析。
http://www.cnblogs.com/coderzh/archive/2009/03/29/1424344.html
二、EMMA进行手工代码覆盖率(过时)
http://clasnake.net/emma_for_android/
三、Jacoco结合case进行自动代码覆盖率(不好)
http://blog.csdn.net/itfootball/article/details/45503883
四、Jacoco手工增强版本
http://blog.csdn.net/itfootball/article/details/45618609
cocerage.ec 转为html报告的方法:
http://blog.csdn.net/itfootball/article/details/45644159
五、Appium自动化测试顺便收集代码覆盖率
上面的测试方法都有点坑的,例如Instrument启动的是WelcomeActivity,这个activity被finish了,整个app就退出了。
Appium支持Instrument启动的,之前说的文档capabilities里面就有一个参数androidCoverage
1. 为项目添加Instrumentation入口
我是在com目录下创建了一个appiumInstrument文件夹存放,放入下面两个文件,,
注意: getLaunchIntentForPackage(“com.minstone.mdoctor”) 里面改为你应用的包名
MyInstrumentation.java
package com.appiumInstrument;
import android.app.Instrumentation;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
public class MyInstrumentation extends Instrumentation {
private Intent intent;
@Override
public void onCreate(Bundle arguments) {
intent = getTargetContext().getPackageManager()
.getLaunchIntentForPackage("com.minstone.mdoctor")
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
start(); // creates new thread which invokes onStart
}
@Override
public void onStart() {
startActivitySync(intent);
LocalBroadcastManager.getInstance(getTargetContext()).registerReceiver(
new EndEmmaBroadcast(), new IntentFilter("com.example.pkg.END_EMMA"));
}
}
EndEmmaBroadcast.java
package com.appiumInstrument;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Process;
import android.util.Log;
import java.io.File;
// adb shell am broadcast -a com.example.pkg.END_EMMA
@SuppressLint("SdCardPath")
public class EndEmmaBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("AppiumEmma", "EndEmmaBroadcast broadcast received!");
// reflection is used so emma doesn't cause problems for other build targets
// that do not include emma.
try {
Class.forName("com.vladium.emma.rt.RT")
.getMethod("dumpCoverageData", File.class, boolean.class, boolean.class)
.invoke(null, new File("/mnt/sdcard/coverage.ec"), false, false);
} catch (Exception e) {
Log.d("AppiumEmma", e.toString());
}
// once coverage is dumped, the processes is ended.
Process.killProcess(Process.myPid());
}
}
2. 配置AndroidManifest.xml
在Application标签里面添加:
<receiver android:name="com.appiumInstrument.EndEmmaBroadcast" >
<intent-filter>
<action android:name="com.example.pkg.END_EMMA" />
</intent-filter>
</receiver>
在Application标签外添加 (targetPackage会有警告,这个不影响,不予理会):
<instrumentation
android:name="com.appiumInstrument.MyInstrumentation"
android:targetPackage="com.minstone.mdoctor" >
</instrumentation>
3. 修改appium脚本
上一步做完之后,重新编译安装ap到测试机。然后退出app。
capabilities添加androidCoverage属性。
//androidCoverage的格式为: "com.minstone.mdoctor/com.appiumInstrument.MyInstrumentation"
capabilities.setCapability("androidCoverage", androidCoverage);
然后在quit前endTestCoverage,第一个参数为广播的action,第二参数为保存路径
@AfterTest
public void afterTest() {
driver.endTestCoverage("com.example.pkg.END_EMMA","/mnt/sdcard/coverage.ec");
driver.quit();
}
4. 生成报告
然后开始你的测试,测试完成之后,在内存卡根目录看到coverage.ec。 按照Q博士大牛的做法就就可以生成对应的html报告
报告大概这样
5. 合并报告
每个用例跑完之后把文件拷贝出来,然后全部跑完之后就可以进行合并了。
妈个鸡,合并不了,求大牛指导,我用下面的命令把多个用例生成的ec文件合并,但是没有生成合并后的文件,。。。
java -cp emma.jar emma merge -input SM1.ec, SM2.ec -outfile SM.ec