对数据库驱动的应用程序进行单元测试的最佳策略是什么? [英] What's the best strategy for unit-testing database-driven applications?

查看:13
本文介绍了对数据库驱动的应用程序进行单元测试的最佳策略是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了许多由后端复杂程度不同的数据库驱动的 Web 应用程序.通常,有一个 ORM 层与业务和表示逻辑分离.这使得对业务逻辑进行单元测试变得相当简单;事物可以在离散模块中实现,测试所需的任何数据都可以通过对象模拟来伪造.

I work with a lot of web applications that are driven by databases of varying complexity on the backend. Typically, there's an ORM layer separate from the business and presentation logic. This makes unit-testing the business logic fairly straightforward; things can be implemented in discrete modules and any data needed for the test can be faked through object mocking.

但是测试 ORM 和数据库本身总是充满问题和妥协.

But testing the ORM and database itself has always been fraught with problems and compromises.

多年来,我尝试了一些策略,但没有一个让我完全满意.

Over the years, I have tried a few strategies, none of which completely satisfied me.

  • 加载具有已知数据的测试数据库.针对 ORM 运行测试并确认返回正确的数据.这里的缺点是您的测试数据库必须跟上应用程序数据库中的任何架构更改,并且可能会不同步.它还依赖于人工数据,并且可能不会暴露由于愚蠢的用户输入而发生的错误.最后,如果测试数据库很小,它不会像缺少索引那样显示效率低下.(好吧,最后一个并不是真正应该用于单元测试的,但它并没有什么坏处.)

  • Load a test database with known data. Run tests against the ORM and confirm that the right data comes back. The disadvantage here is that your test DB has to keep up with any schema changes in the application database, and might get out of sync. It also relies on artificial data, and may not expose bugs that occur due to stupid user input. Finally, if the test database is small, it won't reveal inefficiencies like a missing index. (OK, that last one isn't really what unit testing should be used for, but it doesn't hurt.)

加载生产数据库的副本并对其进行测试.这里的问题是您可能不知道在任何给定时间生产数据库中有什么;如果数据随时间发生变化,您的测试可能需要重写.

Load a copy of the production database and test against that. The problem here is that you may have no idea what's in the production DB at any given time; your tests may need to be rewritten if data changes over time.

有人指出,这两种策略都依赖于特定的数据,而单元测试应该只测试功能.为此,我看到了建议:

Some people have pointed out that both of these strategies rely on specific data, and a unit test should test only functionality. To that end, I've seen suggested:

  • 使用模拟数据库服务器,并仅检查 ORM 是否正在发送正确的查询以响应给定的方法调用.

您使用了哪些策略来测试数据库驱动的应用程序(如果有)?什么对你最有效?

What strategies have you used for testing database-driven applications, if any? What has worked the best for you?

推荐答案

实际上,我已经使用了您的第一种方法并取得了相当大的成功,但我认为会以稍微不同的方式解决您的一些问题:

I've actually used your first approach with quite some success, but in a slightly different ways that I think would solve some of your problems:

  1. 在源代码管理中保留整个架构和用于创建它的脚本,以便任何人在签出后都可以创建当前的数据库架构.此外,将示例数据保存在由构建过程的一部分加载的数据文件中.当您发现导致错误的数据时,将其添加到您的示例数据中以检查错误不会再次出现.

  1. Keep the entire schema and scripts for creating it in source control so that anyone can create the current database schema after a check out. In addition, keep sample data in data files that get loaded by part of the build process. As you discover data that causes errors, add it to your sample data to check that errors don't re-emerge.

使用持续集成服务器构建数据库架构、加载示例数据并运行测试.这就是我们如何保持我们的测试数据库同步(在每次测试运行时重建它).虽然这要求 CI 服务器有权访问和拥有自己的专用数据库实例,但我说每天构建 3 次 db 模式极大地帮助发现了可能直到交付前(如果不是更晚)才会发现的错误).我不能说我在每次提交之前重建架构.有人吗?使用这种方法,您就不必这样做(也许我们应该这样做,但如果有人忘记了也没什么大不了的).

Use a continuous integration server to build the database schema, load the sample data, and run tests. This is how we keep our test database in sync (rebuilding it at every test run). Though this requires that the CI server have access and ownership of its own dedicated database instance, I say that having our db schema built 3 times a day has dramatically helped find errors that probably would not have been found till just before delivery (if not later). I can't say that I rebuild the schema before every commit. Does anybody? With this approach you won't have to (well maybe we should, but its not a big deal if someone forgets).

对于我的小组,用户输入是在应用程序级别(而不是数据库)完成的,因此这是通过标准单元测试进行测试的.

For my group, user input is done at the application level (not db) so this is tested via standard unit tests.

加载生产数据库副本:
这是我上一份工作中使用的方法.这是几个问题的巨大痛苦原因:

Loading Production Database Copy:
This was the approach that was used at my last job. It was a huge pain cause of a couple of issues:

  1. 副本将从生产版本中过时
  2. 将对副本的架构进行更改,并且不会传播到生产系统.在这一点上,我们会有不同的模式.不好玩.

模拟数据库服务器:
我们在我目前的工作中也这样做.每次提交后,我们都会针对注入了模拟数据库访问器的应用程序代码执行单元测试.然后我们每天执行 3 次上述的完整数据库构建.我绝对推荐这两种方法.

Mocking Database Server:
We also do this at my current job. After every commit we execute unit tests against the application code that have mock db accessors injected. Then three times a day we execute the full db build described above. I definitely recommend both approaches.

这篇关于对数据库驱动的应用程序进行单元测试的最佳策略是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