如何通过Maven让Emma或Cobertura报告其他模块中的源代码报道?

时间:2011-01-17 21:02:41

标签: java junit maven cobertura emma

我有一个带有Java代码的多模块Maven设置。

我的单元测试,在其中一个模块中,在多个模块中练习代码。当然,模块具有相互依赖性,并且在测试执行之前根据需要编译所有相关模块中的代码。

那么:我如何获得整个代码库的覆盖率报告?


注意:我不是要问如何在多个模块中组合测试的覆盖率结果。我问如何使用来自多个模块的检测代码在单个模块中获得测试的覆盖率。对前者感兴趣的任何人都可以参考these other questions,以及Crowne对Maven DashboardSonar的建议。

我成功获得了一份完整的报道using pure Ant。 [编辑:]我将开发运行时目录中的所有jar都检测到了一个临时目录;将临时目录添加到类路径中;然后使用 batch-test 从Ant 运行测试

Ant可以从Maven运行,但这里的挑战是无缝集成(即自动将所有类路径和源路径元素从Maven提供给Ant),这就是为什么我没有为此目的使用Maven的工具。

还有关于集成测试的other questions。但是,默认情况下,默认情况下,每个项目的报告仅报告相同项目中代码的覆盖范围,而我的测试则在多个项目中执行代码。

article in Spanish可能相关。这是另一个Seam-specific article


5 个答案:

答案 0 :(得分:6)

这个recent blog post by Thomas Sundberg包含一种方法,通过使用ant进行cobertura调用而不是使用maven cobertura插件来部分解决问题。

它依赖于以下基本方法和专门的pom.xml和build.xml文件:

从父pom上的典型maven编译开始,它将编译子模块中的所有类。

mvn clean compile # maven-compile-plugin called for compiling

然后检测所有模块类:

ant instrument # cobertura called for instrumentation

然后使用测试类调用maven-surefire-plugin进行测试,将cobertura作为测试依赖项

mvn test 

然后使用自定义报告调用从不同模块中提取所有结果:

ant report # cobertura called for reporting

ant build.xml文件的关键元素是分别检测所有模块,然后在合并结果后报告所有模块。需要为他的示例中的每个模块调用此函数:

<target name="instrumentAModule">
    <property name="classes.dir" value="target/classes"/>
    <cobertura-instrument todir="./${module}/${classes.dir}">
        <fileset dir="./${module}/target/classes">
            <include name="**/*.class"/>
        </fileset>
    </cobertura-instrument>
</target>

然后在测试完成后,报告阶段首先将来自所有不同目录的所有结果合并到一个新的.ser文件中(在他的示例中称为sum.ser)

<target name="report" depends="merge">
    <property name="src.dir" value="src/main/java/"/>
    <cobertura-report datafile="sum.ser"
                      format="html"
                      destdir="./target/report">
        <!-- Add all modules that should be included below -->
        <!-- fileset dir="./MODULE_NAME_TO_REPLACE/${src.dir}"/ -->
        <fileset dir="./product/${src.dir}"/>
    </cobertura-report>
</target>

<target name="merge">
    <cobertura-merge datafile="sum.ser">
        <fileset dir=".">
            <include name="**/cobertura.ser"/>
        </fileset>
    </cobertura-merge>
</target>

有可能使用antrun插件将ant组件集成到maven中,但我不熟悉阶段/生命周期知道将不同的调用放在哪里。

这对我来说非常有用,因为我在我的api模块中编写抽象测试类,然后在我的lib模块中为它们提供实现。到目前为止,cobertura和emma都无法处理这种设计,因此我的代码覆盖范围通常为0或单个数字。

答案 1 :(得分:4)

没试过,但这可能是实现它的一种方法:

  • 在每个模块中,就在 install 阶段之前,让cobertura检测jar文件并将检测到的jar文件(!)安装到本地Maven存储库中
  • 在tests-module中,Maven将使用本地Maven存储库中的工件依赖项来运行测试。这些检测类现在应该出现在数据文件中,例如cobertura.ser
  • 像往常一样从项目的测试模块中运行cobertura-report生成,例如: mvn site

请参阅cobertura文档,了解如何手动调用cobertura以就地检测外部JAR文件:

  

...您还可以传入jar文件,使用标准的ant文件集进行检测。 Cobertura将从罐子中提取每个类并对其进行检测。如果未指定'todir',则原始jar将被检测版本覆盖 ...

pom.xml的构建插件可能如下所示 - 如果您不想覆盖它们,您可能需要添加配置文件或使用分类器来区分最终的jar文件和已检测的jar文件你当地的回购。然后,在tests模块中,您只需要使用分类器为其他模块定义依赖项。

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <executions>
                <execution>
                    <id>cobertura-inplace-instrumentation</id>
                    <phase>package</phase>
                    <configuration>
                        <tasks>
                            <taskdef classpathref="maven.plugin.classpath" resource="tasks.properties" />
                            <cobertura-instrument
                                datafile="${project.build.directory}/cobertura-nop.ser">
                                <fileset dir="${project.build.directory}">
                                    <include name="${project.build.finalName}.${project.packaging}" />
                                </fileset>
                            </cobertura-instrument>
                        </tasks>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>net.sourceforge.cobertura</groupId>
                    <artifactId>cobertura</artifactId>
                    <version>1.9.4.1</version>
                </dependency>
            </dependencies>
        </plugin>

答案 2 :(得分:2)

通常,报告与其特定模块有关,但它们可以汇总,
两种方法是:

我建议您尝试使用声纳为您执行报告聚合。

查看他们的公共实例“nemo”,以查看所提供的令人印象深刻的功能。

答案 3 :(得分:0)

我怀疑是否可能,因为覆盖信息是由cobertura / emma通过检测编译的类获得的。虽然这适用于指定项目中的类,但这些工具是否会依赖于仪器依赖库是值得怀疑的。

查看maven cobertura plugin usage似乎也没有表明任何这种可能性。

答案 4 :(得分:0)

我发现这很简单(虽然我刚才做过,但可能会因为细节而生锈......

我的核心项目包含所有模块。我用Cobertura测量我的测试覆盖率。我使用Hudson作为持续集成引擎,并为Hudson提供Cobertura插件。

它已经有一段时间了。

祝你好运!