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.12"
    reportsDirectory = layout.buildDirectory.dir("customJacocoReportDir")
}
build.gradle
jacoco {
    toolVersion = "0.8.12"
    reportsDirectory = layout.buildDirectory.dir('customJacocoReportDir')
}
表 1. JaCoCo 屬性的 Gradle 預設值
屬性 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
    }
}

雖然當 java 外掛程式已套用時,類型為 Test 的所有任務都會自動增強以提供涵蓋率資訊,但任何實作 JavaForkOptions 的任務都可以由 JaCoCo 外掛程式增強。 也就是說,任何分支 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)
--------------------------------------------------
Binary results containing Jacoco test coverage for all targets in the 'test' Test Suite.

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

Artifacts
    - build/jacoco/test.exec (artifactType = binary)
1 TestSuiteName 屬性; 值衍生自 TestSuite#getName()