Rollback Integration Test which uses cucumber and tests the application on embedded tomcat via maven - spring

I am trying to set up an integration test framework for my spring project using cucumber framework and selenium for UI automation.
What I have done till now is
Use tomcat7 plugin for maven and deploy my war file to this embedded tomcat
Use the cucumber feature file to specify any test cases, be it a rest service or for the UI automation
We need to use our existing development DB for test purposes
I will hit the app url for the application running on the embedded tomcat.
What I am unable to find out is, can we rollback a transaction automatically after the test is done?
I am able to rollback transactions from cucumber/junit that were directly using my DAO as the DB connection was initiated from the same spring context.
But when the invocations are made using this model, I am unable to find any idea to rollback the transactions after the tests are done.

Can you think of achieving your integration testing in terms of Spring profile? You can create a spring profile for integration test and use it as environment variable or using annotations to specify rollback for transaction.
Take a look at following references to get an idea:
Spring integration tests with profile
https://spring.io/blog/2011/06/21/spring-3-1-m2-testing-with-configuration-classes-and-profiles

Related

Spring integration test has different behaviour when started via IntelliJ run configuration and via mvn verify

I am working on the Spring application based on Spring Boot 2.6.7 (Spring framework version 5.3.19). I noticed that when I run the integration test via IntelliJ run configuration (basically created only by the right clicking on the test method name and choosing Run test) then the same instance of the ApplicationContext is used in the integration test class and in the actual SpringBootApplication which is tested by the integration test.
But when the same integration test is executed from the command line via mvn verify command, then the different instance of the ApplicationContext is active in the Spring Boot Application from the one which is active in the integration test class.
That for example has a consequence that spring data repository which I added as a field to the integration test class with #SpyBean annotation is not not applied in the Spring boot application. In the applicationContext of the integration test class, that spring data repository is registered as a spy but in the application context of the Spring Boot Application there is no spy proxy but the regular repository.
On the other hand when the test is running via IntelliJ run configuration, the applicationContext is same everywhere and the spy bean is active in the Spring Boot Application flow.
So I want to achieve the same behavior when I run mvn verify as I achieve when I run the test from IntelliJ. Any ideas?

Run external spring boot application as part of an integration test

Is it possible to run an external Spring boot application from an integration test? The basic idea is that I have a mock service that was developed for use in end to end testing and would like to be able to have the e2e integration test take care of starting up the service and shutting it down as part of the test.
I recommend you take a look at docker and the fabric8 maven plugin. This allows you to build container images that contain your application, start and stop instances of those containers as part of your integration test phases.

Using Spring Boot Configuration in a custom JUnit test runner that does not otherwise use Spring

I have a custom JUnit test runner that executes acceptance-level tests using a test specification format specific to my project. The system under test is using Spring Boot and takes advantage of its configuration facility. I'd like the tests to be able to read the same configuration files in the same way. Obviously, using Spring Boot Configuration itself is an answer.
I'd like to just use Spring Boot Configuration as a stand-alone library, but I'm willing to fire up Spring Boot if that's what it takes. I'm not in control of the top-level application - JUnit is. So, I don't know how to start Spring Boot when I get control inside my test runner.
I've looked at extending SpringJunit4ClassRunner but I can't keep it from looking for #Test annotations and failing when it doesn't find any. I've started to look into merging code from SpringJunit4ClassRunner into my custom runner. Before I go too far down that path, I'd appreciate input from the community.
It sounds like you simply want the application running for a standalone webservice testing. This can be done simply by scripting the "java -jar" command to run the spring boot application. However, I would question why you don't want to leverage the testing tools built into spring boot? You can fire up the entire spring boot application and write some very logical looking tests.
For example a rest api test case:
#Test
public void homePage() throwsException () {
mockMvc.perform(get("/readingList"))
.andExpect(status().isOk())
.andExpect(view().name("readingList"))
.andExpect((model().attribute("books", is(empty()))));
}

Is there Arquillian h2/database bootstrap support unrelated to JPA?

I'm using Arquillian for integration testing tomcat apps, and it works great for the web archive and configurations.
I'm also using the inmemdb-maven-plugin for H2 setup during the maven-failsafe verification/integration test run, that also works great.
But, Arquillian allows you to run the integration test as a unit test within the IDE (eclipse)...but this is where the breakdown occurs. I have DataSource test code checking the db values during the integration test runs, but since H2 isn't bootstrapped by Arquillian, it's not bootstrapped in the Eclipse IDE unit-test scenario (But works fine in command-line and jenkins land).
Any possible leads how to get H2 bootstrapped in a way that would work for Arquillian, unit-testing, and maven integration testing?

End to end test across multi Spring Boot applications

Currently in our project, we are using Spring Integration to integrate many service and some protocol related endpoints.
The project is a multi Spring Boot applications, more than one executable jars will be deployed in production.
The question is:
How to run an end to end test which needs to run cross some of these applications, I have to run the one by one manually? In before none-Spring-Boot applications, I can use Maven tomcat7 plugin to complete this work(deploy the wars into an embedded tomcat and run it in pre-integration-test phase), now how to start up all related applications before I run my test. Assume I do not use Docker/Vagrant now.
Similar question found on stackoverflow, End to end integration test for multiple spring boot applications under Maven
How to run the end2end test automatically?
In an Spring Integration test, sometime I have to mock a http endpoint, so I wrote a simple Controller in test package to archive this purpose, but I want to run it at a different port, which make it more like an outside resource. How to run different #SpringBootApplicaiton classes at varied ports at the same time in the test for this purpose?
I am using the latest Maven, Java 8, Spring Boot 1.3.1.RELEASE.
Actually, Spring Boot comes with the embedded Servlet Container support. One of them is exactly Tomcat. The default on for the org.springframework.boot:spring-boot-starter-web.
With the org.springframework.boot:spring-boot-starter-test and its #SpringApplicationConfiguration and #WebIntegrationTest you can achieve your requirements, even with the random port.
Please, refer to the Spring Boot Reference Manual for more information:
To change the port you can add environment properties to #WebIntegrationTest as colon- or equals-separated name-value pairs, e.g. #WebIntegrationTest("server.port:9000"). Additionally you can set the server.port and management.port properties to 0 in order to run your integration tests using random ports.
With that your #SpringBootApplicaiton will be deployed to that embedded Tomcat and your test can get access to the ran services/controllers.
Note: it doesn't matter if your Spring Boot application has Spring Integration facilities. The behavior is the same: embedded Servlet Container and integration tests against #Value("${local.server.port}").

Resources