Java 在集成测试之前启动主应用程序和测试应用程序

Java 在集成测试之前启动主应用程序和测试应用程序,java,maven,spring-boot,testing,server,Java,Maven,Spring Boot,Testing,Server,我有两个spring启动应用程序,一个在src/test中,另一个在src/main中。它们有各自的app.properties和各自的端口 我想做一个集成测试,在它运行之前,我想让它在maven中运行集成测试时启动这两个服务器。 到目前为止,使用前置和后置maven集成测试插件并没有帮助,我似乎无法在Spring Boot中以编程方式启动这两个插件 另外,我已经意识到集成测试不会连接到我的主应用程序,即使我用ActiveProfile和spring boot test指定它,它总是启动我的测试

我有两个spring启动应用程序,一个在src/test中,另一个在src/main中。它们有各自的app.properties和各自的端口

我想做一个集成测试,在它运行之前,我想让它在maven中运行集成测试时启动这两个服务器。 到目前为止,使用前置和后置maven集成测试插件并没有帮助,我似乎无法在Spring Boot中以编程方式启动这两个插件

另外,我已经意识到集成测试不会连接到我的主应用程序,即使我用ActiveProfile和spring boot test指定它,它总是启动我的测试应用程序

我的主应用程序:

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;


@SpringBootApplication
public class App 
{
    public static void main( String[] args )
    {
        new SpringApplicationBuilder(App.class)     
        .build()
        .run(args);
    }
}
我的测试应用程序:

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@SpringBootApplication
public class MockServerApp {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new SpringApplicationBuilder(MockServerApp.class)       
        .build()
        .run(args);

    }
}
我的集成测试

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.PropertySource;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

import com.nulogix.billing.App;
import com.nulogix.billing.mockserver.MockServerApp;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,classes = {App.class})

public class BillingMediatorIT {


        @Test
        public void testOne(){



            }
        }

My App.class连接到端口28433,My MockServerApp.class连接到端口9119

出于某种原因,我的测试仍然连接到MockServerApp.class,因为它使用端口9119


我该如何解决这个问题,并让它启动两个应用程序的预集成测试阶段。

问题本身有些地方看起来不对劲,我会尽力澄清

没有必要保留两个spring启动应用程序:一个在src/test中,另一个在src\main中。如果您确实需要使用两种不同的微服务,请至少使用两个maven模块:

  project
  |___ app1
  |      |__ src/main/java - app1 production code is here
  |      |__ src/test/java - app1 tests are here
  |      |__ pom.xml
  |___ app2      
  |      |__ src/main/java - app2 production code is here
  |      |__ src/test/java - app2 tests are here
  |      |__ pom.xml
  |__ pom.xml
现在,Spring boot在@SpringBootTest注释的帮助下,非常支持运行一个微服务,该注释基本上尝试模拟Spring boot微服务在测试中的启动,包括配置管理、组件扫描等。由于spring配置缓存特性,您可以在测试用例之间重用相同的应用程序上下文

通常,SpringUniverse中的集成测试测试一个特定的微服务,该微服务能够模拟它的一些bean,这些bean可以为外部组件提供集成点

但是,如果要运行2个应用程序,可能需要进行完整的系统测试,因为您要测试这些组件之间的交互。 这超出了spring本身的范围,它存在于一个JVM中,服务于一个进程应用程序

所以,假设每个测试都是为了一个明确的特定原因而进行的,首先,问问自己,你到底想测试什么

例如,如果您想测试application1的内部逻辑,可能根本不应该启动Application2。例如,如果app1通过HTTP/Rest与app2交互,那么您可能应该使用某种模拟服务器,如 或者,在mockito中模拟与该服务器交互的bean,或者使用 表示远程应用程序的内部Spring测试的模拟服务器

这是适用于大多数情况的方法

现在,如果您真的需要一个系统测试来检查可能涉及许多应用程序的业务流,那么请做好准备,有一天您必须创建另一个应用程序,然后测试将变得更加复杂。也许您应该考虑创建一个包含所有微服务的测试环境,并从那里运行测试套件。然后使用一些脚本自动创建环境,并运行此脚本来创建环境和在其上运行测试,然后删除环境。 您还需要关心所有数据库(如果有的话)、配置管理等等。 我建议在你的工作场所与Devops人员讨论这一点,他们可能会在这方面帮助你。你也可以和你的QA部门谈谈,询问项目的自动化,这可能是一项非常有趣的任务,通常每个公司都以自己的方式解决它

现在,如果您仍然需要从maven运行它,那么如何组织代码

我会将系统测试放在单独的模块中,因为它们实际上既不属于app1也不属于app2:

  project
  |___ app1
  |      |__ src/main/java - app1 production code is here
  |      |__ src/test/java - app1 tests are here
  |      |__ pom.xml
  |___ app2      
  |      |__ src/main/java - app2 production code is here
  |      |__ src/test/java - app2 tests are here
  |      |__ pom.xml
  |__ test-module
  |   |__pom.xml //depends on app1, app2
  |   |__ src/test/java - all system tests are here 
  |__ pom.xml
然后使此模块同时依赖于app1和app2,以便首先编译它们。 然后假设到maven构建这个模块时,app1和app2的工件已经准备好了

Maven的默认生命周期有一个概念,基本上就是您想要运行插件的钩子点。 例如,您可以创建一个脚本,该脚本将运行配置了端口的应用程序和所有应用程序,然后在预集成测试阶段运行该脚本
然后在maven failsafe插件的帮助下以集成测试的形式运行所有测试,您必须在测试的模块pom中配置该插件,然后在集成后测试阶段运行另一个脚本,该脚本将停止两个应用程序,没有主要外部依赖关系的测试,如运行数据库、运行应用程序等。。src/test不应包含另一个应用程序。在单个代码树中拥有共同依赖的应用程序的首选方法是拥有模块:app1/src/main、app1/src/test、app2/src/main和app2/src/test。这并不能回答您的问题,但没有任何答案能够处理从src/test启动应用程序的问题。你可以 se目标运行集成前测试和集成后测试目标,并让它们启动您需要的任何应用程序。然后,具有主要外部依赖关系的测试(例如运行那些应用程序)可以进入集成测试目标。