在spring引导上下文中使用h2db进行集成测试是不是一种糟糕的做法



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

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

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

TL;博士

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

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

  • 您更改应用程序的SQL代码只是为了它在real数据库和内存数据库中都运行。这可能导致效率较低、优雅、准确或可维护的实现。或你根本不能做某些事情
  • 你跳过了一些测试功能完整

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

有没有我忽略或没有考虑过的反对h2db的观点?是否存在";最佳实践";关于内存中数据库在springboot/hhibernate集成测试中的使用?

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

H2DB的问题如下:

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

  2. H2DB通常不提供相同的功能,就像真正的RDBMS一样,你会因为只使用SQL而降低数据库的性能,你将无法测试存储过程、触发器和所有可能派上用场的花哨东西。

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

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

但继续使用任何你喜欢的方法,最好自己获得你的个人体验,我经常被H2DB烧伤,不喜欢它。

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

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

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

根据经验,在部署到生产环境时,我曾遇到过与平台/版本/供应商特定问题相关的故障,尽管我对内存中数据库的所有测试都是绿色的。最好尽早发现这些问题,节省大量反复出现的发育时间,最重要的是你晚上睡得好。

相关内容

最新更新