存储过程的单元测试


44

我已经考虑了很长时间了。

基本问题是:如何对存储过程进行单元测试?

我看到我可以相对简单地为经典意义上的函数设置单元测试(我的意思是它们得到零个或多个参数并返回一个值)。但是,如果我考虑一个看似简单的过程的真实示例,该过程似乎在某个位置插入行,并在插入之前或之后执行一些触发器,甚至在定义“单元”的边界时也很难做到。我应该只测试INSERT自身吗?我认为这很简单-价值相对较低。我应该测试整个事件链的结果吗?除了是否要进行单元测试的问题外,设计合适的测试可能是一项艰巨的工作,并且还会增加许多其他问号。

然后是不断更改数据的问题。如果UPDATE影响不只是几行,那么在测试用例中必须以某种方式包括每个可能受影响的行。DELETEs等的进一步困难。

那么如何对存储过程进行单元测试?在复杂性上是否有完全无法实现的极限?维护需要哪些资源?

编辑基于AlexKuznetsov的回答,还有一个小问题:还是有一个完全没有用的阈值?

Answers:


32

我们已经这样做了将近五年,我们认为明确测试修改肯定是可行的,但速度很慢。此外,除非我们使用单独的数据库,否则我们无法轻松地从多个连接中同时运行此类测试。相反,我们应该隐式地测试修改-我们使用它们来构建至少一些测试数据,并验证我们的选择是否返回了预期结果。

我写了一篇题为“ 关闭那些漏洞:从T-SQL单元测试中学到的教训”的文章,以及一些博客文章。

关于您的问题“在完全没有希望的情况下,是否存在复杂性的门槛?”,复杂的模块比简单的模块需要更多的测试。

为了简化维护,我们生成了预期的结果,并将它们存储在单独的文件中-产生了很大的不同。


15

是的,您应该将整个事件链作为一个单元进行测试。因此,在示例中,该过程插入到表中并导致触发多个触发器,因此您应该编写单元测试,以评估该过程的各种输入。每个单元测试应该通过还是失败,具体取决于它是否返回正确的值,正确更改表的状态,创建正确的电子邮件,甚至发送正确的网络数据包(如果旨在执行此操作)。简而言之,应验证该装置的所有作用。

没错,设计单元测试需要做一些工作,但是大部分工作必须手动完成,而您只是保存测试单元所需的工作,以便将来进行更改时进行测试可以变得彻底而简单。

更改数据的确会使测试变得更加困难,但并不会降低测试的重要性,并且实际上增加了单元测试的价值,因为大多数困难只需要考虑一次即可,而不是每次对单元进行更改时都要考虑。保存的数据集,作为设置/拆卸的一部分的插入/更新/删除以及范围狭窄的操作都可以用来简化此过程。由于问题不是特定于数据库的,因此细节会有所不同。

高端或低端没有复杂性阈值,可以阻止您进行测试或单元测试。考虑以下问题:

  1. 您是否总是编写无错误代码?
  2. 小型装置是否始终没有错误?
  3. 大型单位有错误可以吗?
  4. 造成灾难需要多少错误?

假设您开始一项新工作,并且要对许多地方使用的小功能进行优化。整个应用程序是由一个甚至没有人记得的员工编写和维护的。这些单位有描述正常预期行为的文档,但仅此而已。您更希望找到其中哪个?

  • 应用程序中的任何地方都没有单元测试。进行更改后,您可以对设备本身进行一些手动测试,以确保它仍然返回文档中的期望值。然后,您可以将其推广到生产环境,指望并希望它能工作(毕竟,您始终编写无错误代码,并且一个单元中的优化永远不会影响另一个单元),或者花费大量时间学习整个应用程序的方式可以使您可以直接或间接手动测试每个单元。
  • 每天或按需自动运行的整个应用程序中的单元测试。他们不仅检查正常的输入值及其预期的响应,还检查异常的值和引发的预期异常。您进行更改并立即运行该应用程序的单元测试套件,看到其他三个单元不再返回预期结果。其中两个是良性的,因此您需要调整单元测试来解决这个问题。第三个需要稍作调整和小的新单元测试。进行更改后,整个测试套件将成功,您可以放心地进行更改。

1
首先,感谢您的回答-在这个问题上,我没想到会有任何进一步的发展……其次,我不得不承认您对简单的操作是正确的:即使是两列的INSERT也会产生错误。如果编写它的目的是使列顺序可以与参数匹配,那么可以,但是那又是对的:最好将整个应用程序保持在测试状态下。
dezso

@dezso这是一个很好的问题,也是一个需要在数据库世界中获得更多了解的概念。
Leigh Riffel

“您应该将整个事件链作为一个单元进行测试” –这是您可以说的最违反直觉的事情。如果是这样,它就不是单位。您正在执行集成测试
Joe Phillips

@Joe Philips-随心所欲,确保执行插入操作并触发一些触发器的过程符合自动测试的要求。
Leigh Riffel

8

对于PostgreSQL,请查看pgTAP

pgTAP是一组数据库函数,可以轻松地在psql脚本或xUnit风格的测试函数中编写TAP发射单元测试。


看到了,谢谢。有人有经验吗?
dezso 2012年

是的,如今有很多人。如有疑问,请订阅邮件列表
理论

6

如果您希望完全在SQL上完成对存储过程的测试,请访问http://tsqlt.org/

它与MS SQL 2005 SP2和更高版本兼容,并且优点是开发人员不需要了解C#或其他语言即可实现测试。

还提供了用于制作模拟表和视图的工具,以帮助您实现可重新运行的测试套件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.