android studio+jacoco gets code coverage

Recently, I checked the code coverage on the Internet for a long time when doing Android testing, and encountered many pitfalls. I will briefly record it here, mainly referring to this article https://www.jianshu.com/p/671fad23c2ce

Introduction to jacoco

jacoco is the abbreviation of Java Code Coverage. As the name suggests, it is one of the mainstream tools for Java code coverage statistics. The code coverage statistics of Android projects use jacoco's offline instrumentation method. Before testing, the files are instrumented, and then the instrumented class or jar package is generated and tested (unit test, UI test or manual test, etc.) After inserting the stub's class and jar packages, dynamic coverage information will be generated to the file. Finally, the coverage information will be processed uniformly and a report will be generated.

android studio+jacoco configuration

1. Configure build.gradle

Open the project using Android Studio, open the build.gradle file, add the following:
Add the jacoco plugin and set the version
Insert image description here

apply plugin: 'jacoco' //加载代码覆盖库jacoco

jacoco {
    
    
    toolVersion = "0.7.9" //代码覆盖库jacoco版本号
}

Enable jacoco in buildTypes
Insert image description here

testCoverageEnabled = true

Add related settings for generating reports
Insert image description here

//代码覆盖率相关配置
def coverageSourceDirs = [
        '../app/src/main/java'
]

task jacocoTestReport(type: JacocoReport) {
    
    
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."

    reports {
    
    
        xml.enabled = true
        html.enabled = true
    }

    classDirectories = fileTree(
            //检测覆盖率的class所在目录(以项目class所在目录为准)
            dir: './build/intermediates/javac/debug/classes',        
            //增加以上目录中不需要检测的文件列表
//            excludes: ['**/R*.class',
//                       '**/*$InjectAdapter.class',
//                       '**/*$ModuleAdapter.class',
//                       '**/*$ViewInjector*.class'
//            ]
    )
    //设置需要检测覆盖率的目录
    sourceDirectories = files(coverageSourceDirs)
    //存储APP运行时产生报告的路径 
    executionData = files("$buildDir/outputs/code-coverage/connected/code_coverage.ec") 
}

2. Configure AndroidManifest.xml

Confirm that the APP has permission to read and write files
Insert image description here

3. Configure project code

Add a method to generate code coverage in onDestory in the base class Activity

public class BaseActivity extends AppCompatActivity {
    
    

    public static String DEFAULT_COVERAGE_FILE_PATH = Environment.getExternalStorageDirectory()+"/";

    @Override
    protected void onDestroy() {
    
    
        generateCoverageFile();
        super.onDestroy();
    }

    /**
     * 生成executionData
     */
    public void generateCoverageFile() {
    
    
        OutputStream out = null;
        try {
    
    
            out = new FileOutputStream(DEFAULT_COVERAGE_FILE_PATH + "/code_coverage.ec", false); //在SDcard根目录下生产检测报告,文件名自定义
            Object agent = Class.forName("org.jacoco.agent.rt.RT").getMethod("getAgent").invoke(null);
            // 这里之下就统计不到了
            out.write((byte[]) agent.getClass().getMethod("getExecutionData", boolean.class).invoke(agent, false));           
        } catch (Exception e) {
    
                
        } finally {
    
    
            if (out != null) {
    
    
                try {
    
    
                    out.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

4. Generate code coverage files

After the project is built successfully, click Gradle->app->install->installDebug to install the application and
Insert image description here
start the application. Click manually or execute the automated script. After the execution is completed, exit the application and kill the process. Use the adb shell command to enter the scard directory to check whether it is generated. code_coverage.ec file, if the file is generated, use adb pull to pull the file to the local

5. Generate reports

Put the pulled code_coverage.ec file into the project app/build/outputs/code-coverage/connected/ directory. If there is no such directory, you can create it manually. Note that the path here must be the same as the "executionData" written in build.gradle above. "Same.
Insert image description here
Click Gradle->app->reporting->jacocoTestReport, and the report will be generated in the app\build\reports directory of the project. The report will be
Insert image description here
generated in the following location of the project.
Insert image description here
Open the index.html file under the html directory to view it on the web page. code coverage
Insert image description here
Insert image description here
Insert image description here
Insert image description here

6. Frequently Asked Questions

The code_coverage.ec file is not generated.
1. Check whether the project configuration is correct.
2. Confirm in which life cycle the method of obtaining code coverage is added. For example, if added in onDestory, the application process needs to be killed after the operation is completed to generate coverage. The code_coverage.ec file
has been generated, but the data in the generated report is empty. Check
whether the configuration address in build.gradle is consistent with the local project.
Insert image description here
Code execution cannot be viewed in the report.
Check whether the source code configuration path in build.gradle is consistent with the local project.
Insert image description here

Guess you like

Origin blog.csdn.net/y954227239/article/details/117450085
Recommended