在 spring 引导上下文中使用 h2db 进行集成测试是不好的做法吗?

Is it bad practice to use h2db for integration test in a spring boot context?

最近在我们的团队中提出了一个问题,如果生产环境依赖于不同的数据库引擎,在我们的例子中 MySQL8,那么使用 h2db 进行集成测试是否不好 practice/should 应该避免。 =14=]

我不确定我是否同意这一点,考虑到我们正在使用 spring boot/hibernate 作为我们的后端。

我读了一些书,发现这篇文章 https://phauer.com/2017/dont-use-in-memory-databases-tests-h2/ 基本上陈述了以下内容(以及更多内容):

TL;DR

Using in-memory databases for tests reduce the reliability and scope of your tests. Your application’s SQL may fail in production against the real database, although the h2-based tests are green.

They provide not the same features as the real database. Possible consequences are:

  • You change the application’s SQL code just to make it run in both the real and the in-memory database. This may result in less effective, elegant, accurate or maintainable implementations. Or you can’t do certain things at all.
  • You skip the tests for some features completely.

据我所知,对于一个带有一些业务逻辑的简单 CRUD 应用程序,所有这些点都与我无关(文章中还有更多内容),因为 hibernate 包装了所有 SQL 并且那里代码中没有原生SQL。

是否有任何我忽略或未考虑的反对 h2db 的观点?关于使用内存数据库与 spring boot/hibernate 进行集成测试是否有“最佳实践”?

我会尽可能避免使用 H2 DB。使用 H2DB 很好,当你不能 运行 自己的实例时,例如,如果你的公司使用像 Oracle 这样的东西并且不会让你 运行 你自己的数据库随处可见(本地机器,自己的开发服务器...)。

H2DB 的问题如下:

  1. H2DB 和您的数据库的迁移脚本可能不同。您可能需要对 H2DB 脚本和 MySQL 脚本进行一些调整。

  2. H2DB 通常不提供与真正的 RDBMS 相同的功能,您将数据库降级为仅使用 SQL,您将无法测试存储过程、触发器和所有可能会派上用场的花哨东西。

  3. H2DB与其他RDBMS不同。测试不会测试相同的东西,您可能会在生产中遇到一些不会出现在测试中的错误。

说到您的简单 CRUD 应用程序 - 它可能不会永远保持这样。

但是请继续使用您喜欢的任何方法,最好亲自获得您的个人经验,我经常对 H2DB 感到厌烦,所以不喜欢它。

我会说这取决于您的测试范围以及您可以为集成测试支付的费用。我更喜欢在尽可能接近我的生产环境的环境中进行测试。但这是理想情况,实际上由于各种原因可能无法实现。此外,期望 hibernate 完美地抽象出低级细节也是一种理想情况,实际上抽象可能会给你一种错误的安全感。

如果您的测试范围只是测试 CRUD 操作,内存测试应该没问题。它将在该范围内充分发挥作用。它甚至可能有助于减少测试时间以及一定程度的复杂性。它不会检测到任何 platform/version/vendor 特定问题,但这无论如何都不是测试的范围。在投入生产之前,您可以在暂存环境中测试这些东西。

在我看来,现在比以往任何时候都更容易使用 docker、CI/CD tools/platform 之类的东西创建一个尽可能接近您的生产环境的测试环境也支持旋转为此目的的服务。如果这对于您的用例不可用或太复杂,则可以接受回退。

根据经验,我在部署到生产环境时遇到过与 platform/version/vendor 特定问题相关的失败,尽管我针对内存数据库的所有测试都是绿色的。尽早发现这些问题总是更好,这样可以节省大量的重复开发时间,最重要的是让您睡个好觉。