Teamscale Gradle Plugin
The Teamscale Gradle Plugin enables seamless integration between your Gradle builds and Teamscale, allowing you to upload test reports, coverage data, and leverage Test Impact Analysis (TIA) capabilities. The plugin also provides utilities for aggregating and compacting reports to reduce their storage footprint.
Applying the Plugin
Add the Teamscale plugin to your build script (latest version):
plugins {
id "com.teamscale" version "35.0.0"
}
Configuring the teamscale
Extension
The teamscale
extension configures the connection to Teamscale.
Server Configuration
teamscale {
server {
url = 'https://mycompany.teamscale.io/'
project = 'my-project'
userName = 'build'
userAccessToken = property('teamscale.access-token')
}
}
Optional Configuration Options
By default, the plugin tries to detect the commit from CI environment variables (supported environment variables) or the local Git repository.
If needed, you can, however, manually specify a commit by using either a revision or branch and timestamp. The following options exist on the teamscale
extension in addition to server
(see above):
Property | Type | Description |
---|---|---|
commit.revision | Property<String> | The current commit revision (e.g., Git SHA1 hash or SVN revision). |
commit.branchName | Property<String> | The branch name in Teamscale of current code. Prefer commit.revision if possible. |
commit.timestamp | Property<Any> | The timestamp of the commit in Teamscale of current code. Prefer commit.revision if possible. |
baseline.timestamp | Property<Any> | The numerical timestamp of the baseline commit (as obtained from the VCS history). Used to calculate impacted tests. |
baseline.revision | Property<String> | Allows setting the baseline using a VCS revision (e.g., a Git SHA1) instead of a timestamp. Used to calculate impacted tests. |
repository | Property<String> | Specifies the repository in which the commit.revision and baseline.revision should be resolved. Useful when multiple repositories exist in a Teamscale project. |
Report Aggregation for Multi-Project Builds
For projects with multiple subprojects, we recommend to aggregate reports before uploading them. The plugin works similarly to Gradle's JaCoCo Report Aggregation Plugin and Test Report Aggregation Plugin. Please refer to the Gradle documentation for more details on the concepts behind the aggregation mechanism.
The com.teamscale.aggregation
plguin should be applied to the aggregation project:
plugins {
id 'com.teamscale.aggregation'
}
The plugin adds the reportAggregation
configuration. There are two typical scenarios:
- The aggregation project is a JVM project itself – i.e., the aggregation happens in the project that also applies the
application
plugin. In this case thereportAggregation
configuration will automatically depend on all transitive projects and hence aggregate their reports. - The aggregation project is a standalone project – i.e., the project contains no code and has no dependencies to other projects declared. This is usually the case if aggregation happens via the root project or a dedicated subproject that just exists for the purpose to aggregate data. In this case you have to ensure that the projects that you want to aggregate are added as dependencies to the
reportAggregation
configuration.
plugins {
id 'com.teamscale.aggregation'
}
dependencies {
reportAggregation(project(":lib:lib1"))
reportAggregation(project(":lib:lib2"))
}
The plugin adds support for the following aggregate report types:
AggregateCompactCoverageReport
AggregateJUnitReport
AggregateTestwiseCoverageReport
The tasks created for those reports have a dependency on the corresponding test tasks of the projects that produce the coverage and execution data.
With JVM Test Suites
When using the JVM Test Suite Plugin, aggregate reports and their tasks are automatically created for each test suite:
testSuiteAggregateCompactCoverageReport
–CompactCoverageReport
that contains the coverage of all aggregated projects.testSuiteAggregateJUnitReport
–JUnitReportCollectionTask
that collects all the JUnit reports from all aggregated projects.testSuiteAggregateTestwiseCoverageReport
–TestwiseCoverageReport
that collects all the binary testwise coverage data from all aggregated projects.
plugins {
id 'com.teamscale.aggregation'
}
tasks.register("teamscaleIntegrationTestReportUpload", TeamscaleUpload) {
partition = "Integration Tests"
from(tasks.integrationTestAggregateCompactCoverageReport)
from(tasks.integrationTestAggregateJUnitReport)
}
Without JVM Test Suites
If your aggregation project does not use JVM test suites, we can still use the aggregation mechanism. You can associate a Test
task with an arbitrary test suite name. For this purpose we provide the TestSuiteCompatibilityUtil.exposeTestForAggregation(testTask, suiteName)
. Call this for each task in each subproject that you want to take part in aggregation.
import com.teamscale.aggregation.TestSuiteCompatibilityUtil
tasks.register('unitTest', Test) {
// ...
}
tasks.register('systemTest', Test) {
teamscale {
collectTestwiseCoverage = true
}
}
TestSuiteCompatibilityUtil.exposeTestForAggregation(tasks.named('unitTest'), 'myUnitTestSuite')
TestSuiteCompatibilityUtil.exposeTestForAggregation(tasks.named('systemTest'), 'mySystemTestSuite')
In the aggregation project, create an aggregation report:
import com.teamscale.aggregation.compact.AggregateCompactCoverageReport
import com.teamscale.aggregation.junit.AggregateJUnitReport
import com.teamscale.aggregation.testwise.AggregateTestwiseCoverageReport
plugins {
id 'com.teamscale.aggregation'
}
reporting {
reports {
unitTestAggregateCompactCoverageReport(AggregateCompactCoverageReport) {
testSuiteName = 'myUnitTestSuite'
}
unitTestAggregateJUnitReport(AggregateJUnitReport) {
testSuiteName = 'myUnitTestSuite'
}
systemTestAggregateTestwiseCoverageReport(AggregateTestwiseCoverageReport) {
testSuiteName = 'mySystemTestSuite'
}
}
}
tasks.register("teamscaleUnitTestReportUpload", TeamscaleUpload) {
partition = "Unit Tests"
from(tasks.named('unitTestAggregateCompactCoverageReport'))
from(tasks.named('unitTestAggregateJUnitReport'))
}
tasks.register("teamscaleSystemTestReportUpload", TeamscaleUpload) {
partition = "System Tests"
from(tasks.named('systemTestAggregateTestwiseCoverageReport'))
}
TeamscaleUpload Task
The TeamscaleUpload
task uploads reports to Teamscale.
import com.teamscale.TeamscaleUpload
tasks.register('teamscaleTestUpload', TeamscaleUpload) {
partition = "Unit Tests"
from(tasks.test)
from(tasks.jacocoTestReport)
}
Properties & Methods
Property | Type | Description |
---|---|---|
partition | Property<String> | The partition to upload the report to (required) |
message | Property<String> | Optional message to attach to the upload |
ignoreFailures | Property<Boolean> | Whether the task should fail when the upload failed (default false ) |
from(task: Task/TaskProvider) | Adds the reports produced by the given task to the upload. Supported task types are
| |
addReport(format: String, reports: Any) | Adds additional report files in the given format to be uploaded |
CompactCoverageReport
Task
This task is an alternative to JaCoCoReport
, that produces Compact Coverage instead of a JaCoCo XML report. Compact Coverage is way smaller than JaCoCo and can be processed more efficiently by Teamscale.
tasks.register("compactCoverageReport", CompactCoverageReport) {
executionData(tasks.test)
sourceSets(sourceSets.main)
}
Properties & Methods
Property | Type | Description |
---|---|---|
executionData | ConfigurableFileCollection | The JaCoCo execution data files (e.g., *.exec files) to process. |
executionData(vararg tasks: Task) | Adds execution data generated by tasks with a JacocoTaskExtension for coverage analysis. Tasks without this extension are ignored. | |
executionData(vararg files: Any) | Adds one or more execution data files for coverage analysis. | |
classDirectories | ConfigurableFileCollection | The directories containing compiled classes to include in the coverage report. |
sourceSets(vararg sourceSets: SourceSet) | Adds one or more source sets (class outputs) to be included in the report. | |
reports.compactCoverage.required | Property<Boolean> | Enable/disable generating the report. |
reports.compactCoverage.outputLocation | RegularFileProperty | Destination of the generated report. |
TestwiseCoverageReport
Task
This task generates a Testwise Coverage report from the binary data produced by the Test
task. The required binary data is produced when teamscale.collectTestwiseCoverage
is enabled for the test. Testwise Coverage reports are required to perform Test Impact Analysis.
tasks.register("testwiseCoverageReport", TestwiseCoverageReport) {
executionData(tasks.test)
}
Properties & Methods
Property | Type | Description |
---|---|---|
executionData | ConfigurableFileCollection | The binary data produced by the Test task to be converted. |
executionData(vararg tasks: Task) | Sets the execution data, classDirectories and partial flag based on the given test task. Only tasks of type Test will be accepted. | |
classDirectories | ConfigurableFileCollection | The directories containing compiled classes to include in the coverage report. |
sourceSets(vararg sourceSets: SourceSet) | Adds one or more source sets (class outputs) to be included in the report. | |
partial | Property<Boolean> | Indicates whether the tests were only partially executed. This is typically set via executionData(task) . |
reports.testwiseCoverage.required | Property<Boolean> | Enable/disable generating the report. |
reports.testwiseCoverage.outputLocation | RegularFileProperty | Destination of the generated testwise coverage report. |
Test
Extension (TeamscaleTaskExtension
)
Test Impact Analysis can be configured directly on Test
tasks using the teamscale
extension.
tasks.register('unitTest', Test) {
teamscale {
collectTestwiseCoverage = true
runImpacted = true
includeAddedTests = true
includeFailedAndSkipped = true
partition = "Unit Tests"
}
}
Properties
Property | Type | Default | Description |
---|---|---|---|
collectTestwiseCoverage | Property<Boolean> | false | Enables testwise coverage collection |
runImpacted | Property<Boolean> | false | Runs only tests impacted by changes |
runAllTests | Property<Boolean> | false | Forces running all tests even when impacted mode is enabled |
includeAddedTests | Property<Boolean> | true | Includes newly added tests when running in impacted mode |
includeFailedAndSkipped | Property<Boolean> | true | Includes previously failed or skipped tests in impacted mode |
partition | Property<String> | null | The partition name for the test data |