JaCoCo 外掛程式透過與 JaCoCo 整合,提供 Java 程式碼的程式碼涵蓋率指標。

入門

若要開始,請將 JaCoCo 外掛程式套用至您要計算程式碼涵蓋率的專案。

build.gradle.kts
plugins {
    jacoco
}
build.gradle
plugins {
    id 'jacoco'
}

如果 Java 外掛程式也套用至您的專案,將會建立名為 jacocoTestReport 的新工作。預設情況下,HTML 報告會產生於 layout.buildDirectory.dir("reports/jacoco/test")

雖然測試應在產生報告之前執行,但 jacocoTestReport 工作並未依賴 test 工作。

根據您的使用案例,您可能希望總是產生 jacocoTestReport 或在產生報告之前明確執行 test 工作。

build.gradle.kts
tasks.test {
    finalizedBy(tasks.jacocoTestReport) // report is always generated after tests run
}
tasks.jacocoTestReport {
    dependsOn(tasks.test) // tests are required to run before generating the report
}
build.gradle
test {
    finalizedBy jacocoTestReport // report is always generated after tests run
}
jacocoTestReport {
    dependsOn test // tests are required to run before generating the report
}

設定 JaCoCo 外掛程式

JaCoCo 外掛程式會新增一個名為 jacoco 的專案延伸模組,類型為 JacocoPluginExtension,可讓您設定組建中 JaCoCo 使用的預設值。

build.gradle.kts
jacoco {
    toolVersion = "0.8.11"
    reportsDirectory = layout.buildDirectory.dir("customJacocoReportDir")
}
build.gradle
jacoco {
    toolVersion = "0.8.11"
    reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
表格 1. Gradle 預設的 JaCoCo 屬性
屬性 Gradle 預設值

reportsDirectory

layout.buildDirectory.dir("reports/jacoco")

JaCoCo 報告設定

JacocoReport 任務可用於產生不同格式的程式碼涵蓋率報告。它實作標準 Gradle 類型 Reporting,並公開類型為 JacocoReportsContainer 的報告容器。

build.gradle.kts
tasks.jacocoTestReport {
    reports {
        xml.required = false
        csv.required = false
        html.outputLocation = layout.buildDirectory.dir("jacocoHtml")
    }
}
build.gradle
jacocoTestReport {
    reports {
        xml.required = false
        csv.required = false
        html.outputLocation = layout.buildDirectory.dir('jacocoHtml')
    }
}
JaCoCo HTML report

強制執行程式碼涵蓋率指標

此功能需要使用 JaCoCo 0.6.3 或更高版本。

JacocoCoverageVerification 任務可用於驗證是否根據設定的規則達到程式碼涵蓋率指標。其 API 公開方法 JacocoCoverageVerification.violationRules(org.gradle.api.Action),用作設定規則的主要入口點。呼叫其中任何一個方法都會傳回 JacocoViolationRulesContainer 的執行個體,提供廣泛的設定選項。如果任何設定的規則未符合,組建就會失敗。JaCoCo 只會報告第一個違規的規則。

程式碼涵蓋率需求可以針對整個專案、個別檔案,以及特定 JaCoCo 類型的涵蓋率指定,例如涵蓋的行或涵蓋的分支。下列範例說明語法。

build.gradle.kts
tasks.jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = "0.5".toBigDecimal()
            }
        }

        rule {
            isEnabled = false
            element = "CLASS"
            includes = listOf("org.gradle.*")

            limit {
                counter = "LINE"
                value = "TOTALCOUNT"
                maximum = "0.3".toBigDecimal()
            }
        }
    }
}
build.gradle
jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.5
            }
        }

        rule {
            enabled = false
            element = 'CLASS'
            includes = ['org.gradle.*']

            limit {
                counter = 'LINE'
                value = 'TOTALCOUNT'
                maximum = 0.3
            }
        }
    }
}

JacocoCoverageVerification 任務並非 Java 外掛程式提供的 check 任務的任務相依性。這是有充分理由的。目前此任務並非增量式,因為它未宣告任何輸出。任何宣告規則的違規都會在執行 check 任務時自動導致組建失敗。這種行為可能並非所有使用者都希望看到的。Gradle 的未來版本可能會變更此行為。

JaCoCo 特定任務組態

JaCoCo 外掛會新增一個 JacocoTaskExtension 外掛到所有 Test 類型的任務。這個外掛允許組態測試任務的 JaCoCo 特定屬性。

