// Copyright (C) 2024 Gradle, Inc.
//
// Licensed under the Creative Commons Attribution-Noncommercial-ShareAlike 4.0 International License.;
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://creativecommons.org/licenses/by-nc-sa/4.0/
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

[[jacoco_report_aggregation_plugin]]
= The JaCoCo Report Aggregation Plugin

The JaCoCo Report Aggregation plugin (plugin id: `jacoco-report-aggregation`) provides the ability to aggregate the results of multiple JaCoCo code coverage reports (potentially spanning multiple Gradle projects) into a single HTML report.  The binary data backing the coverage reports are produced by link:{groovyDslPath}/org.gradle.api.tasks.testing.Test.html[Test] task invocations; see more at the <<jacoco_plugin#jacoco_plugin,JaCoCo Plugin>> chapter.

[[sec:jacoco_report_aggregation_usage]]
== Usage

To use the JaCoCo Report Aggregation plugin, include the following in your build script:

====
[.multi-language-sample]
=====
[source,kotlin]
----
plugins {
    id("jacoco-report-aggregation")
}
----
=====
[.multi-language-sample]
=====
[source,groovy]
----
plugins {
    id 'jacoco-report-aggregation'
}
----
=====
====

Note that this plugin takes no action unless applied in concert with the <<jvm_test_suite_plugin#jvm_test_suite_plugin,JVM Test Suite Plugin>>.  The <<java_plugin#java_plugin, Java Plugin>> automatically applies the JVM Test Suite Plugin.

There are now two ways to collect code coverage results across multiple subprojects:

1. From the distribution's project, such as an application or WAR subproject -> link:../samples/sample_jvm_multi_project_with_code_coverage_distribution.html[distribution sample]
2. Using a standalone project to specify subprojects -> link:../samples/sample_jvm_multi_project_with_code_coverage_standalone.html[standalone sample]

Example 2 could also be used to aggregate results via the root project.

WARNING: The JaCoCo Report Aggregation plugin does not currently work with the ``com.android.application`` plugin.

[[sec:jacoco_report_aggregation_tasks]]
== Tasks

When the project also applies the `jvm-test-suite` plugin, the following tasks are added for each test suite:

`__testSuite__CodeCoverageReport` — link:{groovyDslPath}/org.gradle.testing.jacoco.tasks.JacocoReport.html[JacocoReport]::
_Depends on_: Artifacts of variants matching the below attributes
+
Collects variants of direct and transitive project dependencies via the `jacocoAggregation` configuration. The following Attributes will be matched:

[source,text]
----
    - org.gradle.category         = verification     // <1>
    - org.gradle.testsuite.name   = test             // <2>
    - org.gradle.verificationtype = jacoco-results   // <3>
----
<1> Category attribute; value is fixed.
<2> TestSuiteName attribute; value is derived from link:{javadocPath}/org/gradle/testing/base/TestSuite.html#getName--[TestSuite#getName()].
<3> VerificationType attribute; value is fixed.

More information about the variants produced by test execution with JaCoCo are available in the <<jacoco_plugin#sec:outgoing_variants,Outgoing Variants>> section of the JaCoCo Plugin documentation.

== Reports

[IMPORTANT]
====
By default, Gradle stops executing tasks when any task fails -- including test failures.
To ensure that your builds always generate aggregation reports, specify the `--continue` option in your Gradle command.
For more information, see <<command_line_interface.adoc#sec:continue_build_on_failure, continuing the build when a failure occurs>>.
====

=== Automatic report creation

When the project also applies the `jvm-test-suite` plugin, the following reporting objects are added for each test suite:

`__testSuite__CodeCoverageReport` — link:{javadocPath}/org/gradle/testing/jacoco/plugins/JacocoCoverageReport.html[JacocoCoverageReport]::
Creates an aggregate Jacoco report aggregating all test suites with a given link:{javadocPath}/org/gradle/api/attributes/TestSuiteName.html[name] across all project dependencies.

=== Manual report creation

When the project does not apply the `jvm-test-suite` plugin, you must manually register one or more reports:

====
include::sample[dir="samples/incubating/java/jvm-multi-project-with-code-coverage-standalone/kotlin/code-coverage-report",files="build.gradle.kts[tags=create_report]"]
include::sample[dir="samples/incubating/java/jvm-multi-project-with-code-coverage-standalone/groovy/code-coverage-report",files="build.gradle[tags=create_report]"]
====
<.> Creates a report named `testCodeCoverageReport` of type `JacocoCoverageReport`, aggregating all test suites from all project dependencies with a given link:{javadocPath}/org/gradle/testing/base/TestSuite.html#getName--[TestSuite#getName()].

Report creation automatically creates backing tasks to aggregate coverage results for the given test suite type value.

[[sec:dependency_management]]
== Dependency management

The JaCoCo Report Aggregation plugin adds the following dependency configurations:

[cols="a,a", options="header"]
|===
| Name
| Meaning

| `jacocoAggregation`
| The configuration used to declare all project dependencies having code coverage data to be aggregated.
| `aggregateCodeCoverageReportResults`
| Consumes the project dependencies from the `jacocoAggregation` configuration using <<variant_aware_resolution.adoc#sec:variant-aware-matching,variant-aware matching>> to find the appropriate test suite type.
|===

It is not necessary to explicitly add dependencies to the `jacocoAggregation` configuration if the project also applies the `jvm-test-suite` plugin.
