JUnit5とJaCoCoを連携するとJaCoCoのカバレッジ測定結果を出力してくれない

# 始めに

JaCoCoでcodecovと連携してカバレッジ測定を行おうと思ったときに嵌った問題について、殆どのサイトで取り扱っていなかったようなので書いておきます。

対象プロジェクト: https://github.com/Morichan/ClassesGrammar



# 関連ツール

* Java9
* JUnit5
* Gradle
* JaCoCo
* codecov


# 問題点

jacocoTestReportタスクをスキップするのが根本的な問題でした。
それと同時に、testタスクもスキップしています。


```groovy:build.gradle
apply plugin: 'java'

sourceCompatibility = 9

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
  }
}

apply plugin: 'org.junit.platform.gradle.plugin'

repositories {
  mavenCentral()
}

dependencies {
  testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0'
  testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.0.0'
}

apply plugin: 'jacoco'

jacocoTestReport {
  reports {
    xml.enabled true
    csv.enabled false
    html.enabled true
  }
}
```

```groovy:実行結果
$ gradle clean test jacocoTestReport

:clean
:compileJava
:processResources
:classes
:compileTestJava
:processTestResources NO-SOURCE
:testClasses
:junitPlatformTest

Test run finished after 248 ms
[        10 containers found      ]
[         0 containers skipped    ]
[        10 containers started    ]
[         0 containers aborted    ]
[        10 containers successful ]
[         0 containers failed     ]
[         6 tests found           ]
[         0 tests skipped         ]
[         6 tests started         ]
[         0 tests aborted         ]
[         6 tests successful      ]
[         0 tests failed          ]

:test SKIPPED
:jacocoTestReport SKIPPED

BUILD SUCCESSFUL in 3s
5 actionable tasks: 5 executed
```

iオプションを追加して実行した結果は次の通りです。

```groovy:実行結果（一部省略）
$ gradle -i clean test jacocoTestReport
...

:test (Thread[Task worker for ':',5,main]) started.
:test
Skipping task ':test' as task onlyIf is false.
:test SKIPPED
:test (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs.

:jacocoTestReport (Thread[Task worker for ':',5,main]) started.
:jacocoTestReport
Skipping task ':jacocoTestReport' as task onlyIf is false.
:jacocoTestReport SKIPPED
:jacocoTestReport (Thread[Task worker for ':',5,main]) completed. Took 0.0 secs.

...
```

## テスト結果のHTMLを出力してくれない

正確には、build/test-results/junit-platformにXMLファイルは出力してくれるが、HTMLファイルはbuild/reports/tests/test/index.htmlしか出力してくれず、しかもカバレッジ測定結果を反映してくれない、という問題です。


## codecovページでWoop!

何度送っても、XMLファイルに関するエラーが発生します。
しかし、codecovのエラー画面は、XMLファイル自体が悪いのか、それともXMLファイルの送信が間違っているのかがわかりません。


## カバレッジ測定を実行してくれない

次のサイトによると、JUnit5を使う場合、なんとカバレッジ測定自体を実行してくれないらしいです。

参考: https://nwillc.wordpress.com/2016/10/27/junit5-gradle-no-jacoco/



# 解決法

jacocoTestReportタスクとtestタスクを実行させるために、次のサイトなど[^et.al.]を参考に、build.gradleを書き換えました。

[^et.al.]: testタスクを無視しない設定を参考にしたサイトは見つかりませんでした。

```groovy:build.gradle
apply plugin: 'java'

sourceCompatibility = 9

buildscript {
  repositories {
    mavenCentral()
  }
  dependencies {
    classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0'
  }
}



apply plugin: 'org.junit.platform.gradle.plugin'

repositories {
  mavenCentral()
}

dependencies {
  testCompile 'org.junit.jupiter:junit-jupiter-api:5.0.0'
  testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.0.0'

  testCompileOnly 'org.apiguardian:apiguardian-api:1.0.0'
}



test {
  systemProperties 'property': 'value'
}

junitPlatform.enableStandardTestTask true

apply plugin: 'jacoco'
jacoco {
  toolVersion = '0.7.9'
  applyTo junitPlatformTest
}

junitPlatformTest {
  jacoco {
    destinationFile = file("${buildDir}/jacoco/test.exec")
  }
}



jacocoTestReport {
  afterEvaluate {
    classDirectories = files(classDirectories.files.collect {
      fileTree(dir: it, exclude: ['**/Main*'])
    })
  }
  reports {
    xml.enabled true
    csv.enabled false
    html.enabled true
  }
}
```

参考: http://codegists.com/snippet/gradle/junit5-jacoco-buildgradle_sw-samuraj_gradle

すると、testとjacocoTestReportをスキップせずに、build/reports/jacoco/test/jacocoTestReport.xmlとbuild/reports/jacoco/test/html/index.htmlを出力してくれました。

また、このXMLファイルをもとに、codecovでカバレッジ測定結果を表示してくれるようになりました！

-----

ポイントは、次の箇所あたりにありそうです。
恐らく、test.execを明記しないと、jacocoを実行しないために、JacocoTestReportが動いてくれないのかもしれません。

```groovy:point_in_build.gradle
jacoco {
  applyTo junitPlatformTest
}

junitPlatformTest {
  jacoco {
    destinationFile = file("${buildDir}/jacoco/test.exec")
  }
}
```

ですが、僕の体力が持たないので、これ以降の深追いは諦めます。



# 終わりに

もともとは、[TravisCIでGradleを使った自動ビルドをやってみた](https://qiita.com/Morichan/items/aa651d07fa8c8e0aad38)の続きの記事として書く予定でしたが、記事にしてみるとそこまで文量が多くなかったうえに問題点が1つだったため、タイトルと内容を変更しました。

codecovのエラー画面はシンプルすぎて、問題個所の把握に手間取りました。
実はその前にcoverallsで挑戦していたのですが、こちらのサイトは何一つ変化せず、測定結果の分析中なのかどうかすらわかりませんでした。

それでも、終わり良ければ総て良しです。

ここまで読んでくださって、ありがとうございます。
もしおかしい点、気づいた点がありましたら教えてください。
特に、build.gradleファイルは現在のプロジェクトのファイルとは異なっているため、誤字脱字があると思います。