我有很多集成测试,并且我已经设置了liquibase,以便可以初始化数据库。但每个测试类都会初始化一个新的初始化。在这种情况下,重复数据错误是不可避免的。我找到了一些避免这种情况的建议,但遇到了问题。
<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>
我还写了一个配置类。
包装内:
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 {
我收到错误:liquibase.exception.MigrationFailedException: 更改集迁移失败 db/changelog/test/liquibase-initdb.xml::1::n: 原因:liquibase.exception.DatabaseException:错误:类型“calc_types”已存在 [失败的 SQL:(0) -- -- PostgreSQL 数据库转储
spring.liquibase.drop-first=true - 它不起作用。
也许谁知道我该如何纠正这个问题?
此刻,我就是这样做的
@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);
}
}
我不得不放弃:
@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();
}
}
我不得不离开一些课程
@Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:createUsers.sql")
public class SomeClassRestTest extends AbstractTestcontainers {
清除表格并用新数据填充表格。
Liquibase配置运行一次,我至少没有看到任何更多的冲突。由于我们创建了一个引发上下文的类,并且所有其他集成测试都是使用此上下文执行的。当然,测试类本身是错误的,因此有必要使用 @AfterClass 或 @AfterMethod 注释来清除数据库中的数据。但尽管如此,现在大约 300 个测试的执行量已经减少了大约 4 倍。
如果此问题还有其他解决方案,请写信。