Skip to content

Teamscale Maven Plugin

The Teamscale Maven Plugin provides integration between Maven-based builds and Teamscale.

Overview

The plugin offers the following main features:

  1. Test Impact Analysis (TIA) – Automatically fetches and executes only impacted tests
  2. Testwise Coverage Recording – Records coverage data per test case
  3. Coverage Upload – Uploads Testwise Coverage or JaCoCo coverage reports to Teamscale

Goals

The plugin provides the following goals:

GoalDescriptionDefault Lifecycle Attachment
prepare-tia-unit-testInstruments Surefire unit tests to run impacted tests and collect Testwise CoverageINITIALIZE
prepare-tia-integration-testInstruments Failsafe integration tests to run impacted tests and collect Testwise CoveragePACKAGE
testwise-coverage-reportConverts binary data produced during the tests to testwise coverage reportsVERIFY
upload-coverageUploads JaCoCo and Testwise Coverage reports to TeamscaleVERIFY
helpDisplays help information for the plugin-

Usage

Add the plugin to your Maven POM file:

xml
<project>
   <properties>
      <teamscale.plugin.version>35.0.2</teamscale.plugin.version>
   </properties>
   <build>
      <pluginManagement>
         <plugins>
            <plugin>
               <groupId>com.teamscale</groupId>
               <artifactId>teamscale-maven-plugin</artifactId>
               <version>${teamscale.plugin.version}</version>
               <configuration>
                  <teamscaleUrl>https://company.teamscale.io</teamscaleUrl>
                  <projectId>myProject</projectId>
                  <username>build</username>
                  <accessToken>myAccessToken</accessToken>
                  <includes>
                     <include>*com.company.*</include>
                  </includes>
                  <!-- More options see below -->
               </configuration>
            </plugin>
         </plugins>
      </pluginManagement>
   </build>
</project>

Check here for the latest version.

Test Impact Analysis

To perform Test Impact Analysis and/or collect Testwise Coverage you need to:

  • Put the impacted-test-engine on the test classpath. This JUnit engine is responsible for querying Teamscale for impacted tests, makes sure to only run the returned subset of tests and informs the coverage profiler about when tests start and end.
  • Run the prepare-tia-unit-test and/or prepare-tia-integration-test goals to attach the coverage profiler to the test JVM.

Apply those settings to all modules that contain relevant tests:

xml

<project>
   <dependencies>
      <dependency>
         <groupId>com.teamscale</groupId>
         <artifactId>impacted-test-engine</artifactId>
         <version>${teamscale.plugin.version}</version>
         <scope>test</scope>
      </dependency>
   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupId>com.teamscale</groupId>
            <artifactId>teamscale-maven-plugin</artifactId>
            <executions>
               <execution>
                  <goals>
                     <goal>prepare-tia-unit-test</goal>
                     <goal>prepare-tia-integration-test</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
</project>

You might also want to only add this conditionally. By moving the configuration into a profile you can enable TIA by running the build with -Dtia

xml
<project>
   <profiles>
      <profile>

         <id>tia</id>
         <activation>
            <property>
               <name>tia</name>
            </property>
         </activation>

         <!-- Configuration from above -->
      </profile>
   </profiles>
</project>

The profiler produces binary data that needs to be converted into a proper report before it can be uploaded to Teamscale. The testwise-coverage-report goal is responsible for performing this conversion. The goal should only be run once, i.e., in your aggregator module (see below).

Limitations

  • JUnit 5: The plugin only supports tests based on the JUnit Platform and frameworks built on it (e.g., Serenity).
  • Surefire Version: TIA only supports Surefire versions >= 3.1.0
  • Parallel Tests: TIA does not support parallelized tests. Ensure Surefire and Failsafe use:
xml
<forkCount>1</forkCount>
<threadCount>1</threadCount>
  • Custom Test Execution: If your system-under-test is launched by means other than Surefire or Failsafe, ensure the argLine property is passed to that JVM. You can also use another property by specifying it via the propertyName configuration.

Upload to Teamscale

The upload to Teamscale should typically only happen once for the whole build. To achieve this with Maven, you need an aggregator module that has a dependency (directly or indirectly) on all modules of your project. If you intend to collect Testwise Coverage, apply the plugin with the testwise-coverage-report goal in your aggregator module. If you intend to upload JaCoCo coverage, make sure to configure the JaCoCo Maven Plugin in the modules to generate XML reports.

xml
<project>
   <build>
      <plugins>
         <plugin>
            <groupId>com.teamscale</groupId>
            <artifactId>teamscale-maven-plugin</artifactId>
            <executions>
               <execution>
                  <goals>
                     <!-- Only needed if you collect Testwise Coverage -->
                     <goal>testwise-coverage-report</goal>
                     
                     <goal>upload-coverage</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
</project>

Common Configuration Parameters

Some parameters can also be set via system properties on the command line (e.g., -Dteamscale.username=build). Parameters without a system property can only be configured via XML.

Authentication and Connection

ParameterSystem PropertyDescriptionRequired
teamscaleUrl-URL of your Teamscale instanceYes
projectId-ID of your Teamscale projectYes
usernameteamscale.usernameUsername for Teamscale authenticationYes
accessTokenteamscale.accessTokenAccess token for Teamscale authenticationYes

Commit and Revision Specification

Teamscale needs to know which code commit the coverage belongs to. 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 manually specify a commit using the parameters below.

ParameterSystem PropertyDescriptionDefault
revisionteamscale.revisionGit commit hash (SHA1) to upload coverage toAuto-detected from CI or Git
repositoryteamscale.repositoryConnector ID in Teamscale to look up the revision. If not set, Teamscale searches all connectors configured in the project.Not set (searches all)
committeamscale.commitAlternative: branch and timestamp in format BRANCH:UNIX_EPOCH_TIMESTAMP_IN_MILLISECONDS (e.g., main:1675123456789)Not used when revision is set

