在Maven多模块项目中使用客户端服务器应用程序进行集成测试

时间:2015-06-08 12:44:09

标签: maven jenkins continuous-integration jetty

我有一个由几个使用maven的模块组成的项目,并自动上传并部署到运行构建及其测试的Jenkins应用程序。

例如,有一个API模块,一个服务器和一个客户端。

客户端和服务器都使用API​​作为依赖关系才能正常工作。 客户端在正常使用中通过HTTP连接到服务器的Web服务。

为了能够运行,服务器需要在Jetty上运行。

我通过使用模拟的HTTP请求调用服务器的功能来进行单元测试,并测试客户端。

我希望能够进行一些集成测试,例如测试2个实体之间的HTTP(和HTTPS)连接,测试超时等,并在不诉诸模拟请求的情况下重现单元测试,更接近真实用例。

似乎这样的事情应该很容易做到,但我找不到一种方法来简单地以可自动化的方式来做。

例如,在我的IDE中手动测试是通过单击服务器项目上的“run war”和在我的应用程序上“运行测试”来完成的。

有没有办法在Jenkins中重现这个简单的过程,所以它是由Maven配置甚至是Jenkins插件自动完成的?

更新:

我正在尝试制作另一个模块,该模块将使用我的服务器打包产生的战争,并使用Jetty运行它。 由于我的服务器的Jetty配置相当复杂,使用由Maven过滤的Spring和https配置,因为缺少类和相关路径在该上下文中不起作用,我在新模块中工作时遇到了一些问题。

是否有可能在不跳过重复资源和其他肮脏技巧的情况下,像在其他模块中启动一样进行战争?

有关信息,我的pom.xml中特定的Jetty war部分是:

<configuration>
                    <contextHandlers>
                        <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
                            <war>${project.parent.basedir}/cmp-service/cmp-webapp/target/cmp-webapp-1.0-SNAPSHOT.war</war>
                            <contextPath>/cmp</contextPath>
                            <persistTempDirectory>true</persistTempDirectory>
                            <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                        </contextHandler>
                    </contextHandlers>
</configuration>

更新2:

我设法构建了一个正常运行的模块,它启动了jetty并使用这个pom.xml运行我的集成测试。

<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/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>parent</artifactId>
        <groupId>com.project.test</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.project.test.integration-testing</groupId>

    <artifactId>integration-testing</artifactId>
    <packaging>jar</packaging>

    <name>integration-testing</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.3.0.M2</version>
                <configuration>
                    <contextHandlers>
                        <contextHandler implementation="org.eclipse.jetty.webapp.WebAppContext">
                            <war>
                                ${project.parent.basedir}/myserver/myservice/target/myservice-${project.parent.version}.war
                            </war>
                            <contextPath>/cmp</contextPath>
                            <persistTempDirectory>true</persistTempDirectory>
                            <allowDuplicateFragmentNames>true</allowDuplicateFragmentNames>
                        </contextHandler>
                    </contextHandlers>

                    <contextXml>
                        ${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-context.xml
                    </contextXml>
                    <jettyXml>
                        ${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-ssl.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-http.xml,${project.parent.basedir}/myserver/myservice/src/test/resources/jetty/jetty-https.xml
                    </jettyXml>
                    <systemProperties>
                        <systemProperty>
                            <name>scsf.configuration.file</name>
                            <value>
                                ${project.parent.basedir}/myserver/myservice/src/main/resources/config/cmpserver.properties
                            </value>
                        </systemProperty>
                        <systemProperty>
                            <name>org.eclipse.jetty.annotations.maxWait</name>
                            <value>180</value>
                        </systemProperty>
                    </systemProperties>
                    <systemPropertiesFile>
                        ${project.parent.basedir}/myserver/myservice/src/main/resources/config/cmpserver.properties
                    </systemPropertiesFile>
                    <daemon>true</daemon>

                    <stopKey>STOP</stopKey>
                    <stopPort>10001</stopPort>
                </configuration>
                <executions>
                    <execution>
                        <id>start-jetty</id>
                        <phase>pre-integration-test</phase>
                        <goals>
                            <goal>start</goal>
                        </goals>
                        <configuration>
                            <scanIntervalSeconds>0</scanIntervalSeconds>
                        </configuration>
                    </execution>
                    <execution>
                        <id>stop-jetty</id>
                        <phase>post-integration-test</phase>
                        <goals>
                            <goal>stop</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <skipTests>true</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>2.18.1</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
       ...
    </dependencies>
</project>

您还需要按照提供的方式为战争添加依赖项。

但是(总有一个但是)运行验证目标时出现问题。 当我在我的集​​成测试模块中运行验证时,它有点工作。 但是,当我在父级中运行验证目标时,它应该调用我的集成测试模块的完全相同的验证目标(如果我正确理解它是如何工作的),则会对某些路径进行不同的处理并将其解析为,例如, parent / src / ...而不是parent / integration-test / src ...

似乎从父级运行我的目标时,执行的上下文会发生变化,导致我的应用程序在查找资源时会中断。

是否有一些我不明白整个过程如何运作的东西,是否有办法让它发挥作用?

更新3

我已决定破解我的所有路径,使其成为绝对路径,它有效,但它并不能解释这种行为。

2 个答案:

答案 0 :(得分:1)

您已经自己想出了基本步骤:

一位专业开发人员Stephen Connolly已经在stackoverflow上写了一篇关于这个主题的great answer

我不太了解jetty-maven-plugin,但它似乎不支持部署现有工件。指定相对路径或绝对路径绝对不是这里的方法。您应该使用货物代替部署到码头。货物配置可能如下所示:

<configuration>
  <configuration>
    <type>runtime</type>
    <properties>
      <cargo.hostname>testserver</cargo.hostname>
      <cargo.servlet.port>8080</cargo.servlet.port>
    </properties>
  </configuration>
  <container>
    <containerId>jetty9x</containerId>
  </container>
  <deployables>
    <deployable>
      <groupId>your.group.id</groupId>
      <artifactId>your-war</artifactId>
      <type>war</type>
      <properties>
        <context>/cmp</context>
      </properties>
    </deployable>
  </deployables>
  <deployer>
    <type>remote</type>
  </deployer>
</configuration>

cargo documentation有更多详情。

HTH,
- 马丁

答案 1 :(得分:0)

enter image description here

Hello Jay,

真的想简化这里的事情,为什么不连续经营这些工作?首先是使用Maven进行编译,单元测试和部署任务。对于集成测试,创建另一个使用Selenium(用于Web应用程序)和JMeter(用于Web服务)等插件的作业。您还可以尝试其他许可证测试套件,如Openscript。

Web服务测试将非常棘手,因为您的Web服务使用者在另一个客户端上运行。您是否在客户端应用程序上运行任何从属代理?如果您有,请在奴隶中运行这些工作。