LoginSignup
5
6

More than 5 years have passed since last update.

GradleでPowerMockとjacocoの喧嘩を仲裁

Posted at

概要

とあるPJでjavaのUTのカバレッジ100%目指して
jacocoでカバレッジレポート作成してみたら、
test_coverage.png
のように軒並み0%になっちゃう。

どうやらpowermockとかいう荒くれ者がjacocoさんは嫌いなようで・・・
とは言ってもpowermock依存症なんデス。

回避策

Second way to get code coverage with JaCoCo - use offline Instrumentation.

どうやらOffline Instrumentationしろと。
Mavenでの実装例しかないしあんまりGradleでの書き方の記事が無いので書いてみようかと。

依存関係

build.gradle
dependencies {
  testCompile group: 'org.mockito', name: 'mockito-core', version: '2.2.7'
  testCompile group: 'org.powermock', name: 'powermock-api-mockito2', version: '2.0.0-beta.5'
  testCompile group: 'org.powermock', name: 'powermock-module-junit4', version: '2.0.0-beta.5'

  jacoco group: 'org.jacoco', name: 'org.jacoco.ant', version: '0.8.2', classifier: 'nodeps'
  jacocoRuntime group: 'org.jacoco', name: 'org.jacoco.agent', version: '0.8.2', classifier: 'runtime'
}

ちなみにOffline Instrumentationが働くのはpowermockの1.6.6以降らしいのでご注意を。

Offline Instrumentation

build.gradle
configurations {
  jacoco
  jacocoRuntime
}

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

gradle.taskGraph.whenReady { graph ->
  if (graph.hasTask(instrument)) {
    tasks.withType(Test) {
      doFirst {
        systemProperty 'jacoco-agent.destfile', buildDir.path + '/jacoco/jacoco-coverage.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/jacoco-coverage.exec')
      }
      structure(name: 'Example') {
         classfiles {
           fileset(dir: sourceSets.main.output.classesDir)
         }
         sourcefiles {
           fileset(dir: 'src/main/java')
         }
      }
      html(destdir: buildDir.path + '/reports/jacoco/test/html')
    }
  }
}

コンパイル直後にinstrumentして、test+jacocoって感じですかね。
これでreportタスク実行してみると、

coverage_after.png

無事にPowerMockとjacocoが仲直りできました。

感想

instrumentってのがまだ何してんのかはよくわかっとらん。
実際はマルチプロジェクト構成なので、カバレッジレポート結合したいですね~。

ということで次回はマルチプロジェクトで様々なドキュメント結合でもしてみます。

5
6
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
5
6