12

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

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

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


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

我使用纯 Ant成功获得了完整的覆盖率报告 。[编辑:] 我将 development-runtime 目录中的所有 jar 检测到一个临时目录中;将临时目录添加到类路径中;然后使用批处理测试从 Ant运行测试。

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

还有其他 关于集成测试的问题。但是,默认情况下,每个项目的报告默认只报告同一项目中代码的覆盖率,而我的测试在多个项目中执行代码。

这篇西班牙语文章可能是相关的。这是另一篇特定于 Seam 的文章


4

5 回答 5

6

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 或个位数。

于 2012-02-29T03:07:10.850 回答
4

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

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

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

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

pom.xml构建插件可能看起来像这样 - 如果您不想在本地 repo 中覆盖它们,您可能需要添加配置文件或使用分类器来区分最终的 jar 文件和检测的 jar 文件。然后,在测试模块中,您只需要使用分类器定义与其他模块的依赖关系。

        <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>
于 2011-01-19T23:20:17.513 回答
2

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

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

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

于 2011-01-19T20:16:41.610 回答
0

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

看一下maven cobertura 插件的使用似乎也没有表明任何这种可能性。

于 2011-01-18T02:17:45.490 回答
0

我发现这很简单(虽然我前一段时间做过,但细节可能生疏了......

我的核心项目包含所有模块。我使用 Cobertura 来衡量我的测试覆盖率。我正在使用 Hudson 作为持续集成引擎,并拥有适用于 Hudson 的 Cobertura 插件。

它已经工作了一段时间了。

祝你好运 !

于 2011-01-19T19:46:09.313 回答