Understanding JaCoCo and Maven Integration | Generated by AI

Home 2025.10

Got it—here’s how the JaCoCo pieces in your exact POM work together, step-by-step, and why.


The two coverage streams this POM creates

  1. Unit-test coverage (Surefire path)
  1. Integration-test coverage (Jetty path)

Lifecycle flow (what happens on mvn verify)

  1. compile

    • Spotless formats (spotless-maven-plugin) and Checkstyle runs (maven-checkstyle-plugin).
    • Your WAR is prepared (maven-war-plugin).
  2. test (Surefire)

    • If you have unit tests, they run under the prepare-agent injected argLine → coverage goes to target/jacoco.exec.
  3. pre-integration-test

    • Jetty is started in daemon mode:

      <daemon>true</daemon>
      

      Maven immediately regains control; Jetty keeps running with the JaCoCo agent attached, writing to jacoco-it.exec.

  4. integration-test

    • Your Python tests hit the running app:

      <plugin>
        <artifactId>exec-maven-plugin</artifactId>
        <execution>
          <id>python-integration-tests</id>
          <phase>integration-test</phase>
          <goals><goal>exec</goal></goals>
          <configuration>
            <executable>python3</executable>
            <workingDirectory>${project.parent.basedir}</workingDirectory>
            <arguments>
              <argument>-m</argument><argument>unittest</argument>
              <argument>discover</argument><argument>tests/</argument>
              <argument>-v</argument>
            </arguments>
          </configuration>
        </execution>
      </plugin>
      

      These tests exercise Jetty, so coverage accumulates in target/jacoco-it.exec via the Jetty JVM’s agent.

  5. post-integration-test

    • Jetty is cleanly stopped:

      <execution>
        <id>stop-jetty</id>
        <phase>post-integration-test</phase>
        <goals><goal>stop</goal></goals>
        ...
      </execution>
      
  6. verify

    • You generate a separate IT report using the IT data file and a custom output directory:

      <execution>
        <id>report-it</id>
        <phase>verify</phase>
        <goals><goal>report</goal></goals>
        <configuration>
          <dataFile>${jacoco.it.exec}</dataFile>
          <outputDirectory>${project.reporting.outputDirectory}/jacoco-it
          </outputDirectory>
        </configuration>
      </execution>
      
    • Result: HTML goes to target/site/jacoco-it/index.html summarizing only integration coverage (from Jetty).

Note: If you also want a unit-test report, you could add another jacoco:report execution that points at the default target/jacoco.exec and outputs to target/site/jacoco—keeping unit and IT reports separate.


About “create new or replace?” for the .exec files

Best practice (to avoid mixing old data):


What each relevant block in your original XML is doing (by reference)


Practical tips / small improvements


TL;DR


Back

openai/gpt-5

Donate