我们有一个包含多个子模块的EAR项目(多个EJB,Web项目,应用程序客户端等)。单一测试的自然范围是它们各自的子模块(因为它们应该是测试隔离单元)。
在很短的时间内,我们引入了非明显的测试依赖项。项目正在嘲笑来自其他项目的功能等。很快我们的架构演变成了几个带有模拟的独立jar文件(web项目1个模拟,ejb 2模拟等);我们将这些嘲讽与EAR联系起来并消耗子模块中的嘲讽(" Skinny War" style)。
EAR
Modules
WEB 1
WEB 2
EJB 2
EJB 3
etc
Libs
Shared library 1
Shared Library 2
Testing dependencies
WEB 1 mocks
WEB 2 mocks
EJB 1 mocks
EJB 2 mocks
etc
WEB1
Uses EJB 1 and EJB 3
Uses Shared Library 1
Testing
Consumes EJB 1 and EJB 2 mocks
无论如何,我们团队的共识是模拟失控。我们希望向Arquillian发展并在容器内部进行测试(例如,向集成测试)。我们还介绍了ATTD(最初只是使用Drone进行功能测试,但我希望尽快安装功能完整的Thucydidies + JBehave或EasyB)。
测试可能取决于来自多个子模块的资源。 ShrinkWrap可以保证事情不会失控。
所以我的问题是:我应该在哪里放置测试,故事,Arquillian配置文件等等?
我觉得EAR是分组一切的最佳场所:
EAR
Modules
Test
src
Java
Test 1
Test 2
Resources
Configuration Files
Stories
Story 1
Story 2
这将允许我们有一个统一的报告,忘记模块间的依赖关系,有一个单一的配置点等等。
但我可能错了(使用每个模块的粒度有其优点)。
那么Arquillian测试的最佳实践是什么:我应该将我的测试文件放在EAR项目中吗?我应该在EAR项目中进行集成/验收测试吗?在子模块中进行单一测试吗?或者我应该把所有东西放在子模块中吗?
更新:替代方法。我应该isolate integration tests进入一个单独的模块吗?如果是这样,如何(如何设置依赖关系,配置Arquillian等)?
答案 0 :(得分:7)
让我提供一些关于如何使用Maven组织集成测试的实用信息,以便其他人可以使用它来做正确的事情。
我最终接受了来自梦幻般的(即使有点旧)Better Builds with Maven以及Codehaus Maven and Integration Testing Guide的建议。
使用聚合器顶级项目:
myproject
myproject-ear
myproject-war
myproject-ejb
...
myproject-integration-tests
作为suggested by mchamati,让每个模块使用单元测试进行测试(就像之前一样)。单元测试很快,可以在每次构建时运行。
有一个单独的集成测试模块,其包装类型可以是pom; (你不会在这个项目中构建一个真正的可部署工件;而且,当测试数量开始增长时,将它转换为另一个聚合器pom可能是有意义的):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>myproject</artifactId>
<groupId>com.mycompany</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.myproject</groupId>
<artifactId>myproject-integration-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
遵循Maven约定,集成测试应该进入src/it
:
<build>
<testSourceDirectory>src/it</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
<executions>
<execution>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
使用failsafe运行集成测试:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.17</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.17</version>
</dependency>
</dependencies>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
让您的集成测试项目导入耳朵项目依赖项(以及您需要的所有其他内容)。我不确定这是否被认为是好的做法,因为它没有在任何指南中提及,但它对我来说效果很好。
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-project-ear</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
</dependency>
在集成测试模块中集中arquillian相关配置:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>${arquillian.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<version>${arquillian.version}</version>
<scope>test</scope>
</dependency>
<!-- Arquillian container related dependencies, etc -->
关注failsafe naming conventions测试文件。
src/it/java
com/mycompany/myproject
mypackage
MyIT.java
MySecondIT.java
anotherpackage
YetAnotherIT.java
<强>利润强>
在顶级聚合器项目下:
mvn test
⇒运行充满嘲笑的快速单元测试mvn verify
⇒运行真正的集成/功能/验收测试(可能很慢) 额外提示:如果您正在运行CI服务器(例如Jenkins),请设置每晚构建以运行集成测试(即,进行构建调用mvn verify
)。不要将未经验证的构建部署到认证或生产服务器。
答案 1 :(得分:2)
我曾经遇到过同样的问题,这更多的是建筑问题,CBD(基于组件的开发)。由于你有子模块,我更喜欢调用组件,他们应该测试自己(单元测试),它们之间的依赖关系不应该是循环的。共享配置,以避免重复,可以是一个称为垂直组件的分离组件(在许多组件之间共享,更多地分类为“util组件”而不是“业务组件”)。报告组件通常不依赖于它们,而是EAR,它是“最终节点”,因此报告组件将取决于许多组件。
我不确定我是否回答了您的需求,但在我看来,这是您遇到问题的根本原因,我曾经面对并重新设计了组件依赖树。
我对Arquillian帮不了多少,但CBD的概念是组件(子模块)是自给自足的,他们必须做他们需要做的一切,甚至是测试和模拟数据。您必须找到解决此体系结构问题的方法,例如,Maven Dashboard可能可以帮助您统一和分析测试结果,查看maven-dashboard甚至sonar。
在这里绘制树是没用的,因为它不会显示依赖树,之前用于绘制它的m2-eclipse插件但它们删除了功能,有多糟糕。然而,在设计CBD时忘记了技术。 EAR没有模块,如果不是严格必要的话,它可能是一个技术障碍。通常,EAR依赖于WAR,WAR取决于依赖于其他JAR的JAR - 每个JAR都是一个组件。
根据您给出的第一个示例,共享库是一个垂直组件,它不依赖于您的任何模块,我不确定您所选择的技术/框架,但使用Spring我们可以轻松共享组件之间的配置文件(垂直组件,如“基本测试”组件,例如,可以提供类以简化配置和测试实现)。继续该示例,子模块2 可能依赖于子模块1 ,在这种情况下, submodule1 将拥有自己的测试和模拟; submodule2 将有自己的测试和模拟,当使用 submodule1 时,将提供模拟数据。
也许你已经知道,但我推荐两本书:(1)Eric Evans的经典“领域驱动设计:解决软件中心的复杂性”; (2)John Cheesman和John Daniels(作者)的“UML组件:指定基于组件的软件的简单过程”。