Spring Boot STS利用

STSでPowerMockを利用したJUnitのテストカバレッジを測定してみた

STS(Eclipse)上で、EclEmmaというツールを利用してテストカバレッジを測定すると、PowerMockを利用したJUnitのソースコードの場合、カバレッジが0%になってしまう。

ただ、jacocoを利用するようにすれば、PowerMockを利用したJUnitのソースコードであっても、カバレッジを正確に測定することができる。

今回は、jacocoを利用してPowerMockを利用したJUnitのテストカバレッジを測定してみたので、その手順を共有する。

前提条件

下記記事の実装が完了していること。

PowerMockを利用して処理途中でnewしているクラスをMock化してみた処理途中でnewしているクラスをMock化するには、PowerMockitoのwhenNewメソッドを利用する必要がある。また、Powe...

また、STS上で下記記事のEclEmmaを導入が完了していること。

STSでJUnitのテストカバレッジを測定してみたテスト対象のプログラムのうち、どのくらいのテストが完了したかを示す指標を「テストカバレッジ」といい、STS(Eclipse)上でテストカ...



やってみたこと

  1. EclEmmaを利用したカバレッジの測定
  2. jacocoを利用したカバレッジの測定

EclEmmaを利用したカバレッジの測定

EclEmmaを利用してPowerMockを利用したJUnitのテストカバレッジを測定した場合の実行結果は、以下の通り。

1) demoプロジェクトに下記記事のソースコードを反映

PowerMockを利用して処理途中でnewしているクラスをMock化してみた処理途中でnewしているクラスをMock化するには、PowerMockitoのwhenNewメソッドを利用する必要がある。また、Powe...

2) 「DemoControllerTest」クラスを選択し右クリックし、「実行」メニューから「JUnitテスト」を選択
EclEmmaの利用_2

3) 以下のように、JUnitのテストが正常終了し、コンソールにSystem.out.printlnで出力した結果が表示されることが確認できる
EclEmmaの利用_3

4) 「DemoControllerTest」クラスを選択し右クリックし、「実行」メニューから「カバレッジ」の「JUnitテスト」を選択
EclEmmaの利用_4

5) 下方の「カバレッジ」ビューに、カバレッジの測定結果が出力されるが、テストしたはずのDemoControllerのカバレッジが0%になっている
EclEmmaの利用_5



jacocoを利用したカバレッジの測定

jacocoを利用してPowerMockを利用したJUnitのテストカバレッジを測定した場合の実行結果は、以下の通り。

1) build.gradleを以下のように変更し、Gradleプロジェクトをリフレッシュ

plugins {
	id 'org.springframework.boot' version '2.1.7.RELEASE'
	id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

configurations {
  jacoco
  jacocoRuntime
}

task instrument(dependsOn: ['classes']) {
    ext.outputDir = buildDir.path + '/classes-instrumented'
    doLast {
        print "sourceSets.main.output.classesDirs: ${sourceSets.main.output.classesDirs}"
        ant.taskdef(name: 'instrument',
                classname: 'org.jacoco.ant.InstrumentTask',
                classpath: configurations.jacoco.asPath)
        ant.instrument(destdir: outputDir) {
            sourceSets.main.output.classesDirs.each { fileset(dir: it) }
        }
    }
}

gradle.taskGraph.whenReady { graph ->
    if (graph.hasTask(instrument)) {
        tasks.withType(Test) {
            doFirst {
                systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/tests.exec'
                classpath = files(instrument.outputDir) + classpath + configurations.jacocoRuntime
            }
        }
    }
}

task report(dependsOn: ['instrument', 'test']) {
    doLast {
        ant.taskdef(name: 'report',
                classname: 'org.jacoco.ant.ReportTask',
                classpath: configurations.jacoco.asPath)
        ant.report() {
            executiondata {
                ant.file(file: buildDir.path + '/jacoco/tests.exec')
            }
            structure(name: 'Example') {
                classfiles {
                    sourceSets.main.output.classesDirs.each { fileset(dir: it) }
                }
                sourcefiles {
                    fileset(dir: 'src/main/java')
                }
            }
            html(destdir: buildDir.path + '/reports/jacoco')
        }
    }
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	//PowerMockが利用できるための設定
	testCompile 'org.powermock:powermock-module-junit4:2.0.0-RC.4'
	testCompile 'org.powermock:powermock-api-mockito2:2.0.0-RC.4'
    //Jacocoが利用できるための設定
    jacoco group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.4', classifier: 'nodeps'
    jacocoRuntime group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.4', classifier: 'runtime'
}

なお、このときの「gradle-wrapper.properties」で読み込んでいるgradleのバージョンは、以下のように、6.4.1とする。
jacocoの利用_1

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

2) コマンドプロンプトを起動し、cdコマンドで、build.gradleのあるディレクトリに移動
jacocoの利用_2_1

なお、移動先のディレクトリに存在するファイルは、以下の通り。
jacocoの利用_2_2

3) コマンドプロンプト上で「gradlew report」を実行
jacocoの利用_3

4) 下記、(build.gradleが存在するディレクトリ)/build/reports/jacoco フォルダ下の、「index.html」をダブルクリックし開く
jacocoの利用_4

5)「index.html」を開いた結果は以下の通り。ここで「com.example.demo」リンクを押下
jacocoの利用_5

6) 以下のように、クラス毎のカバレッジが出力され、DemoControllerクラスのカバレッジが100%になっていることが確認できる
jacocoの利用_6

要点まとめ

  • STS(Eclipse)上でPowerMockを利用したJUnitのソースコードのカバレッジを測定するには、jacocoを利用すればよい。