Cucumber tests not running Liquibase - java

Liquibase does not run when I execute my Cucumber tests, although works fine for application and unit tests.
I have a suite of cucumber-spring tests, testing a spring-boot application.
I have recently introduced Liquibase to the application, which runs fine when I run the application or the unit tests, but does not get run when I run my cucumber tests, either from a RunCukesTest Junit class or from the cucumber-cli.
The correct application.properties files get loaded in all cases, and I do nothing special to get Liquibase to run in the standard application and tests. It is enabled by default, and I have tried forcing enabled, but with no luck.
I have tried setting a SpringLiquibase bean in the tests, but cucumber-spring does not like this, as it does not allow further #Configuration classes.
The Liquibase jar is available on the classpath, and referencing a Liquibase type compiles fine in the cucumber steps.
The only property I set is :
spring.liquibase.change-log=classpath:db/changelog/db.changelog-master.xml
My Cucumber test class has the signature:
#Ignore
#SpringBootTest(classes = {Application.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
public class SpringConfig extends SpringBootBaseIntegrationTest implements En {
in application.properties. I have tried setting this for Cucumber application.properties also with no change.
Liquibase should run my changelog files as per standard application launch.

Related

Disable spring boot all together when running maven test

I have some unit test classes in my project that I want to test with mvn test. But whenever I run the command an instance of spring boot starts and opens database connections.
I´m running these tests in a server that doesn´t have access to a database, and none of my tests uses one. I just one to execute the tests as the IDE does.
I think one of them could help you
1 - Disable all tests
mvn clean install -DskipTests
2 - Prepare your test for switching
#ExtendWith(SpringExtension.class)
#EnabledIf(expression = "${tests.spring.enabled:true}")
if you pass -Dtests.spring.enabled= false or true will disable test
3 - Point your test to other configuration
#ExtendWith(SpringExtension.class)
#TestPropertySource(locations = "classpath:application-${spring.profiles.active:test}.properties")
this way you could connect your application into a local database
4 - Change your tests
Use mocks to turn your integration tests into a unit tests or component tests with no connections
The problem I had was an empty class with #SpringBootTest annotation. After deleting it the tests works without spring interfering.

Spring boot integration test with environment variables

I'm working on a multi-module maven project using Java 8, Spring Boot 2.4.0. I want to test one of a module that is calling a 3rd party service. I'm using wiremock to mock that 3rd party service call and have created a spring boot integration test class. My class is in the same package where my XYZService class is. My test is in src/test/... and looks like this.
#RunWith(SpringRunner.class)
#SpringBootTest(classes = SpringApplicationClassWithMainMethod.class)
public class XYZServiceIntegrationTest {
#Rule
public WireMockRule externalService = new WireMockRule();
#Test
public void test1() {...}
#Test
public void test2() {...}
}
When I run the maven build in my eclipse (clean + install). My build is not detecting the tests present at the maven-module where the Integration test is located. The other unit tests in the same module are also not being detected (Note: before adding the integration test class, the unit tests were working). Maven says Tests ran: 0. The integration test is working fine when I Right click on the file and run as JUnit test(Junit 4). Also, I have some environment variables that need to be set for running the SpringApplicationClassWithMainMethod.class that I'm setting within the configurations of that Integration test class in order to successfully load the Application context(I tried to load the environment variables through code and nothing from other stack-overflow posts worked). One more thing to inform my maven only uses Maven surefire plugin for running tests. I dont know if we need to have Maven fail safe plugin for my purpose(Is my test considered a Integration Test when I added the 2 annotations on top of the test class?). Can someone please help me with any suggestions on how to build the parent project.
Adding the maven-failsafe-plugin into my child pom worked. In the parent pom I added the execution goals for maven-failsafe-plugin in the and in the child pom I inherited that plugin.

Switch Spring annotations depends on active profile

I have the following configuration for Spock class which is responsible for running integration tests.
#ContextConfiguration(classes = AccountService.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#Sql(executionPhase= Sql.ExecutionPhase.BEFORE_TEST_METHOD,scripts="classpath:/integration-tests/clear-tables.sql")
#AutoConfigureEmbeddedDatabase
class AccountControllerIntegrationSpec extends Specification
{
.....
}
I have two profiles. The purpose is to active use set of annotations :
#AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
#Sql(executionPhase= Sql.ExecutionPhase.BEFORE_TEST_METHOD,scripts="classpath:/integration-tests/clear-tables.sql")
when I run docker-test profile.
When I run profile test I would like to use only #AutoConfigureEmbeddedDatabase (postgress embedded database for tests).
Profile test-docker should use real database from other container.
Profile test should use embedded database Postgress when I run tests locally on machine.
How can I configure during startup spring to choose databaseSource ?
When I add both annontations each time Embedded Postgres is only active even if test-docker profile is active I tried to set scope of dependency for embedded Postgres set differently for profiles. But it did not help.

Testng && Spring context unit test -> execute sql before and after test method

When using JUnit a SpringRunner, there is an awesome feature of executing scripts before and after any test method
#Test
#SqlGroup([
#Sql(scripts = ["classpath:clean_db.sql", "populate_data.sql"]),
#Sql(scripts = ["classpath:clean_db.sql"], executionPhase = AFTER_TEST_METHOD)
])
However, when using testngframework and running spring-context tests, this annotation doesn't work because testng uses AbstractTestNGSpringContextTests instead of SpringRunner
Is there any similar annotation in testng or any other util to execute scripts before and after tests?
Is there a reason why executing the script in the TestNG annotations #AfterTest or #AfterMethod (depending what you need) wouldn't work?
The first one would run after all the tests under a suite run, and the second, after each test method.

Spring integration test module running app from separate module without properties for DB config

Given a spring boot gradle module named "md-core" with a Spring application runner and a PostgresDbConfig to connect it to the DB.
The app runs perfectly fine and resolves the properties from the "application.yml" file in the #Config.
#Value("${db.default.pool.size}")
Integer maxPoolSize;
Now, a separate module called "integrationtests" tries to launch the Spring Boot Runner in the "md-core" module.
#ContextConfiguration(classes = {MdCore.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class GivenTest
The test launches the "md-core" Spring runner, but when trying to resolve the properties in the #Config, it does not find any properties.
I've tried directly resolving the "application.yml" in the test. It does not send the properties over to the "md-core" module. Any attempt of adding the "application.yml" properties in the test resolves them to the test file, but does not send them over when the "md-core" module is accessed.
Are there any definitions which should be given in the test via annotations or in the gradle build files?
The classpath when launching the test does not contain the "md-core" resources location, only the classes.
Could this be a reason? If yes, how can the resources be referenced in the classpath of the gradle build files?
I apologize for any mistakes or incomplete information, this post is being written at the end of a work day, hoping there will be answers by morning.
Given this situation, the solution to use the application.properties file for the integration test is the simple addition of initializers = ConfigFileApplicationContextInitializer.class in the #ContextConfiguration annotation of the Test class:
#ContextConfiguration(
initializers = ConfigFileApplicationContextInitializer.class,
classes = {SomeApp.class})
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
public class SomeIntegrationTest {
#Test
public void testTheIntegration() {
// some integration tests here
}
}
Answer also documented in a post on my blog and initially found less detailed on another stackoverflow question.

Categories

Resources