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

时间:2022-10-16 00:00:03

I have a project which I am building with Maven which uses Hibernate (and Spring) to retrieve data from a database, etc.

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

My "tests" for the DAOs in my project extend Spring's AbstractTransactionalDataSourceSpringContextTests so that a DataSource can be wired into my class under test to be able to actually run the query/Hibernate logic, to fetch data, etc.

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

On several other projects I've used these types of test in concert with a HSQL database (either in-memory or pointed at a file) to be able to efficiently test the actual database querying logic without relying on an external database. This works great, since it avoids any external dependencies and the "state" of the database prior to running the tests (each of which are wrapped in a transaction which is rolled back) is well defined.

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

I'm curious though about the best way to organize these tests, which are really a loose flavor of integration tests, with Maven. It feels a bit dirty to keep these tests in src/test/java, but from what I've read there doesn't seem to be a consistent strategy or practice for organizing integration tests with Maven.

我很好奇关于组织这些测试的最佳方法,这些测试对于Maven来说实际上是一种松散的集成测试。将这些测试保存在src / test / java中感觉有点脏,但从我读过的内容来看,似乎并不是用Maven组织集成测试的一致策略或实践。

From what I've read so far, seems like I can use the Failsafe plugin (or a second instance of Surefire) and bind it to the integration-test phase, and that I can also bind custom start-up or shutdown logic (such as for starting/stopping the HSQL instance) to pre-integration-test or post-integration-test. But, is this really the best method?

从我到目前为止所看到的,似乎我可以使用Failsafe插件(或Surefire的第二个实例)并将其绑定到集成测试阶段,并且我还可以绑定自定义启动或关闭逻辑(例如至于启动/停止HSQL实例)到预集成测试或后集成测试。但是,这真的是最好的方法吗?

So my question basically is - what is the generally accepted best practice on organizing this with Maven? I'm having trouble finding any sort of consistent answer in the documentation.

所以我的问题基本上是 - 用Maven组织这个的普遍接受的最佳做法是什么?我在文档中找不到任何一致的答案。

What I'd like is to:

我想要的是:

  • Seperate unit tests from integration tests, so only unit tests are run during the test phase
  • 从集成测试中单独进行单元测试,因此在测试阶段只进行单元测试
  • The ability to bind custom startup/shutdown logic to pre-integration-test and post-integration-test
  • 将自定义启动/关闭逻辑绑定到预集成测试和集成后测试的能力
  • Have the reports from the integration-tests merged/presented with the unit test Surefire reports
  • 将集成测试的报告与单元测试Surefire报告合并/提交

4 个解决方案

#1


21  

There is this codehaus page with some guidelines. I found the failsafe plugin a bit of a hack, and it makes running the unit tests in Eclipse fiendishly complicated. I do broadly what you're describing.

这个codehaus页面有一些指导原则。我发现故障安全插件有点像黑客攻击,这使得在Eclipse中运行单元测试非常复杂。我广泛地描述你所描述的内容。

Define integration tests in src/itest/java In the pre-integration-test phase:

在src / itest / java中定义集成测试在预集成测试阶段:

  • Clear target/test-classes
  • 清除目标/测试类
  • Use the build-helper-maven-plugin's add-test-source goal to add the itest source location
  • 使用build-helper-maven-plugin的add-test-source目标来添加itest源位置
  • Use a custom Mojo to remove src/test/java from the configuration so the unit tests are not compiled again (I don't really like this, but it's needed to maintain the separation of unit and integration tests).
  • 使用自定义Mojo从配置中删除src / test / java,这样单元测试就不会再次编译了(我真的不喜欢这个,但需要保持单元测试和集成测试的分离)。
  • Use the compiler-plugin to compile the integration tests
  • 使用compiler-plugin编译集成测试

Then in the integration-test phase, use the surefire-plugin to run the tests.

然后在集成测试阶段,使用surefire-plugin运行测试。

Finally, bind any tidy up goals to the post-integration-test phase (though normally they're not needed as you can use the test teardown() to tidy up).

最后,将任何整齐的目标绑定到集成后测试阶段(尽管通常不需要它们,因为您可以使用测试拆解()来整理)。

I've not yet found a way to merge the test results as the reporting phase has passed, but I tend to view the integration tests as an added bonus, so as long as they pass the report is not so important.

我还没有找到合并测试结果的方法,因为报告阶段已经过去,但我倾向于将集成测试视为额外的奖励,因此只要他们通过报告就不那么重要了。

Update: I think it's worth pointing out that you can run Jetty from within your integration tests rather than using a jetty goal. This gives you much finer control over the tests. You can get more details from this answer and the referenced blogs.

更新:我认为值得指出的是,您可以在集成测试中运行Jetty,而不是使用jetty目标。这使您可以更好地控制测试。您可以从此答案和引用的博客中获取更多详细信息。

#2


25  

A very simple way of doing this is to use JUnit categories.

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

You can then easily run some tests during the test phase and another during the integration-test phase.

然后,您可以在测试阶段轻松运行某些测试,在集成测试阶段可以轻松运行另一个测试。

It takes minutes and requires only 3 steps.

它需要几分钟,只需要3个步骤。

  1. Define a marker interface
  2. 定义标记界面
  3. Annotate the classes you wish to split
  4. 注释要分割的类
  5. Configure Maven plugins.
  6. 配置Maven插件。

A full example is given here. https://*.com/a/10381662/1365383

这里给出了一个完整的例子。 https://*.com/a/10381662/1365383

#3


7  

This good blog post suggests three options;

这篇好博文提出了三个选择;

1) Separate module for integration tests

