Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cobertura on maven multi module project

I have a Maven project with 4 modules - 3 of them contain code and some tests (testing equals and hashcode of the classes) whereas the 4th module is for testing the 3 other modules.

Now I want to run the cobertura code coverage tool to get an overview which classes are well tested and which are not. I did some investigations on that topic and it seems that cobertura is not aware of generating the right code coverage percentages and line coverages, if some sources which are tested are located within other modules.

I have read over some links like SeamTestCoverageWithCobertura and Using the plugin Coverage within a multi-module Maven 2 but there has to be an out of the box solution. Can anybody report some new directions on this topic? Or are there bether tools like cobertura? I've stumbled upon emma but this tool does not offer line coverage...

like image 667
pangratz Avatar asked Sep 14 '09 10:09

pangratz


People also ask

What does cobertura Maven plugin do?

Simply put, Cobertura is a reporting tool that calculates test coverage for a codebase – the percentage of branches/lines accessed by unit tests in a Java project.

Can two Maven modules depend on each other?

Because modules within a multi-module build can depend on each other, it is important that the reactor sorts all the projects in a way that guarantees any project is built before it is required. The following relationships are honoured when sorting projects: a project dependency on another module in the build.


2 Answers

As of version 2.6, there is an aggregate option that can be set to true in the parent pom:

<reporting> <plugins>   <plugin>     <groupId>org.codehaus.mojo</groupId>     <artifactId>cobertura-maven-plugin</artifactId>     <version>2.6</version>     <configuration>         <outputDirectory>./target/tmpCobertura</outputDirectory>         <formats>             <format>html</format>         </formats>         <aggregate>true</aggregate>     </configuration>   </plugin> </plugins> </reporting> 
like image 149
Martin Avatar answered Sep 17 '22 09:09

Martin


We don't have sonar here and right now, we cant install it. So i had to find a workaround and got one. This solution works with a simple mvn clean install -DrunCobertura=true in a multi module project. You only need to add this profile to your super pom.xml of your project, define the working.dir property and it should work.

<profile>     <id>runCobertura</id>     <activation>         <property>             <name>runCobertura</name>             <value>true</value>         </property>     </activation>     <properties>         <cobertura.format>html</cobertura.format>         <cobertura.working.dir>${working.dir}/${project.version}/cobertura</cobertura.working.dir>         <cobertura.complete.ser.file>${cobertura.working.dir}/complete.ser</cobertura.complete.ser.file>     </properties>     <build>         <plugins>             <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-clean-plugin</artifactId>                 <version>2.4.1</version>                 <inherited>false</inherited>                 <configuration>                     <filesets>                         <fileset>                             <directory>.</directory>                             <includes>                                 <include>cobertura.ser</include>                             </includes>                         </fileset>                         <fileset>                                 <directory>${cobertura.working.dir}</directory>                             </fileset>                     </filesets>                 </configuration>             </plugin>             <plugin>                 <groupId>org.apache.maven.plugins</groupId>                 <artifactId>maven-antrun-plugin</artifactId>                 <version>1.7</version>                 <executions>                     <execution>                         <id>cobertura-Instrument</id>                         <phase>process-classes</phase>                         <goals>                             <goal>run</goal>                         </goals>                         <configuration>                             <target>                                 <taskdef resource="tasks.properties"/>                                 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>                                 <if>                                     <available file="${project.build.outputDirectory}"/>                                     <then>                                         <cobertura-instrument>                                             <fileset dir="${project.build.outputDirectory}">                                                 <include name="**/*.class"/>                                             </fileset>                                         </cobertura-instrument>                                     </then>                                 </if>                             </target>                         </configuration>                     </execution>                     <execution>                         <id>cobertura-createCombinedSerFile</id>                         <phase>generate-test-sources</phase>                         <goals>                             <goal>run</goal>                         </goals>                         <configuration>                             <target>                                 <taskdef resource="tasks.properties"/>                                 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>                                 <if>                                     <available file="${cobertura.complete.ser.file}"/>                                     <then>                                         <cobertura-merge datafile="${basedir}/tmp.ser">                                             <fileset file="${cobertura.complete.ser.file}"/>                                             <fileset file="${basedir}/cobertura.ser"/>                                         </cobertura-merge>                                         <move file="${basedir}/tmp.ser" tofile="${basedir}/cobertura.ser"/>                                     </then>                                 </if>                             </target>                         </configuration>                     </execution>                     <execution>                         <id>cobertura-copyResultSerFileAndSources</id>                         <phase>test</phase>                         <goals>                             <goal>run</goal>                         </goals>                         <configuration>                             <target>                                 <taskdef resource="tasks.properties"/>                                 <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>                                 <if>                                     <available file="${basedir}/cobertura.ser"/>                                     <then>                                         <move file="${basedir}/cobertura.ser" tofile="${cobertura.complete.ser.file}"/>                                         <mkdir dir="${cobertura.working.dir}/source"/>                                         <if>                                             <available file="${basedir}/src/main/java"/>                                             <then>                                                 <copy todir="${cobertura.working.dir}/source">                                                     <fileset dir="src/main/java">                                                         <include name="**/*.java"/>                                                     </fileset>                                                 </copy>                                             </then>                                         </if>                                         <cobertura-report datafile="${cobertura.complete.ser.file}" format="${cobertura.format}" destdir="${cobertura.working.dir}/report">                                             <fileset dir="${cobertura.working.dir}/source"/>                                         </cobertura-report>                                     </then>                                 </if>                             </target>                         </configuration>                     </execution>                 </executions>                 <dependencies>                     <dependency>                         <groupId>net.sourceforge.cobertura</groupId>                         <artifactId>cobertura</artifactId>                         <version>1.9.4.1</version>                     </dependency>                     <dependency>                         <groupId>ant-contrib</groupId>                         <artifactId>ant-contrib</artifactId>                         <version>20020829</version>                     </dependency>                 </dependencies>             </plugin>         </plugins>     </build>     <dependencies>         <dependency>             <groupId>net.sourceforge.cobertura</groupId>             <artifactId>cobertura</artifactId>             <version>1.9.4.1</version>             <scope>test</scope>         </dependency>     </dependencies> </profile> 

What does it do:

1. @process-classes-Instrument the compiled classes of the module.

2. @generate-test-sources-Merges the .ser file from previous modules with the created one of this module to get the complete code coverage.

3. @test-Creates the code coverage report. Should be called in the last module, but due to the fact that the last module can change, i call it always and the previous reports will be overwritten. If you use the report in xml format (for Jenkins) it's fast, so it doesn't matter.

like image 26
Sven Oppermann Avatar answered Sep 20 '22 09:09

Sven Oppermann