web-dev-qa-db-ja.com

Mavenマルチモジュールプロジェクトのcobertura

私は4つのモジュールを持つMavenプロジェクトを持っています-それらの3つにはコードといくつかのテスト(クラスのequalsとハッシュコードのテスト)が含まれていますが、4番目のモジュールは他の3つのモジュールをテストするためのものです。

ここで、coberturaコードカバレッジツールを実行して、十分にテストされているクラスとテストされていないクラスの概要を取得します。私はそのトピックについていくつかの調査を行いましたが、テストされたソースが他のモジュール内にある場合、coberturaは正しいコードカバレッジのパーセンテージとラインカバレッジを生成することを認識していないようです。

SeamT​​estCoverageWithCoberturaマルチモジュールMaven 2内でプラグインCoverageを使用 のようないくつかのリンクを読みましたが、すぐに使用できるソリューションが必要です。誰かがこのトピックに関するいくつかの新しい方向性を報告できますか?それとも、coberturaのような他のツールはありますか?私はemmaに出くわしましたが、このツールはラインカバレッジを提供していません...

30
pangratz

バージョン2.6以降、親pomでtrueに設定できる集約オプションがあります。

<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>
19
Martin

ここにはソナーがありません。現在、インストールできません。だから私は回避策を見つけてそれを手に入れなければなりませんでした。このソリューションは、マルチモジュールプロジェクトの単純なmvn clean install -DrunCobertura=trueで機能します。このプロファイルをプロジェクトのsuper pom.xmlに追加し、working.dirプロパティを定義するだけで、機能するはずです。

<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>

それは何をするためのものか:

1。@process-classes-モジュールのコンパイル済みクラスを計測します。

2。@generate-test-sources-前のモジュールの.serファイルを、このモジュールの作成済みファイルとマージして、完全なコードカバレッジを取得します。

@test-コードカバレッジレポートを作成します。最後のモジュールで呼び出す必要がありますが、最後のモジュールは変更される可能性があるため、常に呼び出します。以前のレポートは上書きされます。レポートをxml形式(Jenkinsの場合)で使用する場合は高速なので、問題ありません。

9
Sven Oppermann

MCOBERTURA-65 によると、Maven coberturaプラグインは、サブモジュールのレポートを統合されたレポートに集約する方法をまだ知りません。 Mavencoberturaプラグインにmergeターゲットを実装するためにいくつかの作業が行われました( MCOBERTURA- を参照)が、このコードはまだプラグインに含まれていません。私は自分でパッチをテストしなかったので、試してみる価値があるかどうかはわかりません。

結果として、多くの人が実際にMavenの使用を提案しています ダッシュボードプラグイン しかし、長期的にはあまり満足のいくものではなく、多くの問題に直面したため、個人的には遠く離れています。 (技術的な問題、歴史の喪失、...)。代わりに、私は暖かくお勧めします ソナー。このツールのライブデモについては、Sonarの最後のバージョンのパブリックインスタンスである Nemo をご覧ください。たとえば、 Commons Digester プロジェクトおよび コードカバレッジのドリルダウン を参照してください。

8
Pascal Thivent

Cobertura(およびその他の)レポートを集約するプラグインがいくつかあります。 sonar および XRadar プラグインを確認してください。 ダッシュボードプラグイン もありますが、少し不格好です。

FWIWエマは行います ラインカバレッジ

3
Rich Seller

RunCoberturaプロファイルソリューションを提出してくれたSvenOppermannに心から感謝します。これは、Sonarを使用できない可能性がある場合に、マルチモジュールプロジェクトの集計カバレッジレポートをどのように取得するかという問題を解決するのに役立ちました。

単体テストのカバレッジ(すべてのサブモジュール)だけでなく、アプリケーションを.WAR INJETTYとして起動する統合テストのカバレッジも評価するコードカバレッジレポートを生成するマルチモジュールプロジェクトを作成する方法を示す例を作成しました。例はここでホストされています:

        http://dl.dropbox.com/u/9940067/code/multi-module-cobertura.Zip 

私が提供しているレシピは、以下にリストされているrunCoberturaプロファイルをコピーするとかなり再利用できます(Svenによって提供されたものに基づいています)。

