Skip to content

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):

groovy
plugins {
	id "com.teamscale" version "35.0.0"
}

Configuring the teamscale Extension

The teamscale extension configures the connection to Teamscale.

Server Configuration

groovy
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):

PropertyTypeDescription
commit.revisionProperty<String>The current commit revision (e.g., Git SHA1 hash or SVN revision).
commit.branchNameProperty<String>The branch name in Teamscale of current code. Prefer commit.revision if possible.
commit.timestampProperty<Any>The timestamp of the commit in Teamscale of current code. Prefer commit.revision if possible.
baseline.timestampProperty<Any>The numerical timestamp of the baseline commit (as obtained from the VCS history). Used to calculate impacted tests.
baseline.revisionProperty<String>Allows setting the baseline using a VCS revision (e.g., a Git SHA1) instead of a timestamp. Used to calculate impacted tests.
repositoryProperty<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:

groovy
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 the reportAggregation 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.
groovy
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:

  • testSuiteAggregateCompactCoverageReportCompactCoverageReport that contains the coverage of all aggregated projects.
  • testSuiteAggregateJUnitReportJUnitReportCollectionTask that collects all the JUnit reports from all aggregated projects.
  • testSuiteAggregateTestwiseCoverageReportTestwiseCoverageReport that collects all the binary testwise coverage data from all aggregated projects.
groovy
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.

groovy
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:

groovy
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.

groovy
import com.teamscale.TeamscaleUpload

tasks.register('teamscaleTestUpload', TeamscaleUpload) {
	partition = "Unit Tests"
	from(tasks.test)
	from(tasks.jacocoTestReport)
}

Properties & Methods

PropertyTypeDescription
partitionProperty<String>The partition to upload the report to (required)
messageProperty<String>Optional message to attach to the upload
ignoreFailuresProperty<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
  • Test (JUNIT)
  • JaCoCoReport (JACOCO)
  • CompactCoverageReport (TEAMSCALE_COMPACT_COVERAGE)
  • TestwiseCoverageReport (TESTWISE_COVERAGE)
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.

groovy
tasks.register("compactCoverageReport", CompactCoverageReport) {
    executionData(tasks.test)
    sourceSets(sourceSets.main)
}

Properties & Methods

PropertyTypeDescription
executionDataConfigurableFileCollectionThe 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.
classDirectoriesConfigurableFileCollectionThe 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.requiredProperty<Boolean>Enable/disable generating the report.
reports.compactCoverage.outputLocationRegularFilePropertyDestination 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.

groovy
tasks.register("testwiseCoverageReport", TestwiseCoverageReport) {
    executionData(tasks.test)
}

Properties & Methods

PropertyTypeDescription
executionDataConfigurableFileCollectionThe 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.
classDirectoriesConfigurableFileCollectionThe 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.
partialProperty<Boolean>Indicates whether the tests were only partially executed. This is typically set via executionData(task).
reports.testwiseCoverage.requiredProperty<Boolean>Enable/disable generating the report.
reports.testwiseCoverage.outputLocationRegularFilePropertyDestination of the generated testwise coverage report.

Test Extension (TeamscaleTaskExtension)

Test Impact Analysis can be configured directly on Test tasks using the teamscale extension.

groovy
tasks.register('unitTest', Test) {
	teamscale {
		collectTestwiseCoverage = true
		runImpacted = true
		includeAddedTests = true
		includeFailedAndSkipped = true
		partition = "Unit Tests"
	}
}

Properties

PropertyTypeDefaultDescription
collectTestwiseCoverageProperty<Boolean>falseEnables testwise coverage collection
runImpactedProperty<Boolean>falseRuns only tests impacted by changes
runAllTestsProperty<Boolean>falseForces running all tests even when impacted mode is enabled
includeAddedTestsProperty<Boolean>trueIncludes newly added tests when running in impacted mode
includeFailedAndSkippedProperty<Boolean>trueIncludes previously failed or skipped tests in impacted mode
partitionProperty<String>nullThe partition name for the test data