jacoco coverage per test setup

空扰寡人 提交于 2019-12-04 16:55:52
HankCa

Add the jacoco-maven-plugin since that is what is using the Listener and it seems to be missing from your pom. Like this:

           <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>0.7.7.201606060606</version>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <!--<phase>test</phase>-->
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to the file to write the execution data to. -->
                            <destFile>${sonar.jacoco.reportPath}</destFile>
                            <!-- Connection with SureFire plugin -->
                            <propertyName>sonarUnitTestArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to where the execution data is located. -->
                            <dataFile>${sonar.jacoco.reportPath}</dataFile>
                            <!-- Sets the output directory for the code coverage report. -->
                            <outputDirectory>${jacoco.ut.outputdir}</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>pre-integration-test</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>prepare-agent-integration</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to the file to write the execution data to. -->
                            <destFile>${sonar.jacoco.itReportPath}</destFile>
                            <!-- Connection with Failsafe plugin -->
                            <propertyName>sonarIntegrationTestArgLine</propertyName>
                        </configuration>
                    </execution>
                    <execution>
                        <id>post-integration-test</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>report-integration</goal>
                        </goals>
                        <configuration>
                            <!-- Sets the path to where the execution data is located. -->
                            <dataFile>${sonar.jacoco.itReportPath}</dataFile>
                            <!-- Sets the output directory for the code coverage report. -->
                            <outputDirectory>${jacoco.it.outputdir}</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>default-check</id>
                        <goals>
                            <goal>check</goal>
                        </goals>
                        <configuration>
                            <dataFile>${sonar.jacoco.itutCombinedReportPath}</dataFile>
                            <haltOnFailure>true</haltOnFailure>
                            <rules>
                                <!--  implementation is needed only for Maven 2  -->
                                <rule implementation="org.jacoco.maven.RuleConfiguration">
                                    <element>BUNDLE</element>
                                    <limits>
                                        <!--  Bump this up.  Currently a very low 0.01 -->
                                        <limit implementation="org.jacoco.report.check.Limit">
                                            <counter>COMPLEXITY</counter>
                                            <value>COVEREDRATIO</value>
                                            <minimum>0.01</minimum>
                                        </limit>
                                    </limits>
                                </rule>
                            </rules>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

My properties are:

<properties>
   ...
    <!-- Sonar static analysis / Jacoco code coverage -->
    <sonar.host.url>https://sonar.domain.com/</sonar.host.url>
    <sonar.projectKey>${project.artifactId}</sonar.projectKey>
    <sonar.projectName>${project.artifactId}</sonar.projectName>
    <sonar.projectVersion>${project.version}</sonar.projectVersion>
    <sonar.language>java</sonar.language>
    <sonar.sources>src/main/java</sonar.sources>
    <sonar.test>target/test-classes</sonar.test>
    <sonar.scm.provider>git</sonar.scm.provider>
    <sonar.login>${SONAR_LOGIN}</sonar.login>
    <jacoco.basedir>${project.build.directory}/code-coverage</jacoco.basedir>
    <!-- Define location of Java CodeCoverage data from Unit Tests (run using SureFire) -->
    <sonar.jacoco.reportPath>${jacoco.basedir}/jacoco-ut.exec</sonar.jacoco.reportPath>
    <jacoco.ut.outputdir>${jacoco.basedir}/jacoco-ut-out</jacoco.ut.outputdir>
    <!-- Define location of Java CodeCoverage data from Integration Tests (run using Failsafe) -->
    <sonar.jacoco.itReportPath>${jacoco.basedir}/jacoco-it.exec</sonar.jacoco.itReportPath>
    <jacoco.it.outputdir>${jacoco.basedir}/jacoco-it-out</jacoco.it.outputdir>
    <!-- Combined report file -->
    <sonar.jacoco.itutCombinedReportPath>${jacoco.basedir}/jacoco-itut-combined.exec</sonar.jacoco.itutCombinedReportPath>
</properties>

And for the record, here is my AntRun plugin that creates the itUtCombined report file. WARNING - I haven't finished testing to confirm this works properly (feedback appreciated!):

         <plugin>
                <!--The JaCoCo report files need to be combined into one for the code coverage check-->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <phase>post-integration-test</phase>
                        <configuration>
                            <target>
                                <!--<copy file="${sonar.jacoco.reportPath}" tofile="${sonar.jacoco.itutCombinedReportPath}"/>-->
                                <concat destfile="${sonar.jacoco.itutCombinedReportPath}" append="true" binary="yes">
                                    <filelist files="${sonar.jacoco.reportPath},${sonar.jacoco.itReportPath}"/>
                                </concat>
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

(This comes from the comments in my first answer which I'm keeping as it is a relevant answer in situations - https://stackoverflow.com/a/38177659/1019307)

Are you sure that is your surefire configuration?

I get the same result if my POM includes <reuseForks>false</reuseForks> AND the org.sonar.java.jacoco.JUnitListener in the surefire configuration:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${surefire.version}</version>
            <configuration>
                <reuseForks>false</reuseForks>
                <!-- Headless - prevent the annoying ForkedBooter process from stealing window focus on Mac OS -->
                <argLine>${surefireArgLine} -Djava.awt.headless=true</argLine>
                <skipTests>${skip.unit.tests}</skipTests>
                <includes>
                    <include>au/gov/ga/geodesy/**/*.java</include>
                </includes>
                <properties>
                    <property>
                        <name>listener</name>                                
                        <value>org.sonar.java.jacoco.JUnitListener</value>
                    </property>
                </properties>
            </configuration>
        </plugin>

You can either drop <reuseForks>false</reuseForks> OR switch to TestNG which doesn't seem to suffer this problem:

         <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>6.9.4</version>
            <scope>test</scope>
        </dependency>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <forkCount>1</forkCount>
                <!-- Headless - prevent the annoying ForkedBooter process from stealing window focus on Mac OS -->
                <argLine>${surefireArgLine} -Djava.awt.headless=true</argLine>
                <skipTests>${skip.unit.tests}</skipTests>
                <includes>
                    <include>au/gov/ga/geodesy/**/*.java</include>
                </includes>
                <properties>
                    <property>
                        <name>listener</name>
                        <value>org.sonar.java.jacoco.TestNGListener</value>
                    </property>
                </properties>
            </configuration>
        </plugin>

When I'm wearing my developer hat, the real difference to me between TestNG and Junit is the order of the arguments to assertEquals. Which is just plainly annoying. However now we've adopted (my team!) the practice of using Hamcrest so that this is no longer an issue:

Thus:

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;

...

@Test public void theTest() {
    assertNotNull(manifestService.getExternalManifests());
    assertEquals(1, manifestService.getExternalManifests().size());

Becomes:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.core.IsNot.not;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

....

@Test public void theTest() {
    assertThat(manifestService.getExternalManifests(), not(nullValue()));
    assertThat(manifestService.getExternalManifests().size(), is(1));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!