Precedence rules

  1. If revision is set, it takes precedence over commit
  2. If only commit is set, it is used
  3. If neither is set, the plugin auto-detects from CI environment variables or Git HEAD

If both are set, a warning is logged and revision is used.

When to use commit vs. revision

  • revision (preferred): Use when you have a Git commit hash (standard for CI/CD pipelines)
  • commit: Use when you need to specify a point in time on a branch (timestamp in Unix epoch milliseconds)

Code Coverage Control

The following patterns use wildcard syntax (not Ant patterns):

  • * matches any number of any characters (including slash, dot, etc.)
  • ? matches exactly one character

Patterns are matched against fully qualified class names (e.g., com.example.MyClass).

ParameterSystem PropertyDescriptionDefault
includes-Patterns for classes to include in coverage instrumentation*
excludes-Patterns for classes to exclude from coverage instrumentationSome packages that are often included during testing, e.g., junit, assertj, mockito,...

Example:

xml
<includes>
   <include>*com.company.*</include>
</includes>
<excludes>
   <exclude>*com.company.generated.*</exclude>
</excludes>

TIP

Prefix patterns with * (e.g., *com.company.*) to handle nested JAR structures.

Two types of include/exclude patterns

The plugin has two separate sets of includes/excludes parameters:

  1. Coverage Instrumentation (common configuration, used by prepare-tia-* goals):

    • Applied at runtime during test execution
    • Controls which classes are instrumented by the Java profiler
  2. Report Generation (testwise-coverage-report goal):

    • Applied during post-processing when generating the report
    • Controls which compiled .class files are analyzed
    • Defaults to * (all classes)

In most cases, configure only the coverage instrumentation patterns in a common configuration.

Test Execution Control

ParameterSystem PropertyDescriptionDefault
runImpactedrunImpactedWhether to execute only impacted teststrue
runAllTestsrunAllTestsWhether to execute all tests regardless of impactfalse
skip-Whether to skip the execution of the goalfalse

Goal-Specific Parameters

TIA Configuration (prepare-tia-unit-test and prepare-tia-integration-test)

ParameterSystem PropertyDescriptionDefault
unitTestPartitionteamscale.unitTestPartitionPartition name for unit test reports (prepare-tia-unit-test only)"Unit Tests"
integrationTestPartitionteamscale.integrationTestPartitionPartition name for integration test reports (prepare-tia-integration-test only)"Integration Tests"
propertyName-Property name for JVM argumentsargLine/spring-boot.run.jvmArguments/tycho.testArgLine
additionalAgentOptions-Additional options for the Teamscale Java ProfilerNone
agentPort-Port for Java agent communicationAuto-selected
debugLoggingdebugLoggingEnable DEBUG level logging for the Java profiler and impacted test enginefalse
baselineCommit-Baseline for impact analysisNone
baselineRevision-VCS revision for baselineNone

Testwise Coverage Report (testwise-coverage-report)

This goal converts binary coverage data into a testwise coverage report. The includes and excludes parameters control which compiled class files are analyzed.

ParameterSystem PropertyDescriptionDefault
includes-Wildcard patterns for class files to include during report generation*
excludes-Wildcard patterns for class files to exclude during report generationNone
splitAfter-Number of tests after which to split coverage into multiple reports5000

Coverage Upload (upload-coverage)

ParameterSystem PropertyDescriptionDefault
unitTestPartitionteamscale.unitTestPartitionPartition name for unit test reports"Unit Tests"
integrationTestPartitionteamscale.integrationTestPartitionPartition name for integration test reports"Integration Tests"
aggregatedTestPartitionteamscale.aggregatedTestPartitionPartition name for aggregated test reports"Aggregated Tests"

Troubleshooting

The plugin creates log files in the target/tia/ directory to help diagnose issues:

  • agent.log – Logs from the Java profiler
  • engine.log – Logs from the impacted test engine

You can enable debug logging by adding the debugLogging configuration property or via the command line with -DdebugLogging=true:

xml
<plugins>
	<plugin>
		<groupId>com.teamscale</groupId>
		<artifactId>teamscale-maven-plugin</artifactId>
		<version>${teamscale.plugin.version}</version>
		<configuration>
			<debugLogging>true</debugLogging>
			<!-- More options -->
		</configuration>
	</plugin>
</plugins>

If the log files are not created when executing your tests, check if you have <argLine>...</argLine> in your pom.xml and remove it. This overwrites the arguments we set in the plugin and thus de-registers the coverage profiler.

In some cases, the test reports generated by Surefire/Failsafe may also contain error information. You can find them under target/surefire-reports after all tests have finished. Check the stdout/stderr of failing tests for additional error messages.

If the build fails after applying the above POM changes but works without them, try to re-run the build with -e to discover the error that caused this.

If you notice largely increased test runtimes on systems that set <reuseForks>true</reuseForks> it is recommended to set the tiaMode to exec-file:

xml
<plugins>
	<plugin>
		<groupId>com.teamscale</groupId>
		<artifactId>teamscale-maven-plugin</artifactId>
		<version>${teamscale.plugin.version}</version>
		<configuration>
			<tiaMode>exec-file</tiaMode>
			<!-- More options -->
		</configuration>
	</plugin>
</plugins>

Writing a testwise coverage report every time the JVM closes can be time-consuming, so writing raw .exec files instead, has been shown to increase test execution times. Have a look at the testwise-coverage-report goal for more information. You can use the upload-coverage goal to then upload the created testwise coverage report to Teamscale.