English 中文(简体)
您使用哪些最佳实践来测试数据库查询?
原标题:
  • 时间:2008-11-03 23:36:19
  •  标签:

我目前正在测试我们的解决方案,该方案拥有全部的“色度层级”:用户界面(UI)、中间层和普遍存在的数据库。

在我加入当前团队之前,查询测试是由测试人员手动编写查询来理论上返回储存过程应该返回的结果集,基于各种相关规则、排序等等。

这个副作用是,错误经常被报告给测试人员的查询,而不是实际的查询。

我建议实际上与已知的结果集一起工作,你可以推断出它应该返回什么,因为你控制着存在的数据——以前,数据是从生产环境中拉取,消毒,然后填充到我们的测试数据库中。

人们仍然坚持创建自己的查询来测试开发人员所创建的内容。我怀疑许多人仍然这样做。我认为这根本不是理想的做法,只会不必要地增加我们的测试范围。

所以,我很好奇,您使用哪些实践来测试这样的场景,并且什么被认为是最理想的,以获得最佳的端到端覆盖,而不引入混乱的数据?

我面临的问题是在哪里进行最好的测试。我只需直接测试服务,将该数据集与可以从存储过程中提取的数据集进行比较吗?我有一个初步的想法,并且迄今为止已经取得了足够的成功,但我感觉我们仍然遗漏了一些重要问题,因此我希望向社区寻求帮助,看看它们是否有任何有价值的见解,可以帮助我更好地制定测试方法。

最佳回答

测试存储过程需要每个测试人员都拥有一个单独的数据库实例。这是一个要求。如果您共享环境,则无法依赖于测试结果。这些结果将是毫无价值的。

您还需要确保在每次测试后将数据库回滚到其先前的状态,以使结果可预测和稳定。由于需要在每次测试后回滚状态,因此这些测试需要比标准单元测试更长的时间才能完成,因此它们可能是您想要在晚上运行的测试。

有一些工具可以帮助你完成这项工作。DbUnit是其中之一,我也相信微软有一个名为“数据库专业人员的Visual Studio”工具,其中包含了一些对数据库测试的支持。

问题回答

这里有一些指导原则:

  1. Use an isolated database for unit testing (e.g. No other test runs or activity)
  2. Always insert all the test data you intend to query within the same test
  3. Write the tests to randomly create different volumes of data e.g. random number of inserts say between 1 and 10 rows
  4. Randomize the data e.g. for a boolean field random insert and true or false
  5. Keep a count in the test of the variables (e.g. number of rows, number of trues)
  6. For the Asserts execute query and compare against local test variables
  7. Use Enterprises Services transactions to rollback database to previous state

请查看以下链接了解企业服务交易技术:

将此翻译为中文:http://weblogs.asp.net/rosherove/articles/DbUnitTesting.aspx http://weblogs.asp.net/rosherove/articles/DbUnitTesting.aspx

作为我们持续集成的一部分,我们每晚运行数据库查询的构建。这包括一套 DB 调用,这些调用会定期从代码中的真实调用以及任何预期的临时查询进行更新。

这些电话是按时进行的,以确保:

他们不需要太长时间。

2/ 它们没有与前一晚明显地不同(在不良方面)。

这样,我们可以很快捕捉到错误查询或数据库变更。

查询计划器是你的朋友,尤其是在这种情况下。检查索引是否被使用以及查询是否需要额外的工作是一种良好的实践。即使你的套件中包含了压力测试,也最好在应用程序开始崩溃之前捕捉到昂贵的查询。

我们为每个开发人员和测试人员准备了一个空白数据库。

当测试运行时,每个测试都清除数据库并加载它要使用的数据。这使我们始终具有已知状态。

我们可以在同一个数据库上测试几种不同的情况(一个接一个),而且不会影响其他测试人员的工作。

这涵盖了测试数据访问本身。对于服务测试,我们做类似的事情,但我们仅测试服务内部 - 我们实际上不会调用服务,而是创建一个服务处理类的实例并传入我们需要的所有内容。这样,我们就测试了代码而不是基础设施(消息等)。

Django提供数据库单元测试的功能。您可以借鉴他们的设计思路,并在其他环境中进行复制。

Django 的开发者提供了 Python 标准单元测试工具集的子类 TestCase。该工具集可以使用一个已知的固定数据集来填充数据库 -- 即一组已知的数据记录。

对于Django(和Python)来说,最容易从JSON数据提取中填充数据库。其他固定资产的文件格式可用于其他框架。例如,如果您正在使用Oracle,您可能会发现CSV文件更容易使用。

这个 TestCase 子类允许编写一个看起来典型的测试用例,以已知的数据装置来练习数据库。

另外,Django测试运行程序会为测试目的创建一个临时架构。这对Django来说很容易,因为它们拥有完整的对象关系管理组件,包括DDL创建。如果没有这个可用,您仍然需要DDL脚本,以便为unittest目的创建和处置测试模式。

SQLServerCentral有一篇文章在这里(您可能需要注册,但是免费的且没有任何限制),介绍了一个名为tsqlUnit的TSQL单元测试框架。它是开源的,并遵循xUnit框架的传统。

它遵循SEAT TDD模式:

设置 - 通过操作对象、表格和/或数据来准备测试条件

运动 - 调用生产代码

断言 - 检查实际结果是否等于预期结果。

拆卸 - 将所有东西归还到测试开始之前的状态。实际上,这是通过回滚事务来完成的,可以保持一切井然有序。

尽管我没有使用过它,但它看起来很有前途,我一定会更详细地研究它。

该框架可以在这里下载。

我发现测试发送到数据库的 SQL 语句比查询数据库的结果有用。

不是我不做后者,但我发现测试比数据库太大更快。

这是一个繁重的设置,但我建议使用TDD容器。

运行您的测试脚本后,构建一个包含您的数据库运行的新容器,使用模拟数据进行填充,然后运行查询并测试返回结果以及查询是否成功。

通过这种方式,您可以控制测试环境与生产环境的接近程度。

ThoughtWorks (思沃客)





相关问题
热门标签