Reputation: 1903
I have a lot of integration tests and I have set up liquibase so that the database can be initialized. But each test class initializes a new initialization. In this case, duplicate data errors are unavoidable. I found a few recommendations to avoid this, but ran into a problem.
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<changeSet author="n" context="test" id="1" runOnChange="false">
<sqlFile encoding="utf8" endDelimiter="\nGO" path="classpath:dump.sql" relativeToChangelogFile="false"/>
</changeSet>
</databaseChangeLog>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
<include file="xml/changelog-1.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
I have also written a configuration class .
In the package :
public class CleanUpDatabaseTestExecutionListener extends AbstractTestExecutionListener {
@Autowired
SpringLiquibase liquibase;
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
@Override
public void afterTestClass(TestContext testContext) throws Exception {
testContext.getApplicationContext()
.getAutowireCapableBeanFactory()
.autowireBean(this);
liquibase.afterPropertiesSet();
}
}
@Slf4j
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@TestExecutionListeners(listeners = {
DependencyInjectionTestExecutionListener.class,
TransactionalTestExecutionListener.class,
CleanUpDatabaseTestExecutionListener.class,
})
public abstract class AbstractTestcontainers extends ContainerConfig {
I get an error: liquibase.exception.MigrationFailedException: Migration failed for change set db/changelog/test/liquibase-initdb.xml::1::n: Reason: liquibase.exception.DatabaseException: ERROR: type "calc_types" already exists [Failed SQL: (0) -- -- PostgreSQL database dump
spring.liquibase.drop-first=true - It doesn't work.
Maybe who know how can i correct this ?
Upvotes: 3
Views: 22082
Reputation: 1903
At the moment, I did this
@Slf4j
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public abstract class AbstractTestcontainers extends ContainerConfig{
@DynamicPropertySource
private static void dynamicProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", postgreSQLContainer::getJdbcUrl);
registry.add("spring.datasource.username", postgreSQLContainer::getUsername);
registry.add("spring.datasource.password", postgreSQLContainer::getPassword);
}
}
I had to give up on:
@DirtiesContext(classMode = ClassMode.BEFORE_CLASS)
public abstract class ContainerConfig {
protected static final PostgreSQLContainer postgreSQLContainer;
static {
DockerImageName postgres = DockerImageName.parse("postgres:11.7");
postgreSQLContainer = (PostgreSQLContainer) new PostgreSQLContainer(postgres)
.withDatabaseName("test")
.withPassword("root")
.withUsername("root")
.withReuse(true);
postgreSQLContainer.start();
}
}
I had to leave over some classes
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:createUsers.sql")
public class SomeClassRestTest extends AbstractTestcontainers {
to clear the tables and fill them with new data.
Liquibase configuration is run once, I at least didn't see any more conflicts. Since we have made one class that raises the context and all the other integration tests are performed using this context. Of course, the test classes themselves are incorrectly made, there it was necessary, using the @AfterClass or @AfterMethod annotations, to clear data from the databases. But nevertheless, now the execution of about 300 tests has been reduced by about 4 times.
If there are other solutions to this problem, please write.
Upvotes: 0