使用Maven进行集成测试的最佳实践?

68

我正在使用Maven构建一个项目,该项目使用Hibernate(和Spring)从数据库中检索数据等。

我在我的项目中为DAO的“测试”扩展了Spring的AbstractTransactionalDataSourceSpringContextTests,以便可以将一个数据源连接到我的测试类中,以便能够实际运行查询/ Hibernate逻辑来获取数据等。

在其他几个项目中,我与HSQL数据库结合使用这些类型的测试(内存或指向文件),以便能够有效地测试实际的数据库查询逻辑,而无需依赖外部数据库。这很好用,因为它避免了任何外部依赖性,并且在运行测试之前的数据库“状态”(每个测试都包含在回滚的事务中)被定义得很好。

但是,我对使用Maven组织这些测试的最佳方法感到好奇。将这些测试保存在src/test/java中似乎有点肮脏,但从我所读的内容来看,在使用Maven组织集成测试方面并没有一致的策略或做法。

从我迄今为止所读的内容来看,似乎我可以使用Failsafe插件(或第二个Surefire实例),并将其绑定到integration-test阶段,并且我还可以将自定义启动/关闭逻辑(例如用于启动/停止HSQL实例)绑定到pre-integration-testpost-integration-test。但是,这真的是最好的方法吗?

所以我的问题基本上是 - 使用Maven组织这个有什么通常被接受的最佳实践?在文档中找到任何一致的答案都让我感到困难。

我想要的是:

  • 将单元测试与集成测试分开,因此只有单元测试在test阶段运行
  • 能够将自定义启动/关闭逻辑绑定到pre-integration-testpost-integration-test
  • 需要将集成测试的报告与单元测试 Surefire 报告合并/呈现

  • 2
    将集成测试移动到一个单独的项目中,并将单元测试保留在与源代码相同的项目中。 - Thorbjørn Ravn Andersen
    4个回答

    26

    一个非常简单的方法是使用JUnit类别。

    你可以很容易地在测试阶段运行一些测试,而在集成测试阶段运行另一些测试。

    这只需几分钟,并且只需要3个步骤:

    1. 定义一个标记接口
    2. 为您想要拆分的类进行注释
    3. 配置Maven插件

    这里提供了一个完整的示例。 https://dev59.com/jnE85IYBdhLWcg3wzWzM#10381662


    或者如果您正在使用TestNG,您可以指定测试组:例如单元测试和集成测试。 - Kemoda

    21

    这里有一个codehaus页面提供了一些指导方针。我认为failsafe插件有点繁琐,而且在Eclipse中运行单元测试也很复杂。我基本上按照你描述的方式做。

    在src/itest/java中定义集成测试

    在pre-integration-test阶段:
    • 清除target/test-classes
    • 使用build-helper-maven-plugin插件的add-test-source目标添加itest源文件夹
    • 使用自定义Mojo从配置中删除src/test/java,以免编译单元测试(虽然我不是很喜欢这样做,但必须保持单元测试和集成测试的分离)
    • 使用compiler-plugin插件编译集成测试
    然后在integration-test阶段,使用surefire-plugin插件运行测试。
    最后,在post-integration-test阶段绑定任何清理目标(尽管通常不需要,因为您可以使用测试teardown()来清理)。
    我还没有找到一种合并测试结果的方法,因为报告阶段已经过去了,但我认为集成测试是额外的奖励,只要它们通过了测试,报告并不是那么重要。
    更新:我认为值得指出的是,您可以从集成测试中运行Jetty而不是使用jetty目标。这样可以更精细地控制测试。您可以从此答案和引用的博客中获取更多详细信息。


    2
    你真的需要移除单元测试吗?在集成测试时重新运行它们并不是一个坏主意。 - Michael Rutherfurd
    1
    总的来说,你是对的。再次运行单元测试不会有任何损害,但我在服务器上有数百个项目,必须进行一些优化以在可用硬件内管理负载。 - Rich Seller
    好的,你有一个相当重要的特殊情况 :-) - Michael Rutherfurd
    6
    这个回答在2016年还有效吗?看起来使用mvn failsafe插件是更好的选择。 - zengr

    7

    这篇好的博客文章提出了三个选项:

    1) 单独模块进行集成测试

    2) 不同的源目录

    3) 不同的文件名规则

    我还没有尝试过全部三种方法,因此无法确定哪个是最好的选择。


    3
    正确的链接是 http://javamoods.blogspot.com/2009/12/unit-and-integration-testing-with-maven.html。 - Alex

    1
    我更喜欢第二个选项,即不同的源目录,但我发现必须以IT结尾进行集成测试或排除软件包非常烦人。
    为了避免这种情况,我最终采用了以下配置:
    <properties>
        <testSource>src/test/java</testSource>
        <testSourceResource>src/test/resources</testSourceResource>
    </properties>
    <build>
        <testSourceDirectory>${testSource}</testSourceDirectory>
        <testResources>
                <testResource>
                <directory>${testSourceResource}</directory>
                </testResource>
            </testResources>
    .....
    .....
    

    然后我在不同的配置文件中覆盖这两个变量,以进行集成测试和验收测试:

    <profiles>
      <profile>
       <id>acceptance-tests</id>
       <properties>
        <testSource>src/acceptance-test/java</testSource>
        <testSourceResource>src/acceptance-test/resources</testSourceResource>
       </properties>
      </profile>
     <profile>
       <id>integration-tests</id>
        <properties>
        <testSource>src/integration-test/java</testSource>
        <testSourceResource>src/integration-test/resources</testSourceResource>
        </properties>
      </profile>
    .....
    .....
    .....
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接