jacco.zip
更新后可能需要更改的地方
https://www.cnblogs.com/renjiaqi/p/11456358.html
使用教程
https://blog.csdn.net/qq_27103959/article/details/74549964

gradle报错相关解决办法
https://www.jianshu.com/p/e0ba79c83183
https://blog.csdn.net/zengsidou/article/details/79797417

使用步骤

1.更改app目录里的gradle文件

  1. apply plugin: 'com.android.application'
  2. apply plugin: 'jacoco'//添加插件jacoco
  3. jacoco {
  4. toolVersion = "0.7.9"//声明jacoco的版本号
  5. }
  6. android {
  7. compileSdkVersion 25
  8. buildToolsVersion "25.0.2"
  9. defaultConfig {
  10. applicationId "com.weex.jasso"
  11. minSdkVersion 16
  12. targetSdkVersion 25
  13. versionCode 1
  14. versionName "1.0"
  15. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  16. }
  17. buildTypes {
  18. debug {
  19. testCoverageEnabled = true//设置为true
  20. }
  21. }
  22. }
  23. dependencies {
  24. compile fileTree(include: ['*.jar'], dir: 'libs')
  25. androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
  26. exclude group: 'com.android.support', module: 'support-annotations'
  27. })
  28. compile 'com.android.support:appcompat-v7:25.1.1'
  29. //compile 'org.jacoco:org.jacoco.core:0.7.9' 旧语法导入jacoco的版本包
  30. implementation 'org.jacoco:org.jacoco.core:0.7.9'//新语法导入jacoco的版本包
  31. compile 'com.android.support.constraint:constraint-layout:+'
  32. }
  33. //添加资源目录
  34. def coverageSourceDirs = [
  35. '../app/src/main/java'
  36. ]
  37. //建立task任务将outputs/code-coverage/connected/目录下coverage.ec文件的生成覆盖率报告
  38. task jacocoTestReport(type: JacocoReport) {
  39. group = "Reporting"
  40. description = "Generate Jacoco coverage reports after running tests."
  41. reports {
  42. xml.enabled = true
  43. html.enabled = true
  44. }
  45. classDirectories.from = fileTree(
  46. dir: './build/intermediates/javac/debug/classes',
  47. excludes: ['**/R*.class',
  48. '**/*$InjectAdapter.class',
  49. '**/*$ModuleAdapter.class',
  50. '**/*$ViewInjector*.class'
  51. ])
  52. sourceDirectories.from = files(coverageSourceDirs)
  53. executionData.from = files("$buildDir/outputs/code-coverage/connected/coverage.ec")
  54. doFirst {
  55. new File("$buildDir/intermediates/javac/debug/classes/").eachFileRecurse { file ->
  56. if (file.name.contains('$$')) {
  57. file.renameTo(file.path.replace('$$', '$'))
  58. }
  59. }
  60. }
  61. }

2.修改基础类BaseActivity

  1. 基础类在oncreate()创建coverage.ec文件用于写入代码覆盖率及方法createFile()方法,在界面关闭的onDestroy()生命周期写入覆盖数据方法closeFile();
  2. 创建文件夹等操作需动态获取安卓读写权限 ```java public abstract class BaseActivity extends Activity { private static final int PERMISSIONS_READ_WRITE_STATE = 300;//读写权限 public static String DEFAULT_COVERAGE_FILE_PATH = Environment.getExternalStorageDirectory() + “/jacco”;//生成覆盖率文件的路径 public static String TAG = Test1Activity.class.getName();//获取activity名字,随实际情况修改 protected void onCreate(Bundle savedInstanceState) {

    1. super.onCreate(savedInstanceState);
    2. //activity创建时,生成测试覆盖率文件
    3. createFile(DEFAULT_COVERAGE_FILE_PATH,"coverage.ec");

    }

    @Override protected void onDestroy() {

    1. super.onDestroy();
    2. //activity关闭时,将数据写入到覆盖率文件中
    3. closeFile();

    }

    //创建覆盖率文件 public void createFile(String path, String fileName) {

    1. File file = null;
    2. file = new File(path, fileName);
    3. //先创建文件夹后在创建文件
    4. if (!file.exists()) {
    5. file.getParentFile().mkdirs();
    6. try {
    7. Toast.makeText(this,"创建文件",Toast.LENGTH_LONG).show();
    8. file.createNewFile();
    9. } catch (IOException e) {
    10. e.printStackTrace();
    11. }
    12. }

    }

    //关闭activity写入数据到覆盖率文件

    1. public void closeFile(){
    2. OutputStream out = null;
    3. try {
    4. out = new FileOutputStream(DEFAULT_COVERAGE_FILE_PATH + "/coverage.ec", false);
    5. Object agent = Class.forName("org.jacoco.agent.rt.RT")
    6. .getMethod("getAgent")
    7. .invoke(null);
    8. out.write((byte[]) agent.getClass().getMethod("getExecutionData", boolean.class)
    9. .invoke(agent, false));
    10. } catch (Exception e) {
    11. Log.d(TAG, e.toString(), e);
    12. } finally {
    13. if (out != null) {
    14. try {
    15. out.close();
    16. } catch (IOException e) {
    17. e.printStackTrace();
    18. }
    19. }
    20. }
    21. }
  1. /**
  2. * 检测读写权限是否开启
  3. */
  4. private static String[] PERMISSIONS_STORAGE = {
  5. "android.permission.READ_EXTERNAL_STORAGE",
  6. "android.permission.WRITE_EXTERNAL_STORAGE" };
  7. public void showReadWriteContacts(){
  8. if (Build.VERSION.SDK_INT >= 23) { //判断是否为android6.0系统版本,如果是,需要动态添加权限
  9. if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
  10. //权限还没有授予,需要在这里写申请权限的代码
  11. ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE, PERMISSIONS_READ_WRITE_STATE);
  12. }
  13. } else {
  14. Toast.makeText(this,"安卓6.0以下",Toast.LENGTH_LONG).show();
  15. }
  16. }

}

  1. <a name="CjRD3"></a>
  2. ### 3.生成报告
  3. 1. 携带编码参数以防乱码,两个选一个就好生成报告
  4. 2. 将手机中的coverage.ec文件复制到build/outputs/code-coverage/connected下,执行task任务即可
  5. ```java
  6. gradlew -Dfile.encoding=UTF-8 jacocoTestReport
  7. gradle -Dfile.encoding=UTF-8 jacocoTestReport