Java Maven 集成测试的最佳实践?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1228709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practices for integration tests with Maven?
提问by matt b
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
以便数据源可以连接到我的测试类中,以便能够实际运行查询/休眠逻辑,获取数据等。
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 的第二个实例)并将其绑定到integration-test
阶段,而且我还可以绑定自定义启动或关闭逻辑(例如用于启动/ 停止 HSQL 实例)到pre-integration-test
或post-integration-test
。但是,这真的是最好的方法吗?
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
andpost-integration-test
- Have the reports from the integration-tests merged/presented with the unit test Surefire reports
- 将单元测试与集成测试分开,因此在该
test
阶段只运行单元测试 - 将自定义启动/关闭逻辑绑定到
pre-integration-test
和的能力post-integration-test
- 将来自集成测试的报告与单元测试 Surefire 报告合并/呈现
采纳答案by Rich Seller
There is this codehaus pagewith 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 中定义集成测试 在 pre-integration-test 阶段:
- Clear target/test-classes
- Use the build-helper-maven-plugin's add-test-source goal to add the itest source location
- 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).
- Use the compiler-plugin to compile the integration tests
- 清除目标/测试类
- 使用build-helper-maven-plugin的 add-test-source 目标添加 itest 源位置
- 使用自定义 Mojo 从配置中删除 src/test/java 以便不会再次编译单元测试(我真的不喜欢这个,但需要它来保持单元测试和集成测试的分离)。
- 使用 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).
最后,将任何整理目标绑定到后集成测试阶段(尽管通常不需要它们,因为您可以使用测试 teardown() 进行整理)。
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 answerand the referenced blogs.
更新:我认为值得指出的是,您可以从集成测试中运行 Jetty,而不是使用 jetty 目标。这使您可以更好地控制测试。您可以从此答案和引用的博客中获得更多详细信息。
回答by Mike
This good blog postsuggests 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.
我还没有尝试所有三个,所以不能提供我喜欢的意见。
回答by John Dobie
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 个步骤。
- Define a marker interface
- Annotate the classes you wish to split
- Configure Maven plugins.
- 定义一个标记接口
- 注释您要拆分的类
- 配置 Maven 插件。
A full example is given here. https://stackoverflow.com/a/10381662/1365383
这里给出了一个完整的例子。 https://stackoverflow.com/a/10381662/1365383
回答by Pablo Gutierrez
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>
.....
.....
.....