如何强制Flyway每次新增数据库迁移都配套对应版本测试数据脚本?
Flyway 主迁移脚本强制匹配测试数据脚本实现方案
核心思路
通过读取所有主迁移脚本和测试数据脚本的版本号,校验每一个主迁移版本都存在对应的[主版本号].1格式的测试数据版本,不存在则测试断言失败。
推荐直接使用Flyway自带的API读取迁移脚本信息,避免自行解析文件可能出现的规则适配错误。
具体代码实现
直接在原有的集成测试类中新增版本校验的测试方法即可,修改后的完整测试类如下:
@SpringBootTest @ActiveProfiles("test") @Import(FlywayCallback::class) class DatabaseMigrationScriptIntegrationTest { @Autowired private lateinit var strategy: FlywayMigrationConfig private val log = LogFactory.getLog(javaClass) // 可选:不需要配套测试数据的主版本白名单,按需添加 private val ignoredMainVersions = setOf<String>() @BeforeEach fun setUp() { strategy.cleanMigrateStrategy() } @Test fun `所有主迁移脚本都存在对应的测试数据脚本`() { val flyway = flywaySetup() // 获取所有识别到的迁移脚本 val allMigrations = flyway.info().all() // 区分主迁移脚本和测试数据脚本 val mainMigrationVersions = mutableSetOf<String>() val testDataMigrationVersions = mutableSetOf<String>() allMigrations.forEach { migration -> val scriptPath = migration.script if (scriptPath.startsWith("db/migration/afterEachMigrate")) { testDataMigrationVersions.add(migration.version.version) } else if (scriptPath.startsWith("db/migration")) { val mainVersion = migration.version.version if (!ignoredMainVersions.contains(mainVersion)) { mainMigrationVersions.add(mainVersion) } } } // 校验每个主版本都有对应的 x.1 测试数据版本 val missingTestVersions = mainMigrationVersions.filter { mainVer -> val expectedTestVer = "$mainVer.1" !testDataMigrationVersions.contains(expectedTestVer) } Assertions.assertThat(missingTestVersions) .withFailMessage("以下主迁移版本缺少对应的测试数据脚本:${missingTestVersions.joinToString(", ")}") .isEmpty() } @Test fun successfullyRunsMigrationsWithTestingData() { val configureFlyway = flywaySetup() val runMigrations = configureFlyway.migrate() Assertions.assertThat(runMigrations.migrationsExecuted).isGreaterThan(0) } private fun flywaySetup(): Flyway { return Flyway.configure() .dataSource("jdbc:tc:mysql://localhost:3306", "test", "test") .locations("classpath:db/migration", "classpath:db/migration/afterEachMigrate") .callbacks(FlywayCallback()) .load() } }
补充说明
- 代码中预留了
ignoredMainVersions白名单,如果你有部分特殊的主迁移脚本不需要配套测试数据,可以直接把版本号加入该集合跳过校验。 - 如果你不想依赖Flyway API做版本读取,也可以使用
PathMatchingResourcePatternResolver自行扫描两个目录下的SQL文件,通过正则匹配提取版本号做校验,逻辑完全一致。 - 校验测试会在迁移执行测试之前运行,只要存在未配套测试数据的主迁移脚本,测试会直接失败,阻断后续流程。
内容的提问来源于stack exchange,提问作者Farukh Khan
相关产品推荐
相关产品推荐