このプロファイルの使用に役立つメモを次に示します。

  • jettyを起動する(そして本番環境の.warに対して実行されるテストを定義する)統合テストモジュールは、web-test-driver-for-code-coverageという名前にするか、runCobertura構成ブロックのステートメントを変更する必要があります。

  • 変数を設定すると、カバレッジレポートが表示されます

  • コードカバレッジのためにビルドを実行するときは、コマンドラインに「clean」を含める必要があります。 「clean」は以前のcobertura.serファイルを吹き飛ばします。これは、潜んでいると非常に紛らわしいレポートが生成される可能性があります(「clean」する必要がある兆候は、レポートが、知っているものを含め、すべてを100%カバーしていることです。呼び出されることはありません。

      mvn -PrunCobertura clean install      # gives you the aggregate reports.
    
  • モジュールweb-test-driver-for-code-coverageは、Webサーバーのシャットダウン時にcoberturaメトリックをディスクに明示的にフラッシュするサーブレットコンテキストリスナーを定義します。おそらくコンテナはこれを自動的に行うことになっていますが、それは私にとってはうまくいきませんでした。そのため、メトリックをフラッシュするために明示的な呼び出しをフックする必要がありました。

  • 統合テストはgroovyで行われます。これは、すでにgroovyを使用しているいくつかのMavenプロジェクトスケルトンに基づいているためです。雑然として申し訳ありませんが、Groovyでテストを行う方法を示しています(とにかく強くお勧めします)。

  • RunCoberturaプロファイルを使用してコンパイルすると、.warファイルも含め、すべてのアーティファクトがcoberturaインストルメンテーションで作成されることに注意してください。もちろん、これを本番環境に出させたくはありません(1つには、実行速度が非常に遅くなります)。「cobertura-ness」が明らかになるように、アーティファクトの名前を変更する方法をまだ理解していません。

    <profiles>
    <profile>
        <id>runCobertura</id>
        <activation>
            <property>
                <name>runCobertura</name>
                <value>true</value>
            </property>
        </activation>
        <properties>
            <cobertura.format>html</cobertura.format>
            <working.dir>/tmp</working.dir>
            <cobertura.working.dir>${working.dir}/${project.version}/cobertura</cobertura.working.dir>
            <cobertura.complete.ser.file>${cobertura.working.dir}/complete.ser</cobertura.complete.ser.file>
    
            <!-- scope which determines whether or not cobertura is included in .war file: overriden here -->
            <cobertura.dependency.scope>compile</cobertura.dependency.scope>
        </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"/>
                                    <echo message="::PROCESS CLASSES: ${artifactId}"/>
    
                                    <if>
                                      <equals arg1="${artifactId}" arg2="web-test-driver-for-code-coverage" />
                                        <then>
                                            <echo message="::SKIPPING PHASE for integration test"/>
                                        </then>
                                        <else>
                                            <if>
                                                <available file="${project.build.outputDirectory}"/>
                                                <then>
                                                    <echo message="::BEFORE INSTRUMENT"/>
                                                    <cobertura-instrument>
                                                        <fileset dir="${project.build.outputDirectory}">
                                                            <include name="**/*.class"/>
                                                        </fileset>
                                                    </cobertura-instrument>
                                                </then>
                                            </if>
                                        </else>
                                    </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"/>
                                    <echo message=":::generate-test-sources"/>
    
    
                                    <if>
                                      <equals arg1="${artifactId}" arg2="web-test-driver-for-code-coverage" />
                                        <then>
                                            <echo message="::SHORT CIRCUIT COMBINE PHASE for integration test"/>
                                            <echo  message="source - ${cobertura.complete.ser.file} dest - ${basedir}/cobertura.ser"/>
                                            <copy file="${cobertura.complete.ser.file}" tofile="${basedir}/cobertura.ser"/>
                                        </then>
                                        <else>
                                            <if>
                                                <available file="${basedir}/cobertura.ser"/>
                                                <then>
                                                    <echo message="::: Is available ${basedir}/cobertura.ser"/>
                                                </then>
                                            </if>
    
                                            <if>
                                                <available file="${cobertura.complete.ser.file}"/>
                                                <then>
                                                    <echo message="before merge1"/>
                                                    <cobertura-merge datafile="${basedir}/tmp.ser">
                                                        <fileset file="${cobertura.complete.ser.file}"/>
                                                        <fileset file="${basedir}/cobertura.ser"/>
                                                    </cobertura-merge>
                                                    <echo message="move temp.ser to ${basedir}/cobertura.ser"/>
                                                    <move file="${basedir}/tmp.ser" tofile="${basedir}/cobertura.ser"/>
                                                </then>
                                            </if>
                                        </else>
                                    </if>
                                </target>
                            </configuration>
                        </execution>
                        <execution>
                            <id>cobertura-copyResultSerFileAndSources</id>
                            <phase>verify</phase>
                            <goals>
                                <goal>run</goal>
                            </goals>
                            <configuration>
                                <target>
                                    <taskdef resource="tasks.properties"/>
                                    <taskdef resource="net/sf/antcontrib/antcontrib.properties"/>
    
                                    <echo message=":::copyResultSerFileAndSources -beforeIf"/>
                                    <if>
                                        <available file="${basedir}/cobertura.ser"/>
                                        <then>
                                            <echo message="move1"/>
                                            <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>
                                            <echo message="runreport"/>
                                            <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>
            </dependency>
        </dependencies>
    </profile>
    </profiles>
    
2
Chris Bedford

Thomas Sundbergは、インストルメンテーションとテストのレポートがantを介して行われるが、すべてのテストと依存関係の管理がmvnを介して行われる興味深いソリューションを提供します。

ここをチェックしてください: thomassundberg wordpress

これは、以下のコマンドを親レベルで次の順序で実行する必要があることを意味します。

mvn clean compile
ant instrument
mvn test
ant report

これらのステップをsonarに統合することは、MartijnStelingaによって説明されています。

test-coverage-in-multi-module-projects

1
avandeursen

この回答のおかげで、必要なものと非常によく似たものを実装できます: Maven-アーティファクトソースへの依存関係を追加

<classifier>sources</classifier>を追加したところ、coberturaには依存関係のクラスも含まれています。

よろしく。

0
mschonaker