【问题标题】:How to prepare for integration tests which use PostgreSQL's in memory replacement?如何准备在内存替换中使用 PostgreSQL 的集成测试?
【发布时间】:2017-09-15 13:47:01
【问题描述】:

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

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

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

【问题讨论】:

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


【解决方案1】:

我在真实 postgres 上的一些数据库测试每次需要 10 毫秒。我在每个测试中进行多次提交。所以:

要覆盖 postgres-native 特性,您需要相同的数据库(如您所见,h2 和其他内存数据库不是很兼容)。 postgres 没有内存模式。 对于功能测试,真实数据库本身并不比任何内存数据库慢多少。区别通常在于启动时间(对于 postgres 9.6,它大约是 4 秒)。但是,如果您的测试生命周期很智能,并且您可以将 db 开始数减少到 1 或 0(通过让开发数据库始终准备好),那么问题就不再那么明显了。

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

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

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

    缺点:

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

    缺点:

    • 仅对小型项目免费
    • 非常年轻的项目

另一个步骤是将数据库移动到操作系统级别的内存。同样,第一次启动时间将相似,因为所有内容都需要加载。一些起点herehere

缺点:

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

【讨论】:

    【解决方案2】:

    这个问题征求意见,但这里是:

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

    如果您使用足够小以适合 RAM 的数据库,则可以使 PostgreSQL 变得非常快,这对于只针对功能而非整体性能的集成测试应该是可能的。

    【讨论】:

    • 问题还提到了“如何?”部分。
    • 不需要特殊配置。如果有足够的 RAM 以使数据库适合它而不会产生内存压力,那么它将保持在那里。如果您不想依赖文件系统缓存,请将shared_buffers 设置得足够大,以便整个数据库都适合。
    【解决方案3】:

    您实际上可以让一个真正的 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

    【讨论】:

      【解决方案4】:

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

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

      如果您必须使用原生 PostgreSQL 语句,另一种方法是使用使用 Testcontainers 的 dockerized 数据库。这不会加快测试速度,但会使设置/清理环境更加容易。

      【讨论】:

      • 我用mybatis访问
      • 为什么它适用于 H2? Mybatis 是否只支持 PostgreSQL 的子集功能,顺便兼容 H2?
      • 那么您需要原生 PostgreSQL 功能吗?比你必须使用真正的 PostgresSQL 数据库。也许 Testcontainers 会派上用场。
      猜你喜欢
      • 2021-12-19
      • 2013-08-09
      • 2019-02-07
      • 2019-06-30
      • 2015-09-17
      • 1970-01-01
      • 2017-01-16
      • 2016-06-04
      • 2021-04-22
      相关资源
      最近更新 更多