使用Docker进行集成测试后恢复数据库状态?

时间:2016-10-17 17:41:38

标签: postgresql docker integration-testing

我们正在使用PostgreSQL以及部署到JBoss的EAR。在构建过程中,我们有一个开发数据库转储,然后在集成测试中使用:部署了特殊工件,测试使用http客户端与应用程序通信。

目前,测试运行期间数据库状态发生了变化,因此我们无法为每个修改它的测试添加其他内容,因此没有测试会相互依赖。这需要很多时间和耐心,因为这样的测试甚至取决于记录的顺序。

有没有办法制作数据库的快照,以便在每次测试运行后使用合理数量的资源恢复它? Docker可以提供帮助吗?或者其他任何方式?

H2不是这样的,因为我们使用了一些PostgreSQL特有的功能。测试可能跨越多个事务,因此我认为回滚也无济于事。

3 个答案:

答案 0 :(得分:2)

Docker的一个简单方法是将数据库快照作为重置的卷,然后安装到测试运行的开头。

您可以在运行测试之前按下这些数据(要么具有整个起始数据库配置的tar或其他内容),然后启动PostgreSQL测试数据库,测试数据作为卷安装,PostgreSQL指向此,每次测试。

答案 1 :(得分:1)

一种选择是在每次集成测试完成后重新播种数据。 Spring通过SqlScriptsTestExecutionListener@Sql注释提供此类功能。我知道你提到了EARJBoss,所以如果没有使用Spring,我相信Arquillian可能会提供类似内容。

如果由于用于集成测试的数据量而导致重新播种数据库成为一项昂贵的操作,另一种选择是使用已包含数据库和种子数据的Docker映像。您需要在执行每个集成测试之前启动DB with data容器,并在完成后停止,换句话说,您需要在集成测试期间管理容器生命周期。我在几个月前写了一篇关于如何实现这一点的博客:Integration Testing using Spring Boot, Postgres and Docker,再次使用Spring Boot,但这些想法可以与其他框架一起使用。它包括使用导入的数据创建Docker图像,从现有模式生成JPA个实体,在执行每个测试之前和之后添加对集成测试的支持以启动/停止容器,并且可以轻松扩展每次测试启动多个容器或同时执行它们,因为Docker容器映射到主机随机端口。

此时它是妥协,从知道状态(恕我直言,正确的方法)开始每个测试,代价是重新播种数据或启动/停止每个单独测试的容器或运行测试按特定顺序,只需在执行测试套件之前重新播种数据。

答案 2 :(得分:0)

You can do this by cloning the initial database and dropping the newly created test database after the test. When using the original database as a "TEMPLATE" this will probably only take milliseconds.

// FIXTURES // Create "initial_database" before all tests are run and load fixtures etc.

// TEST SETUP BEFORE EACH TEST CREATE DATABASE some_test_database_name TEMPLATE "initial_database";

// TEST TEARDOWN AFTER EACH TEST DROP DATABASE some_test_database_name;