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

时间:2019-08-19 02:04:41

标签: java maven spring-boot testing server

我有两个spring boot app,一个在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(){



            }
        }

我的App.class连接到端口28433,我的MockServerApp.class连接到端口9119。

由于某些原因,我的测试仍连接到MockServerApp.class,因为它使用端口9119。

如何解决此问题并使它启动两个应用程序的集成前测试阶段。

1 个答案:

答案 0 :(得分:1)

问题本身看起来有些错误,我将尝试澄清

保留两个Spring Boot应用程序是没有意义的: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配置缓存功能,您可以在测试用例之间重用相同的应用程序上下文。

通常情况下,Spring Universe中的集成测试会测试一种特定的微服务,该服务具有模拟其某些bean的能力,这些bean可以为外部组件提供集成点。

但是,如果要运行2个应用程序,则可能需要完整的“系统测试”,因为您要测试这些组件之间的交互。 而且,这超出了spring本身的范围,spring本身只能驻留在一个JVM中并为一个进程(应用程序)服务。

因此,假设每次测试都是出于明确的特定原因进行的,那么首先,问问自己您到底想测试什么

例如,如果您想测试application1的内部逻辑,也许根本不应该启动application 2。例如,如果app1通过HTTP / Rest与app2交互,则也许您应该使用某种模拟服务器,例如wiremock 或者,以模拟方式模拟与该服务器交互的bean,或者使用 内部Spring Test的Mock服务器,它将代表远程应用程序like here for example

这是在大多数情况下有效的方法。

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

现在,如果您仍然需要从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的默认生命周期的概念为phases,这基本上就是您要运行插件的挂钩点。 因此,例如,您可以创建一个脚本,该脚本将运行两个应用程序(具有已配置的端口和所有内容),然后在pre-integration-test阶段运行该脚本 然后在必须在测试的模块pom中配置的maven-failsafe-plugin的帮助下,将所有测试作为集成测试运行,然后在post-integration-test阶段运行另一个脚本,该脚本将同时停止这两个应用程序