1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Android studioでJacocoを使って、手動で一つずつテストケースを実行して、カバレッジレポートを作成する方法

Last updated at Posted at 2021-04-02

Android studioでtestCoverageEnabledフラグをtrueにしたら、createDebugCoverageReportという機能が使えます。
しかしcreateDebugCoverageReportを実行したら、全てのUnit test / Instrumented testのテストケースが実行されます。環境に依存するテストケース(Internet、周辺機器など)がFailになってしまいます。

本文は手動でカバレッジレポートの作成方法を説明します。

#実行環境
・Android Studio 4.1.1
・compileSdkVersion 29
・Gradle version 6.5

#jacoco.gradleの作成
appあるいはmoduleのbuild.gradleと同じフォルダーにjacoco.gradleを作成します。

jacoco.gradle
apply plugin: 'jacoco'
jacoco {
    toolVersion = "0.8.4"
    reportsDir = file("$projectDir/reports")
}

task jacocoTestReport(type: JacocoReport) {
    group = "Reporting"
    description = "Generate Jacoco coverage reports after running tests."
    reports {
        xml.enabled = true
        html.enabled = true
    }
    def coverageClassDirectories = fileTree(
            dir: "$buildDir/intermediates/javac/debug/classes",
            excludes: ['**/R*.class',
                       '**/*$InjectAdapter.class',
                       '**/*$ModuleAdapter.class',
                       '**/*$ViewInjector*.class'
            ])

    def coverageSourceDirs = [
            "$buildDir/../src/main/java"
    ]

    def coverageExecutionData = files("$projectDir/reports/coverageEC/coverage.exec")

    getClassDirectories().setFrom(coverageClassDirectories)
    getSourceDirectories().setFrom(coverageSourceDirs)
    getExecutionData().setFrom(coverageExecutionData)
}

coverageExecutionData は自分好きな所に設定してください。
後で手動でcoverage.execをこっちにコピーして、Android studioでcoverage.execを読み込んでレポートを生成します。

#build.gradleの設定

ファイルの上にjacoco.gradleのインポートを追加します。

build.gradle
apply from: "jacoco.gradle"

debugの所に「testCoverageEnabled = true」を追加します。

build.gradle
    buildTypes {
        //...
        debug {
            testCoverageEnabled = true
        }
    }

jacoco.gradleとbuild.gradleを変更したら一回「Sync Project with Gradle Files」を押してください。
image.png

GradleウインドウにjacocoTestReportが現れたはずです。
後で使うので、今放っておいてください。
image.png

#クラスJacocoUtilsの制作
Instrumentation testの所(Android studioのデフォルトテスト例ExampleInstrumentedTest.java同じフォルダー)にJacocoUtils.javaを作成します。
後でInstrumentation testのテストケースで使います。

JacocoUtils.java
package Example.package.name;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

class JacocoUtils {
    static String TAG = "JacocoUtils";

    private static String DEFAULT_COVERAGE_FILE_PATH = "coverage.exec";

    /**
     * execファイルを生成する
     *
     * @param isnew execファイルを作り直すか。
     */
    public static void generateEcFile(Context context, boolean isnew) {
        Log.d(TAG, "カバレッジファイル生成: " + DEFAULT_COVERAGE_FILE_PATH);
        OutputStream out = null;
        File mCoverageFilePath = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),DEFAULT_COVERAGE_FILE_PATH);

        try {
            if (isnew && mCoverageFilePath.exists()) {
                Log.d(TAG, "旧execファイルを削除");
                mCoverageFilePath.delete();
            }
            if (!mCoverageFilePath.exists()) {
                mCoverageFilePath.createNewFile();
            }
            out = new FileOutputStream(mCoverageFilePath.getPath(), true);

            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) {
            Log.e(TAG, "generateEcFile: " + e.getMessage());
        } finally {
            if (out == null)
                return;
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

#ExampleInstrumentedTest.javaの変更
ExampleInstrumentedTest.javaにJacocoUtilsの使用を追加します。
テストが終わったらtearDownが実行されるので、必ずexecファイルが生成されます。

ExampleInstrumentedTest.java
public class ExampleInstrumentedTest1{
    @After
    public void tearDown() throws Exception {
        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        JacocoUtils.generateEcFile(appContext, false);
    }

    @Test
    public void ExampleInstrumentedTest1 () {
        //Do something to test
    }
}

#テストケースの実行
image.png

DebuggerのConsole画面でカバレッジファイル生成のメッセージが見えるはずです。
image.png

*もっとテストケースをしたらcoverage.execのサイズがだんだん増えていって、カバレッジも増えます。

#Android機器からcoverage.execをコピーする
USBでAndroid機器をPCと接続して、
「[Android機器名]\内部共有ストレージ\Android\data\[package名]\files\Documents\coverage.exec」を
「[project名]\app\reports\coverageEC\」にコピーします。(存在しないフォルダーがあったら手動で生成)

#カバレッジレポートの生成
jacocoTestReportのRunを実行してください。
image.png

「[Project名]\app\reports\jacocoTestReport\html」でカバレッジレポートが生成されるはずです。
image.png

index.htmlを見てみます。
image.png
できました!

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?