如何准备在内存替换中使用PostgreSQL的集成测试?

时间:2017-04-19 11:02:06

标签: postgresql testing spring-boot integration-testing in-memory-database

我了解到在集成测试中使用实际数据库可以显着减慢它们的速度。因此,我必须使用内存数据库,这可能会显着提高我的集成测试的速度。

我正在使用Springboot进行应用程序开发。如何配置PostgreSQL用于测试目的?内存数据库中是否有与PostgreSQL语法高度兼容的内容?

如果没有,我应该如何进行集成测试。

4 个答案:

答案 0 :(得分:3)

这个问题要求提出意见,但这里有:

如果要测试将使用PostgreSQL的应用程序,则必须使用PostgreSQL进行测试。 SQL方言和行为在不同的数据库管理系统之间变化太大。

如果您使用足够小的数据库以适应RAM,您可以非常快地制作PostgreSQL,这应该可以用于仅针对功能的集成测试,而不是整体性能。

答案 1 :(得分:3)

我对真实postgres的一些db测试每次需要10ms。我在每个测试中做了多次提交。这样:

要覆盖postgres-native功能,您需要相同的db(如您所见,h2和其他内存中的db不是很兼容)。 postgres没有内存模式。 对于功能测试,真实数据库本身并不比任何内存数据库慢得多。差异通常在于启动时间(对于postgres 9.6它的〜4s)。但是,如果您的测试生命周期是智能的,并且您可以将db启动次数降低到1或0(通过让开发db始终准备好),那么问题就会停止显着。

所以获得真正的postgres并正确设置其生命周期。有一些工具可以帮助您解决一些问题:

  1. testcontainers会帮助您提供 真正的数据库。

  2. dbunit - 将帮助您清理测试之间的数据

    缺点:

    • 创建和维护架构和数据需要做很多工作。特别是当您的项目处于密集开发阶段时。
    • 它是另一个抽象层,所以如果突然想要使用这个工具不支持的某个数据库功能,可能很难测试它
  3. testegration - 旨在为您提供完整,随时可用且可扩展的生命周期(披露:我是创作者)。

    缺点:

    • 仅适用于小型项目
    • 非常年轻的项目
  4. 另一个步骤是在操作系统级别将db移动到内存。再次,第一次启动时间将类似,因为所有需要加载。一些起点herehere

    缺点:

    • 团队中的每个开发人员都必须修改他的本地环境
    • 不能在操作系统之间移植(如果您的团队有异构环境)

答案 2 :(得分:1)

如何在应用程序中访问数据库?使用普通JDBC或在其上使用抽象(JPA)?

如果您使用抽象层,例如JPQL,所以方言不是那么重要,也许你可以使用in-memory H2数据库进行测试。

如果必须使用本机PostgreSQL语句,另一种方法是使用Testcontainers使用dockerized数据库。这不会加快测试速度,但它可以更轻松地设置/清理环境。

答案 3 :(得分:1)

实际上,您可以得到一个真正的Postgres,以便在测试环境中保持安静。

我还建议您使用dockerized数据库,但使用tmpfs来对数据文件夹进行内存映射:

docker run --name postgres95 -p 5432:5432 --tmpfs /var/lib/postgresql/data:rw -e POSTGRES_PASSWORD=admin -d postgres:9.5.6

这与使用真实事物所获得的“内存中”非常接近。

我认为,慢速集成测试的主要问题之一不是数据库本身的性能,而是每次测试设置数据库所花费的时间。

我写了一个小图书馆来帮助您快速将数据库恢复到“干净”状态。这样,您只需运行一次昂贵的数据库迁移,然后就可以为每个测试快速还原数据库。

我们在生产系统中使用了它,从而在集成测试中将速度提高了4倍:

https://github.com/ayedo/postgres-db-restore