Maven下多个spring引导应用程序的端到端集成测试

Maven下多个spring引导应用程序的端到端集成测试,maven,spring-boot,integration-testing,multi-module,end-to-end,Maven,Spring Boot,Integration Testing,Multi Module,End To End,在Mavenbuild的验证阶段,为多个Springboot应用程序运行端到端集成测试的推荐方法是什么 基本上,我有一个多模块Maven项目,其中几个模块是独立的spring boot应用程序。这些独立的应用程序有自己的数据源配置、与JMS队列的集成流等。例如,应用程序A将轮询数据库中的事件,当事件发生时,它生成一个JSON数据文件,并将一条消息放在JMS队列上。应用程序B正在轮询JMS队列,因此会拾取消息,读取文件,使用另一个数据库进行一些处理,并将消息放在不同的队列中。然后应用程序C将接收该

Maven
build的验证阶段,为多个
Spring
boot应用程序运行端到端集成测试的推荐方法是什么

基本上,我有一个多模块Maven项目,其中几个模块是独立的spring boot应用程序。这些独立的应用程序有自己的数据源配置、与
JMS
队列的集成流等。例如,应用程序A将轮询数据库中的事件,当事件发生时,它生成一个
JSON
数据文件,并将一条消息放在
JMS
队列上。应用程序B正在轮询
JMS
队列,因此会拾取消息,读取文件,使用另一个数据库进行一些处理,并将消息放在不同的队列中。然后应用程序C将接收该消息,等等

我已经为各个应用程序设置了集成测试;它们在Maven故障保护插件下运行。然而,我想在Maven下对整个系统进行端到端的集成测试。我在项目中专门为此任务设置了一个单独的模块,因此希望该模块的验证构建阶段使用其他相关模块进行端到端测试

有没有一种最佳实践方法可以做到这一点?我看到了3种可能的方法:

  • 将每个应用程序的配置加载到相同的应用程序上下文中。但是,由于多个数据源等原因,这会产生冲突,因此这些数据源都必须手动配置,以便启用端到端集成测试,因此我认为这是错误的
  • 将每个应用程序作为一个单独的过程启动-然后如何正确跟踪它们,并确保它们在测试模块构建停止/崩溃等情况下关闭
  • 有没有一种方法可以在同一个过程中轻松加载单独的spring引导应用程序,每个应用程序都有自己的配置上下文?这似乎是最明智的选择。对于
    Maven
    build/failsafe插件,是否有任何注意事项

  • 很好的问题!我自己会对别人的回答感兴趣。我将分享我的观点

    根据我的理解,首先你应该知道你到底想测试什么。 集成测试应该与的应用程序一起工作,至少与其中的一部分一起工作,并确保您开发的组件在半真实环境中正常工作。看来你已经这么做了

    现在,关于系统测试(我有意区分集成测试和系统测试)。他们应该“模仿”QA人员:)所以,他们将系统视为一个黑匣子。它们不能调用任何内部API并运行真正的流。 端到端测试属于这一类

    在本例中,您希望对照在生产环境中部署的系统检查它们,并在生产环境中使用类路径检查它们

    所以我和你一样,并不真的相信选项1

    关于选项3,我不确定它是否也是一个好的解决方案。 即使您在不同的应用程序上下文中运行您的东西(我不太了解Spring boot,所以我不能从技术上对其进行评论),据我所知,它们在运行时将共享相同的类路径,因此您可能有可能在第三方之间发生冲突(虽然我知道spring boot本身定义了很多JAR版本,但您知道我的意思)特别是当您只升级一个模块并且可能更改依赖项时。 所以,当您按照这种方法运行时,您并不知道内存中到底运行了什么

    因此,对于端到端的测试,我会选择选项2。 关于同步,可能的选择是在应用程序级别实现一些逻辑,同时在操作系统级别实现进程状态跟踪。 我想评论的另一点是,端到端测试通常仍然是功能测试(它们检查系统的功能行为),因此一般来说,您不应该在每个测试中检查系统崩溃。如果您检查每个流的系统崩溃,这些测试将太慢。 当然,您可以维护一个相对较小的测试套件来检查这样的情况


    希望这有助于跟进并说明我最终做了什么(这项工作仍在顺利进行):

    • 我在我的测试模块中创建了以下Maven配置文件:“default”默认跳过测试(我们使用插件,因此只希望在明确请求时运行端到端测试),“standalone-e2e”用于不需要外部资源的端到端测试,如数据库(针对希望进行完整端到端测试的开发人员)和“integrated-e2e”对于使用真实数据库等的端到端测试(可以作为CI的一部分触发)。Spring配置文件(由相应的Maven配置文件激活)控制单个组件的配置
    • 对于standalone-e2e,相关插件(如等)作为端到端测试的一部分启动(稍后关闭)资源,在保留的端口上运行。用于启动所有要在预集成测试阶段测试的组件(作为标准Spring引导应用程序),它会在集成后测试阶段自动关闭它们。Spring配置和特定的Maven测试依赖关系会处理其他资源,例如。在所有资源和组件运行后,测试代码本身会根据需要填充数据库和文件系统,并触发流(并等待相应的回复等)使用JMS
    • integrated-e2e配置文件几乎相同,但使用在相关Spring属性中配置的“真实”外部资源(在我们的例子中,是amazonsqs队列、MySQL数据库等)
    • 测试所需和生成的所有文件(例如数据文件、HSQLDB文件、日志文件等)都是在“目标”构建目录下创建的,因此很容易检查该区域以查看w
      <build>
        ...
        <plugin>
          <!-- copy apps to current build-dir -->
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>3.1.2</version>
          <executions>
            <execution>
              <id>copy-app-A</id>
              <goals>
                <goal>copy</goal>
              </goals>
              <phase><!-- either pre-test or pre-integration-test --></phase>
              <configuration>
                <artifactItems>
                  <artifactItem>
                    <groupId>${project.groupId}</groupId>
                    <artifactId>app_a</artifactId>
                    <version>${project.version}</version>
                    <outputDirectory>${project.build.directory}</outputDirectory>
                    <destFileName>app_a.jar</destFileName>
                  </artifactItem>
                </artifactItems>
              </configuration>
            </execution>
            <execution><!-- repeat as many apps you have --></execution>
          </executions>
        </plugin>
        <plugin>
          <!-- start applications -->
          <groupId>com.bazaarvoice.maven.plugins</groupId>
          <artifactId>process-exec-maven-plugin</artifactId>
          <version>0.9</version>
          <executions>
            <execution>
              <!-- repeat 'start' block for each copied app -->
              <id>start-external-server</id>
              <phase><!-- same as in copy block --></phase>
              <goals>
                <goal>start</goal>
              </goals>
              <configuration>
                <name>run-app-A</name>
                <arguments>
                  <argument>java</argument>
                  <argument>-jar</argument>
                  <argument>${project.build.directory}/app_a.jar</argument>
                </arguments>
              </configuration>
            </execution>
            <execution>
              <!-- this is always executed and ensures apps get stopped -->
              <id>stop-server</id>
              <phase><!-- either post-test or post-integration-test depending on --></phase>
              <goals>
                <goal>stop-all</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        ...
      </build>