【问题标题】:in-memory DBs evaluation内存数据库评估
【发布时间】:2009-07-08 18:15:47
【问题描述】:

我正在尝试增加整体集成测试执行时间,并且我目前正在评估各种内存数据库解决方案。这个想法是让 DAO 在测试期间访问内存数据库,而不是访问真正的数据库。这是一个使用 Hibernate 进行持久化的 java 应用程序。

我很想了解您对 H2、Derby、HSQLDB、Oracle Berkeley DB 等产品之一的体验。

我的一些担忧是:内存数据库是否能够执行存储过程、自定义原生 sql?您能否有选择地选择您的哪一项服务应该访问真实数据库和内存数据库?

总体而言,由于这种方法涉及 DB 引导(预加载/预创建所有包含数据的表),我现在正在考虑是否只是简单地模拟 DAO 层而不用担心所有mem DB中可能带来的未知问题...

谢谢。

【问题讨论】:

    标签: java database testing integration-testing


    【解决方案1】:

    我的建议是测试所有内容,包括您提到的 DAO 层。但是看看你是否可以分段测试它。服务、DAO、UI。

    对于服务层测试,模拟 DAO。这样,服务层测试就独立于 DAO 是否正常工作。如果服务层测试使用 DAO 并使用真实数据库,那么我认为这不是真正的单元测试,而是集成测试。虽然这些也很有价值,但如果它们失败了,它并不能像单元测试那样查明问题。

    对于我们的 DAO 层测试,我们使用带有 HSQLDB 的 DbUnit。 (如果您使用 Spring/Hibernate/DbUnit 将它们捆绑在一起,则使用 Unitils 会有所帮助。)我们的 DAO 测试执行得很好而且很快(当您有 500 多个测试时,这一点很重要)。内存数据库模式是从我们的模式创建脚本构建的,因此我们也在测试这些脚本。我们将一些平面文件中的一组已知数据加载/刷新到内存数据库中。 (与我们使用 DEV 数据库时相比,一些数据会被删除,然后破坏测试)。 这个解决方案非常适合我们,我会推荐给任何人。

    但是请注意,我们无法以这种方式测试使用存储过程的 DAO(但我们只有一个)。我有点不同意发帖者提到使用不同的数据库是“不好的”——只要注意差异并知道这样做的含义。

    您没有提及您是否使用 Hibernate——这是一个重要因素,因为它使我们无需修改任何可能特定于 Oracle 或 SQLServer 或 HSQLDB 的 SQL,而另一位发帖人提到了这一点。

    【讨论】:

    • dustmachine - 感谢您的回复,非常有帮助。是的,我们使用的是 Hibernate,底层数据库是 Oracle。我们有很多存储过程和很多疯狂的原生 sql。
    • 我同意您应该运行集成测试。然而,在与您最终将使用的数据库不同的数据库上进行测试的价值有限——它究竟证明了什么?如果这种方法的唯一好处是速度,您需要质疑为什么您的集成测试如此缓慢。使用 dbunit 和少量测试数据,您在 Oracle 上的集成测试应该非常快。
    • Hibernate 等框架允许进行测试,而无需关心后端的数据库。无论数据库供应商如何,UserDAO 的 findUserByName 方法都会按预期执行。例如,如果合同说不区分大小写。针对实时数据库进行测试很脆弱,因为它需要数据处于稳定状态。开发人员需要记住不要更改某些记录或测试需要在每次测试之前执行大量设置。这可以克服,但每次都有一个新的数据库更容易,尤其是有很多 FK。运行 500 次测试时,内存数据库总是会更快。
    【解决方案2】:

    模拟 DAO 层。

    尽管有人声称,除非您只是使用微不足道的 sql,否则数据库之间的细微实现差异和不同的功能集将限制您可以执行的操作(存储过程、视图等),并且在某种程度上也会使测试无效。

    我个人选择的模拟框架是 Mockito。但是有很多东西可以完成这项工作,并且模拟 DAO 是标准做法,因此您会找到很多文档。

    【讨论】:

    • Mocking DAO 需要付出太多努力,而且反馈很少。
    • 使用现代模拟框架,模拟 DAO 层应该需要很少的努力。
    • 只有在没有完全分离的情况下才需要努力。我一直在 .NET 中模拟我的 DAL,当我使用 Moq 时几乎不需要努力。
    【解决方案3】:

    为单元测试和生产使用不同的数据库是个坏主意。

    顺便说一句,在真实数据库中测试应该很快,可能你在测试中做错了什么。

    【讨论】:

    • 我个人认为,如果在你的真实数据库上测试很慢,那是重要的信息,这意味着查询在 prod 上的执行也可能无法接受!除了您打算实际使用的后端之外,我认为在其他后端进行测试没有任何价值。您可能会了解到查询有效,但这只是您需要测试的一半,除非您喜欢恢复到旧代码,因为新代码在 prod 上超时。
    【解决方案4】:

    我刚刚在 mem db 中遇到了 Oracle Times Ten。 http://www.oracle.com/technology/products/timesten/index.html

    这似乎可能是最轻松的解决方案。因为不需要额外的模拟/配置。您的所有集成测试仍然完好无损地进入数据库,但现在数据交付速度更快。大家觉得呢?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多