Scan is not picking up any Spring Cloud Contract tests

I’m building a Java Spring Boot web service with Maven in GitHub and using GitHub actions to run a SonarQube scan against my code on checkin. I have the following properties set up in the sonar-project.properites file.

# Configuration
sonar.projectKey=<my project key>
sonar.language=java
# Sources
sonar.sources=src/main
sonar.java.binaries=target/classes
sonar.java.libraries=target
# Test Coverage
sonar.tests=src/test
sonar.java.test.binaries=target/test-classes
sonar.java.coveragePlugin=jacoco
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

I’m using the Jacoco plugin and it’s reporting test coverage for standard junit tests fine, but it’s not picking up any of my Spring Cloud Contract tests.

Here is a sub set of my pom.xml

  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.5</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>

  <properties>
    <java.version>11</java.version>
    <spring-cloud.version>2020.0.4</spring-cloud.version>
    <tinylog-version>2.2.1</tinylog-version>
    <springfox-version>2.9.2</springfox-version>
  </properties>

  <dependencies>
    <!--Spring boot starter dependencies-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

    <!--Database dependencies-->

    <!--Swagger codegen and UI dependencies-->
    <dependency>
      <groupId>io.swagger.core.v3</groupId>
      <artifactId>swagger-annotations</artifactId>
      <version>2.1.7</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger2</artifactId>
      <version>${springfox-version}</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-swagger-ui</artifactId>
      <version>${springfox-version}</version>
    </dependency>

    <!--Logging dependencies-->
    <dependency>
      <groupId>org.tinylog</groupId>
      <artifactId>tinylog-api</artifactId>
      <version>${tinylog-version}</version>
    </dependency>
    <dependency>
      <groupId>org.tinylog</groupId>
      <artifactId>tinylog-impl</artifactId>
      <version>${tinylog-version}</version>
    </dependency>

    <!--Apache dependencies-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.12.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-collections4</artifactId>
      <version>4.4</version>
    </dependency>

    <!--Misc dependencies-->

    <!--Testing dependencies-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-contract-verifier</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-core</artifactId>
      <version>4.0.0</version>
    </dependency>
  </dependencies>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>io.swagger.codegen.v3</groupId>
        <artifactId>swagger-codegen-maven-plugin</artifactId>
        <version>3.0.25</version>
        <executions>
          <execution>
            <goals>
              <goal>generate</goal>
            </goals>
            <configuration>
              <inputSpec>${project.basedir}/src/main/resources/api.yml</inputSpec>
              <language>spring</language>
              <configOptions>
                <sourceFolder>swagger</sourceFolder>
                <java8>true</java8>
                <interfaceOnly>true</interfaceOnly>
                <dateLibrary>java8-localdatetime</dateLibrary>
              </configOptions>
            </configuration>
          </execution>
        </executions>
      </plugin>
      <plugin>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-contract-maven-plugin</artifactId>
        <version>3.0.4</version>
        <extensions>true</extensions>
        <configuration>
          <baseClassForTests>com.kroger.esb.BaseTestClass</baseClassForTests>
          <testFramework>JUNIT5</testFramework>
        </configuration>
      </plugin>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
      <plugin>
        <groupId>org.jacoco</groupId>
        <artifactId>jacoco-maven-plugin</artifactId>
        <version>0.8.7</version>
        <executions>
          <execution>
            <goals>
              <goal>prepare-agent</goal>
            </goals>
          </execution>
          <execution>
            <id>report</id>
            <phase>prepare-package</phase>
            <goals>
              <goal>report</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

I can’t seem to find anything on Stack Overflow or here on these forums, so I thought I would ask if anyone has had any luck at all getting Sonar to see the Spring Cloud Contract tests.

Thanks.

Ok, after further investigation, it appears it is picking them up for coverage, but not for the number of unit tests metric, which isn’t as big of a deal, but would be nice to know how to fix.

Hello @Viedt

As stated in the documentation:

SonarQube doesn’t run your tests or generate reports. It only imports pre-generated reports.

It means that you will have to provide report paths to the different properties, one for coverage and one for test execution.

For coverage reports generated by Jacoco, we are able to guess the expected path, so it should work out of the box. If not, please check the analysis logs, and eventually set sonar.coverage.jacoco.xmlReportPaths manually.

For unit tests, you will have to set sonar.junit.reportPaths to a comma-delimited list of paths to Surefire XML-format reports.

Hope it helps.
Best,
Quentin