1)用于集成测试的独立模块

2) Different source directories

2)不同的源目录

3) Different file name patterns

3)不同的文件名模式

I'm yet to try all three, so can't offer an opinion on which I favour.

我还没试过这三个,所以不能提出我赞成的意见。

#4


1  

I prefer the second option, Different source directories ,but I found quite annoying have to end with IT the integration tests or excluding packages.

我更喜欢第二个选项,不同的源目录,但我发现非常讨厌必须以IT结束集成测试或排除包。

To avoid this, I've ended up with this config:

为了避免这种情况,我最终得到了这个配置:

<properties>
    <testSource>src/test/java</testSource>
    <testSourceResource>src/test/resources</testSourceResource>
</properties>
<build>
    <testSourceDirectory>${testSource}</testSourceDirectory>
    <testResources>
            <testResource>
            <directory>${testSourceResource}</directory>
            </testResource>
        </testResources>
.....
.....

and then I override both variables in different profiles for integration and acceptance test:

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

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

#1


21  

There is this codehaus page with some guidelines. I found the failsafe plugin a bit of a hack, and it makes running the unit tests in Eclipse fiendishly complicated. I do broadly what you're describing.

这个codehaus页面有一些指导原则。我发现故障安全插件有点像黑客攻击,这使得在Eclipse中运行单元测试非常复杂。我广泛地描述你所描述的内容。

Define integration tests in src/itest/java In the pre-integration-test phase:

在src / itest / java中定义集成测试在预集成测试阶段:

  • Clear target/test-classes
  • 清除目标/测试类
  • Use the build-helper-maven-plugin's add-test-source goal to add the itest source location
  • 使用build-helper-maven-plugin的add-test-source目标来添加itest源位置
  • Use a custom Mojo to remove src/test/java from the configuration so the unit tests are not compiled again (I don't really like this, but it's needed to maintain the separation of unit and integration tests).
  • 使用自定义Mojo从配置中删除src / test / java,这样单元测试就不会再次编译了(我真的不喜欢这个,但需要保持单元测试和集成测试的分离)。
  • Use the compiler-plugin to compile the integration tests
  • 使用compiler-plugin编译集成测试

Then in the integration-test phase, use the surefire-plugin to run the tests.

然后在集成测试阶段,使用surefire-plugin运行测试。

Finally, bind any tidy up goals to the post-integration-test phase (though normally they're not needed as you can use the test teardown() to tidy up).

最后,将任何整齐的目标绑定到集成后测试阶段(尽管通常不需要它们,因为您可以使用测试拆解()来整理)。

I've not yet found a way to merge the test results as the reporting phase has passed, but I tend to view the integration tests as an added bonus, so as long as they pass the report is not so important.

我还没有找到合并测试结果的方法,因为报告阶段已经过去,但我倾向于将集成测试视为额外的奖励,因此只要他们通过报告就不那么重要了。

Update: I think it's worth pointing out that you can run Jetty from within your integration tests rather than using a jetty goal. This gives you much finer control over the tests. You can get more details from this answer and the referenced blogs.

更新:我认为值得指出的是,您可以在集成测试中运行Jetty,而不是使用jetty目标。这使您可以更好地控制测试。您可以从此答案和引用的博客中获取更多详细信息。

#2


25  

A very simple way of doing this is to use JUnit categories.

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

You can then easily run some tests during the test phase and another during the integration-test phase.

然后,您可以在测试阶段轻松运行某些测试,在集成测试阶段可以轻松运行另一个测试。

It takes minutes and requires only 3 steps.

它需要几分钟,只需要3个步骤。

  1. Define a marker interface
  2. 定义标记界面
  3. Annotate the classes you wish to split
  4. 注释要分割的类
  5. Configure Maven plugins.
  6. 配置Maven插件。

A full example is given here. https://*.com/a/10381662/1365383

这里给出了一个完整的例子。 https://*.com/a/10381662/1365383

#3


7  

This good blog post suggests three options;

这篇好博文提出了三个选择;

1) Separate module for integration tests

1)用于集成测试的独立模块

2) Different source directories

2)不同的源目录

3) Different file name patterns

3)不同的文件名模式

I'm yet to try all three, so can't offer an opinion on which I favour.

我还没试过这三个,所以不能提出我赞成的意见。

#4


1  

I prefer the second option, Different source directories ,but I found quite annoying have to end with IT the integration tests or excluding packages.

我更喜欢第二个选项,不同的源目录,但我发现非常讨厌必须以IT结束集成测试或排除包。

To avoid this, I've ended up with this config:

为了避免这种情况,我最终得到了这个配置:

<properties>
    <testSource>src/test/java</testSource>
    <testSourceResource>src/test/resources</testSourceResource>
</properties>
<build>
    <testSourceDirectory>${testSource}</testSourceDirectory>
    <testResources>
            <testResource>
            <directory>${testSourceResource}</directory>
            </testResource>
        </testResources>
.....
.....

and then I override both variables in different profiles for integration and acceptance test:

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

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