Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

End to end integration test for multiple spring boot applications under Maven

Tags:

What is the recommended way of running an end to end integration test for multiple Spring boot applications in the Maven build's verify phase?

Basically, I have a multi-module Maven project where several modules are separate spring boot applications. These separate applications have their own configuration for data sources, integration flows with JMS queues, etc. For example, application A will poll a database for an event, and when that occurs, it produces a JSON file of data and puts a message on a JMS queue. Application B is polling the JMS queue, so picks up the message, reads the file, does some processing using another database, and puts a message on a different queue. Application C will then pick up that message, etc, etc.

I have set up integration tests for the individual applications; these run under the Maven failsafe plugin. However, I would like to integration test the whole system, end to end, under Maven. I have set up a separate module in the project dedicated to this task, and so would like the verify build phase of this module to do the end to end testing using the other dependent modules.

Is there a best practice way of doing this? I see 3 potential ways:

  1. Load each application's configuration into the same application context. However, because of multiple data sources etc, this creates conflicts, and so these data sources would all have to be manually configured just to enable end to end integration testing - so this seems wrong to me.
  2. Launch each application as a separate process - how then to properly keep track of them and make sure they get shut down if the test module build stops/crashes/etc?
  3. Is there a way to easily load separate spring boot applications, each with its own configuration context, in the same process? This would seem to be the most sensible option. Are there any considerations in respect of the Maven build/failsafe plugin?
like image 828
Gary Sedgwick Avatar asked Nov 23 '15 14:11

Gary Sedgwick


People also ask

How do I run an integration test in Maven?

The simplest way to run integration tests is to use the Maven failsafe plugin. By default, the Maven surefire plugin executes unit tests during the test phase, while the failsafe plugin runs integration tests in the integration-test phase.

How do I run an integration test in spring boot?

As explained above, for integrating testing of a spring-boot application, we need to use @SpringBootTest. spring-boot also does provide other classes like TestRestTemplate to test the REST APIs. Like RestTemplate class, it also does have methods getForObject(), postForObject(), exchange(), etc..

What is the difference between integration testing and end to end testing?

In this case, integration tests work like a health check that identifies pain points to address. As for E2E testing, it is a testing type that automatically simulates user experience when working with the tool relying on the so-called user stories.

What is unit testing and integration testing in spring boot?

Unit tests run in isolation while integration tests bootstrap the Spring web context before execution starts. UNIT TESTS. Running in isolation will sometimes require that you mock your dependencies based on the class you are testing.


1 Answers

Just to follow-up and say what I ended up doing (which is continuing to work well):

  • I created the following Maven profiles in my testing module: "default" to skip tests by default (we use jgitflow plugin so only want end-to-end tests run when explicitly requested), "standalone-e2e" for end-to-end tests not requiring external resources such as databases (aimed at developers wanting to do a full end-to-end test), and "integrated-e2e" for end-to-end tests using real databases etc (which can get triggered as part of CI). Spring profiles (activated by the corresponding Maven profile) control the configuration of the individual components.
  • For standalone-e2e, relevant plugins such as activemq-maven-plugin, hsqldb-maven-plugin etc. launch (and later shut down) resources as part of the end-to-end test, running on ports reserved with build-helper-maven-plugin. The process-exec-maven-plugin is used to launch all the components to be tested in the pre-integration-test phase (as standard Spring Boot apps), and it automatically takes care of shutting them down in the post-integration-test phase. Spring configuration and specific Maven test dependencies take care of other resources such as a fake FTP server. After all resources and components are running, the test code itself then populates the database and file system as required and triggers flows (and waits for corresponding replies etc) using JMS.
  • The integrated-e2e profile is almost identical but uses "real" external resources (in our case, Amazon SQS queues, MySQL database, etc) configured in the associated Spring properties.
  • All files needed for and generated by the tests (e.g. data files, HSQLDB files, log files, etc) are created under the "target" build directory, so it's easy to inspect this area to see what happened during the test, and also allow "mvn clean" to clear out everything.

I hope that's useful - it was certainly refreshing to find that whatever I needed to do, a Maven plugin existed to take care of it!

like image 51
Gary Sedgwick Avatar answered Oct 21 '22 12:10

Gary Sedgwick