やること
GitHubのREADMEに以下のようなカバレッジ表示を出します。

プロジェクト構成
今回は自作のOSS、KRowMapperのリポジトリで作業をしました。
このプロジェクトは以下のような構成となっています
-
Kotlin JVMのGradleプロジェクト-
build.gradleはKotlin DSLで記述 - テストフレームワークは
JUnit5 - カバレッジ計測には
Jacocoを使用
-
-
CIはCircleCIで実行 - カバレッジの分析周りは
Codecovを利用
コードはGitHubに公開しています。
外部設定
まずプロジェクト外でカバレッジ計測の準備をします。
Codecovの設定
GitHub等のアカウントを利用してCodecovにログインし、計測対象にしたいリポジトリを選択します。


選ぶとtokenが生成されます(スクショを撮り忘れたので生成した時の表示の画像が有りません、申し訳ありません)。
このtokenは「Settings -> Repository Upload Token」から確認できます。
CircleCIの設定
次に、CircleCIで「PROJECT SETTINGS -> Environment Variables -> Add Variable」から環境変数を追加します。

NameはCODECOV_TOKENで、先ほど生成したCodecovのtokenを入力します。
この時tokenはダブルクォートで囲まずそのままで入力する必要が有ります(ダブルクォートで囲ってしまった場合カバレッジが上手く反映されません)。

Orb Security Settingsの設定
CircleCIでCodecovのOrbを利用する場合、Organization SettingsからOrb Security SettingsでYesを指定する必要が有ります。
この設定はOrganization等の単位で設定するため、これまでに何も触っていない場合は設定が必要です。
この設定無しで実行した場合、To use this orb, an organization admin must opt-in to using third party orbs in Organization Security settings.となって失敗します。
内部設定
続いてリポジトリ内での設定をします。
Jacocoによるレポートの出力設定
build.gradleにJacocoによるレポート出力を追記していきます。
まずpluginsにjacocoを追加します。
/* 略 */
plugins {
/* 略 */
id("jacoco")
}
/* 略 */
続いてtasksにjacocoTestReportを追加します。
この設定はこちらの記事を参考にしています。
/* 略 */
tasks {
/* 略 */
test {
useJUnitPlatform()
}
jacocoTestReport {
reports {
xml.isEnabled = true
csv.isEnabled = false
html.isEnabled = true
}
}
}
最後に、自分はテスト実行後に自動でカバレッジのレポートを生成する設定を行いました。
tasks {
/* 略 */
test {
useJUnitPlatform()
// テスト終了時にjacocoのレポートを生成する
finalizedBy(jacocoTestReport)
}
jacocoTestReport {
reports {
xml.isEnabled = true
csv.isEnabled = false
html.isEnabled = true
}
}
}
最終的にbuild.gradle.ktsは以下のようになりました(実際に利用している内容なため、今回の設定に対しては余計な内容が多く含まれています)。
`build.gradle.kts`
plugins {
id("maven")
id("java")
id("org.jetbrains.kotlin.jvm") version "1.3.72"
id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
id("jacoco")
}
group = "com.mapk"
version = "0.14"
java {
sourceCompatibility = JavaVersion.VERSION_1_8
}
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath(kotlin("gradle-plugin"))
}
}
repositories {
mavenCentral()
maven { setUrl("https://jitpack.io") }
}
dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation(kotlin("reflect"))
api("com.github.ProjectMapK:Shared:0.16")
// 使うのはRowMapperのみなため他はexclude、またバージョンそのものは使う相手に合わせるためcompileOnly
compileOnly(group = "org.springframework", name = "spring-jdbc", version = "5.2.4.RELEASE") {
exclude(module = "spring-beans")
exclude(module = "spring-jcl")
exclude(module = "spring-tx")
}
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter
testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.6.2") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
// https://mvnrepository.com/artifact/io.mockk/mockk
testImplementation("io.mockk:mockk:1.10.0")
// テスト時には無いと困るため、別口でimplementation
testImplementation(group = "org.springframework", name = "spring-jdbc", version = "5.2.4.RELEASE")
// https://mvnrepository.com/artifact/com.h2database/h2
testImplementation(group = "com.h2database", name = "h2", version = "1.4.200")
// 現状プロパティ名の変換はテストでしか使っていないのでtestImplementation
// https://mvnrepository.com/artifact/com.google.guava/guava
testImplementation(group = "com.google.guava", name = "guava", version = "28.2-jre")
}
tasks {
compileKotlin {
dependsOn("ktlintFormat")
kotlinOptions {
jvmTarget = "1.8"
allWarningsAsErrors = true
}
}
compileTestKotlin {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "1.8"
}
}
test {
useJUnitPlatform()
// テスト終了時にjacocoのレポートを生成する
finalizedBy(jacocoTestReport)
}
jacocoTestReport {
reports {
xml.isEnabled = true
csv.isEnabled = false
html.isEnabled = true
}
}
}
.circleci/config.ymlにCodecov関連を設定する
まずクイックスタートを参考にCodecovのOrbを追加します。
自分のプロジェクトではconfigのバージョンが2.0だったため、これを機に2.1に上げました。
version: 2.1
orbs:
codecov: codecov/codecov@1.0.5
# 略
続いて、CIの最後にCodecovにカバレッジ関連ファイルを上げる設定を追加します。
# 先ほど設定した部分
version: 2.1
orbs:
codecov: codecov/codecov@1.0.5
# 略
jobs:
build:
# 略
steps:
# 略
# run tests!
- run: gradle test
# ↓2行を追加
# upload coverages to codecov
- run: bash <(curl -s https://codecov.io/bash)
最終的に.circleci/config.ymlは以下のようになりました。
内容はほぼLanguage Guide: Javaのコピペです。
`.circleci/config.yml`
# Java Gradle CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-java/ for more details
#
version: 2.1
orbs:
codecov: codecov/codecov@1.0.5
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/openjdk:8-jdk
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4
working_directory: ~/repo
environment:
# Customize the JVM maximum heap limit
JVM_OPTS: -Xmx3200m
TERM: dumb
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "build.gradle.kts" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: gradle dependencies
- save_cache:
paths:
- ~/.gradle
key: v1-dependencies-{{ checksum "build.gradle.kts" }}
# run lints!
- run: gradle ktlintCheck
# run tests!
- run: gradle test
# upload coverages to codecov
- run: bash <(curl -s https://codecov.io/bash)
GitHubで動作を確認する
最後に、これまでの設定からGitHubでの動作を確認します。
Pull Requestを作成する
PRを出した際にCIを回す設定になっていれば、以下のようにCodecov Reportが届きます。
実際にCodecov Reportが届いているPRです。
READMEにバッジを貼る
Codecovの「Settings -> Badge」から各フォーマットでのバッジが確認できます。

これをREADMEに貼ることで、以下のようなカバレッジ表示を出せます。




