2

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

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

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

TL;博士

使用内存数据库进行测试会降低测试的可靠性和范围。尽管基于 h2 的测试是绿色的,但您的应用程序的 SQL 可能会在生产环境中针对真实数据库失败。

它们提供的功能与真实数据库不同。可能的后果是:

  • 您更改应用程序的 SQL 代码只是为了让它在真实数据库和内存数据库中运行。这可能会导致不太有效、优雅、准确或可维护的实现。或者你根本无法做某些事情。
  • 您完全跳过了某些功能的测试。

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

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

4

2 回答 2

5

如果可能的话,我会避免使用 H2 DB。使用 H2DB 很好,当您无法运行自己的实例时,例如,如果您的公司使用 Oracle 之类的东西并且不允许您在任何地方运行自己的数据库(本地机器、自己的开发服务器......)。

H2DB 的问题如下:

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

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

  3. H2DB 和其他 RDBMS 是不同的。测试不会测试同一件事,您可能会在生产中遇到一些不会出现在测试中的错误。

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

但是请继续使用您喜欢的任何方法,最好自己获得您的个人经验,我经常被 H2DB 烧伤而无法喜欢它。

于 2021-06-29T14:33:39.783 回答
4

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

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

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

根据经验,我在部署到生产环境时遇到了与平台/版本/供应商特定问题相关的故障,尽管我对内存数据库的所有测试都变绿了。尽早发现这些问题并节省大量的重复开发时间总是更好的,最重要的是您可以睡个好觉。

于 2021-06-29T14:48:45.737 回答