Maven文件夹布局:我应该在EAR或其子模块中放置测试吗?

时间:2014-07-01 19:24:13

标签: java maven module integration-testing jboss-arquillian

我们有一个包含多个子模块的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等)?

2 个答案:

答案 0 :(得分:7)

让我提供一些关于如何使用Maven组织集成测试的实用信息,以便其他人可以使用它来做正确的事情。

我最终接受了来自梦幻般的(即使有点旧)Better Builds with Maven以及Codehaus Maven and Integration Testing Guide的建议。

  1. 使用聚合器顶级项目:

    myproject
        myproject-ear
        myproject-war
        myproject-ejb
        ...
        myproject-integration-tests
    
  2. 作为suggested by mchamati,让每个模块使用单元测试进行测试(就像之前一样)。单元测试很快,可以在每次构建时运行。

  3. 同样对于单元测试,事实证明我最初的策略并不是那么糟糕。我仍然有几个模拟模块绑定到EAR作为托管依赖项。
  4. 有一个单独的集成测试模块,其包装类型可以是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>
    
  5. 遵循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> 
    
  6. 使用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>
    
  7. 让您的集成测试项目导入耳朵项目依赖项(以及您需要的所有其他内容)。我不确定这是否被认为是好的做法,因为它没有在任何指南中提及,但它对我来说效果很好。

    <dependency>
        <groupId>com.mycompany</groupId>
        <artifactId>my-project-ear</artifactId>
        <version>1.0-SNAPSHOT</version>
        <type>pom</type>
    </dependency>
    
  8. 在集成测试模块中集中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 -->
    
  9. 关注failsafe naming conventions测试文件。

    src/it/java
        com/mycompany/myproject
            mypackage
                MyIT.java 
                MySecondIT.java
            anotherpackage
                YetAnotherIT.java  
    
  10. <强>利润

    在顶级聚合器项目下:

    1. mvn test⇒运行充满嘲笑的快速单元测试
    2. mvn verify⇒运行真正的集成/功能/验收测试(可能很慢)

  11. 额外提示:如果您正在运行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组件:指定基于组件的软件的简单过程”。