在我们的团队中,最近提出了一个问题,如果生产环境依赖于不同的数据库引擎(在我们的案例中是MySQL 8),那么使用h2 db进行集成测试是否是一种不好的做法/是否应该避免。
我不确定我是否同意这一点,考虑到我们正在为我们的后端使用spring Boot /hibernate。
我做了一些阅读,并偶然发现这篇文章https://phauer.com/2017/dont-use-in-memory-databases-tests-h2/基本上说明了以下(和更多):
左心室,右心室
使用内存数据库进行测试会降低测试的可靠性和范围。尽管基于h2的测试是绿色的,但应用程序的SQL在生产环境中对真实的数据库可能会失败。
它们提供的功能与真实的数据库不同。可能的后果是:
- 您更改应用程序的SQL代码只是为了使它在真实的和内存数据库中运行。这可能会导致不太有效,优雅,准确或维护的实现。或者你根本不能做某些事情。
- 您完全跳过了某些功能的测试。
就我所知,对于一个带有一些业务逻辑的简单CRUD应用程序,所有这些问题都与我无关(本文中还有更多),因为hibernate Package 了所有SQL,代码中没有原生SQL。
有没有什么是我忽略或没有考虑到的,反对h2 db的?关于使用内存数据库进行spring Boot /hibernate集成测试,有没有“最佳实践”?
3条答案
按热度按时间ne5o7dgx1#
如果可能的话,我会避免使用H2 DB。当你不能运行自己的示例时,使用H2 DB是很好的,例如,如果你的公司使用像Oracle这样的东西,并且不允许你在任何你想要的地方运行自己的数据库(本地机器,自己的开发服务器...)。
H2 DB的问题如下:
说到简单的CRUD应用程序-它可能不会永远保持这种状态。
但是,继续使用任何你喜欢的方法,最好是自己获得个人经验,我经常在H2 DB上被烧伤,不喜欢它。
vpfxa7rd2#
我认为这取决于测试的范围以及集成测试的成本。我更喜欢在尽可能接近我的生产环境的环境中进行测试。但这是理想的情况,在现实中,由于各种原因,这可能是不可能的。此外,期望hibernate完美地抽象掉底层细节也是一种理想的情况,实际上,抽象可能会给你一种错误的安全感。
如果您的测试范围只是测试CRUD操作,那么内存中测试就可以了。在这个范围内,它将发挥相当大的作用。它甚至可能有利于减少测试的时间,以及一定程度的复杂性。它不会检测到任何平台/版本/供应商特定的问题,但这不是测试的范围。在投入生产之前,您可以在登台环境中测试这些东西。
在我看来,现在比以往任何时候都更容易使用Docker等工具创建尽可能接近生产环境的测试环境,CI/CD工具/平台也支持为此目的启动服务。如果这对于您的用例来说不可用或太复杂,那么回退是可以接受的。
根据经验,我在部署到生产环境时遇到过与平台/版本/供应商特定问题相关的失败,尽管我对内存数据库的所有测试都是绿色的。尽早发现这些问题总是更好的,这样可以保存大量的重复开发时间,最重要的是可以保证您的良好睡眠。
3wabscal3#
只是为了补充这些答案,但是由于设置测试容器的容易性,我真的看不到使用h2进行集成测试的必要性/优势。大多数管道也有Docker运行时开箱即用。
我甚至会说,模拟你的仓库调用和使用h2进行集成测试一样有价值,因为h2不能为一个真实的数据库提供足够的准确性,从而不能真正信任结果。