build.gradle.kts
tasks.test {
    extensions.configure(JacocoTaskExtension::class) {
        destinationFile = layout.buildDirectory.file("jacoco/jacocoTest.exec").get().asFile
        classDumpDir = layout.buildDirectory.dir("jacoco/classpathdumps").get().asFile
    }
}
build.gradle
test {
    jacoco {
        destinationFile = layout.buildDirectory.file('jacoco/jacocoTest.exec').get().asFile
        classDumpDir = layout.buildDirectory.dir('jacoco/classpathdumps').get().asFile
    }
}

組態為使用 JaCoCo 代理程式執行的任務會在任務開始執行時刪除執行資料的目的地檔案。這可確保執行資料中沒有過時的涵蓋率資料。

JaCoCo 任務外掛的預設值

build.gradle.kts
tasks.test {
    configure<JacocoTaskExtension> {
        isEnabled = true
        destinationFile = layout.buildDirectory.file("jacoco/${name}.exec").get().asFile
        includes = emptyList()
        excludes = emptyList()
        excludeClassLoaders = emptyList()
        isIncludeNoLocationClasses = false
        sessionId = "<auto-generated value>"
        isDumpOnExit = true
        classDumpDir = null
        output = JacocoTaskExtension.Output.FILE
        address = "localhost"
        port = 6300
        isJmx = false
    }
}
build.gradle
test {
    jacoco {
        enabled = true
        destinationFile = layout.buildDirectory.file("jacoco/${name}.exec").get().asFile
        includes = []
        excludes = []
        excludeClassLoaders = []
        includeNoLocationClasses = false
        sessionId = "<auto-generated value>"
        dumpOnExit = true
        classDumpDir = null
        output = JacocoTaskExtension.Output.FILE
        address = "localhost"
        port = 6300
        jmx = false
    }
}

雖然所有 Test 類型的任務都會自動增強為在套用 java 外掛時提供涵蓋率資訊,但 JaCoCo 外掛可以增強任何實作 JavaForkOptions 的任務。也就是說,任何分岔 Java 程序的任務都可以用來產生涵蓋率資訊。

例如,您可以組態您的建置以使用 application 外掛來產生程式碼涵蓋率。

build.gradle.kts
plugins {
    application
    jacoco
}

application {
    mainClass = "org.gradle.MyMain"
}

jacoco {
    applyTo(tasks.run.get())
}

tasks.register<JacocoReport>("applicationCodeCoverageReport") {
    executionData(tasks.run.get())
    sourceSets(sourceSets.main.get())
}
build.gradle
plugins {
    id 'application'
    id 'jacoco'
}

application {
    mainClass = 'org.gradle.MyMain'
}

jacoco {
    applyTo run
}

tasks.register('applicationCodeCoverageReport', JacocoReport) {
    executionData run
    sourceSets sourceSets.main
}
applicationCodeCoverageReport 產生的涵蓋率報告
.
└── build
    ├── jacoco
    │   └── run.exec
    └── reports
        └── jacoco
            └── applicationCodeCoverageReport
                └── html
                    └── index.html

任務

對於也套用 Java 外掛的專案,JaCoCo 外掛會自動新增下列任務

jacocoTestReportJacocoReport

為測試任務產生程式碼涵蓋率報告。

jacocoTestCoverageVerificationJacocoCoverageVerification

根據指定規則驗證測試任務的程式碼涵蓋率指標。

相依性管理

JaCoCo 外掛會新增下列相依性組態

表 2. JaCoCo 外掛 - 相依性組態
名稱 意義

jacocoAnt

用於執行 JacocoReportJacocoCoverageVerification 任務的 JaCoCo Ant 函式庫。

jacocoAgent

用於測試程式碼的 JaCoCo 代理程式庫。

傳出變異

當產生 JaCoCo 涵蓋率資料的專案與 JVM 測試套件外掛程式 一起套用時,將會產生其他傳出變異。這些變異是設計給 JaCoCo 報告聚合外掛程式 使用的。

屬性會類似以下。使用者可設定的屬性會在範例下方標示。

傳出變異工作輸出
--------------------------------------------------
Variant coverageDataElementsForTest (i)
--------------------------------------------------
Description = Binary data file containing results of Jacoco test coverage reporting for the test Test Suite's test target.

Capabilities
    - org.gradle.sample:application:1.0.2 (default capability)
Attributes
    - org.gradle.category              = verification
    - org.gradle.testsuite.name        = test           (1)
    - org.gradle.testsuite.target.name = test           (2)
    - org.gradle.testsuite.type        = unit-test      (3)
    - org.gradle.verificationtype      = jacoco-coverage

Artifacts
    - build/jacoco/test.exec (artifactType = binary)
1 TestSuiteName 屬性;值來自 JvmTestSuite#getName()
2 TestSuiteTargetName 屬性;值來自 JvmTestSuiteTarget#getName()
3 TestSuiteType 屬性;值來自 JvmTestSuite#getTestType()