Kover - Gradle plugin for Kotlin code coverage agents: IntelliJ and JaCoCo.
Minimal supported Gradle
version: 6.4
.
- Collecting the code coverage for
JVM
test tasks XML
andHTML
reports generation- Support of
Kotlin/JVM
,Kotlin Multiplatform
and mixedKotlin-Java
sources with zero additional configuration Kotlin Android
support without dividing them into build types and flavours- Customizable filters for instrumented classes
In top level build file
Kotlin
plugins {
id("org.jetbrains.kotlinx.kover") version "0.4.3"
}
Groovy
plugins {
id 'org.jetbrains.kotlinx.kover' version '0.4.3'
}
In top level build file
Kotlin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.jetbrains.kotlinx:kover:0.4.3")
}
}
apply(plugin = "kover")
Groovy
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.jetbrains.kotlinx:kover:0.4.3'
}
}
apply plugin: 'kover'
To apply the plugin to all modules in the project, you need to apply the plugin only to the root module, as shown above.
There are no dependencies between tasks from different modules, they are executed independently.
Cross-module tests are not supported in reports and validation yet. For each test, only the classpath belonging to the current module is taken.
Once applied, the plugin can be used out of the box without additional configuration.
However, in some cases, custom settings are needed - this can be done by configuring special extensions and tasks.
If you need to disable or filter instrumentation for a some test task, you may configure the Kover extension for it.
For example, to configure a standard test task for Kotlin/JVM named test
, you need to add the following code to the build script of the module where this task is declared
Kotlin
tasks.test {
extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
isEnabled = true
binaryReportFile.set(file("$buildDir/custom/result.bin"))
includes = listOf("com\\.example\\..*")
excludes = listOf("com\\.example\\.subpackage\\..*")
}
}
Groovy
tasks.test {
kover {
enabled = true
binaryReportFile.set(file("$buildDir/custom/result.bin"))
includes = ['com\\.example\\..*']
excludes = ['com\\.example\\.subpackage\\..*']
}
}
For other platforms (Android, Kotlin-Multiplatform) the name may differ, you may also have several test tasks, so you first need to determine the name of the required task.
Example of configuring test task for build type debug
in Android:
Kotlin
android {
// other Android declarations
testOptions {
unitTests.all {
if (it.name == "testDebugUnitTest") {
extensions.configure(kotlinx.kover.api.KoverTaskExtension::class) {
isEnabled = true
binaryReportFile.set(file("$buildDir/custom/debug-report.bin"))
includes = listOf("com\\.example\\..*")
excludes = listOf("com\\.example\\.subpackage\\..*")
}
}
}
}
}
Groovy
android {
// other Android declarations
testOptions {
unitTests.all {
if (name == "testDebugUnitTest") {
kover {
enabled = true
binaryReportFile.set(file("$buildDir/custom/debug-report.bin"))
includes = ['com\\.example\\..*']
excludes = ['com\\.example\\.subpackage\\..*']
}
}
}
}
}
If you need to change the name of the XML report file or HTML directory, you may configure the corresponding tasks
Kotlin
tasks.koverHtmlReport {
isEnabled = true // false to disable report generation
htmlReportDir.set(layout.buildDirectory.dir("my-reports/html-result"))
}
tasks.koverXmlReport {
isEnabled = true // false to disable report generation
xmlReportFile.set(layout.buildDirectory.file("my-reports/result.xml"))
}
Groovy
tasks.koverHtmlReport {
enabled = true // false to disable report generation
htmlReportDir.set(layout.buildDirectory.dir("my-reports/html-result"))
}
tasks.koverXmlReport {
enabled = true // false to disable report generation
xmlReportFile.set(layout.buildDirectory.file("my-reports/result.xml"))
}
You may specify custom directory to collect reports from all modules in the build file of the root module:
Kotlin
tasks.koverCollectReports {
outputDir.set(layout.buildDirectory.dir("my-reports-dir") )
}
Groovy
tasks.koverCollectReports {
outputDir.set(layout.buildDirectory.dir("my-reports-dir") )
}
In the module in which the plugin is applied, you need to add code:
Kotlin
kover {
isEnabled = true // false to disable instrumentation of all test tasks in all modules
coverageEngine.set(kotlinx.kover.api.CoverageEngine.INTELLIJ) // change instrumentation agent and reporter
intellijEngineVersion.set("1.0.637") // change version of IntelliJ agent and reporter
jacocoEngineVersion.set("0.8.7") // change version of JaCoCo agent and reporter
generateReportOnCheck.set(true) // false to do not execute `koverReport` task before `check` task
}
Groovy
kover {
enabled = true // false to disable instrumentation of all test tasks in all modules
coverageEngine.set(kotlinx.kover.api.CoverageEngine.INTELLIJ) // change instrumentation agent and reporter
intellijEngineVersion.set('1.0.637') // change version of IntelliJ agent and reporter
jacocoEngineVersion.set('0.8.7') // change version of JaCoCo agent and reporter
generateReportOnCheck.set(true) // false to do not execute `koverReport` task before `check` task
}
For all test task of module, you can specify one or more rules that check the values of the code coverage counters.
Validation rules work for both types of agents.
The plugin currently only supports line counter values.
In the build file of the verified module:
Kotlin
tasks.koverVerify {
rule {
name = "The project has upper limit on lines covered"
bound {
maxValue = 100000
valueType = kotlinx.kover.api.VerificationValueType.COVERED_LINES_COUNT
}
}
rule {
// rule without a custom name
bound {
minValue = 1
maxValue = 1000
valueType = kotlinx.kover.api.VerificationValueType.MISSED_LINES_COUNT
}
}
rule {
name = "Minimal line coverage rate in percents"
bound {
minValue = 50
// valueType is kotlinx.kover.api.VerificationValueType.COVERED_LINES_PERCENTAGE by default
}
}
}
Groovy
tasks.koverVerify {
rule {
name = "The project doesn't has upper limit on lines covered"
bound {
maxValue = 100000
valueType = 'COVERED_LINES_COUNT'
}
}
rule {
// rule without a custom name
bound {
minValue = 1
maxValue = 1000
valueType = 'MISSED_LINES_COUNT'
}
}
rule {
name = "Minimal line coverage rate in percents"
bound {
minValue = 50
// valueType is 'COVERED_LINES_PERCENTAGE' by default
}
}
}
The plugin, when applied, automatically creates tasks for the module (all modules, if the project is multi-module, and it applied in root build script):
koverXmlReport
- Generates code coverage XML report for all module's test tasks.koverHtmlReport
- Generates code coverage HTML report for all module's test tasks.koverReport
- Executes bothkoverXmlReport
andkoverHtmlReport
tasks.koverCollectReports
- Collects reports from all submodules in one directory. Default directory is$buildDir/reports/kover/all
, names for XML reports and dirs for HTML are projects names. Executing this task does not runkoverXmlReport
orkoverHtmlReport
, it only copies previously created reports if they exist to the output directory.koverVerify
- Verifies code coverage metrics based on specified rules. Always executes beforecheck
task.
During the applying of the plugin, the artifacts of the JaCoCo or IntelliJ toolkit are dynamically loaded. They are downloaded from the mavenCentral
repository.
For the plugin to work correctly, you need to make sure that the mavenCentral
or its mirror is added to the list by the repository of the module in which the plugin is applied (usually this is the root module of the project) and add it if necessary.
Kotlin
repositories {
mavenCentral()
}
Groovy
repositories {
mavenCentral()
}