You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitLab CI/CD流水线中Micronaut测试数据跨测试残留问题

解决GitLab CI中Micronaut测试数据库数据残留问题

问题根源

你的测试类都设置了@MicronautTest(transactional = false),且使用@TestInstance(TestInstance.Lifecycle.PER_CLASS)模式,这导致:

  • 测试方法的数据库操作不会自动回滚
  • 测试类实例复用,多个测试方法共享同一状态
  • GitLab CI中所有测试共享同一个Postgres服务实例,Test1插入的数据会残留到Test2的执行环境中,触发断言失败

可行解决方案

1. 启用事务自动回滚(优先推荐)

去掉@MicronautTest的transactional = false参数(默认即为true),让每个测试方法执行后自动回滚事务:

@Slf4j
@MicronautTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Text1 {
    // 原有代码保持不变
}

注意:如果测试中使用HttpClient调用外部接口(如Test1的POST请求),由于HTTP请求在事务上下文外执行,自动回滚可能不生效,需要结合其他清理方式。

2. 测试前后手动清理数据库

在每个测试类的初始化或销毁阶段清空相关表数据,确保测试环境干净:

@Slf4j
@MicronautTest(transactional = false)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class Text1 {
    @Inject
    ProductService productService;

    @BeforeAll
    void initTestData() {
        productService.deleteAll(); // 测试前清空产品表
    }

    @AfterAll
    void cleanTestData() {
        productService.deleteAll(); // 测试后清空产品表
    }

    // 原有测试方法
}

如果需要更高效的清理(比如关联表),可以直接用JDBC执行TRUNCATE语句:

@Inject
DataSource dataSource;

@BeforeAll
void clearTables() {
    try (Connection conn = dataSource.getConnection()) {
        conn.createStatement().execute("TRUNCATE TABLE product RESTART IDENTITY CASCADE");
    } catch (SQLException e) {
        log.error("清理产品表失败", e);
    }
}

3. CI阶段全局清理(辅助方案)

在GitLab CI的测试脚本中,添加测试前的数据库清理命令,确保所有测试启动时数据库初始状态干净:

test:
  # 原有配置保持不变
  script:
    - psql -h localhost -U test -d postgres -c "TRUNCATE TABLE product RESTART IDENTITY CASCADE;"
    - mvn clean test 

该方案仅能在所有测试开始前清理一次,无法解决测试类之间的数据残留,建议结合测试类内部的清理逻辑使用。

4. 为测试分配独立数据库(进阶方案)

通过动态生成数据库名,让每个测试类使用独立的数据库实例,彻底隔离测试数据。此方案需要调整测试代码动态获取数据库连接信息,适合数据隔离要求极高的场景。

内容的提问来源于stack exchange,提问作者Rafael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 12:53:01