如何(单元)测试数据密集型PL/SQL应用程序

Kar*_*tný 9 oracle legacy tdd unit-testing plsql

我们的团队愿意对在扩展现有庞大Oracle系统的正在运行的项目下编写的新代码进行单元测试.

该系统仅由PL/SQL编写,由数千个表,数百个存储过程包组成,主要从表中获取数据和/或插入/更新其他数据.

我们的延期也不例外.大多数函数从非常复杂的SELECT语句返回数据,通过许多相互绑定的表(在返回它们之前添加一些逻辑)或者从一个复杂的数据结构转换到另一个(以另一种方式复杂化).

对这些代码进行单元测试的最佳方法是什么?

现有代码库没有单元测试.更糟糕的是,只有包,触发器和视图是源控制的,表结构(包括"alter table"内容和必要的数据转换是通过除版本控制之外的通道部署的).在我们的项目范围内无法改变这一点.

维护测试数据似乎是不可能的,因为每周都有新的代码部署到生产环境中,通常没有事先通知,经常改变数据结构(在这里添加一列,在那里删除一个).

我很高兴有任何建议或参考来帮助我们.一些团队成员往往厌倦了弄清楚如何开始我们的经验,单元测试不包括PL/SQL数据密集型遗留系统(只有那些"来自本书"的绿地Java项目).

APC*_*APC 8

有几种不同的PL/SQL测试工具. 史蒂文·费尔斯坦(Steven Feuerstein)写了两篇名为utplsqlQuest Code Tester for Oracle(以前的QUTE).我是utplsql的忠实粉丝,但它不再拥有一个活跃的支持社区(这是一种耻辱).它也往往非常冗长,特别是在设置测试夹具时.它确实具有纯粹的PL/SQL包的基本虚拟; 源代码有点粗糙,但它是FOSS.

QCTO附带一个GUI,这意味着 - 像其他Quest产品,即TOAD - 它只是Windows.它并不能完全自动化测试数据生成,但它提供了一个支持它的接口.与其他Quest产品一样,QCTO虽然有免费软件,但仍获得许可.

史蒂文(披露,他是我的Oracle英雄之一)编写了所有PL/SQL测试工具的功能比较.显然,QOTC名列前茅,但我认为比较是诚实的. 看看这个.

关于utplsql中测试装置的建议

管理单元测试的测试数据可能是一个真正的痛苦.不幸的是,utplsql并没有提供太多的负担.所以

  • 始终针对已知值进行测试:
    • 避免使用dbms_random;
    • 尝试将序列的使用限制为值无关紧要的列;
    • 日期也很棘手.避免使用硬编码日期:使用填充sysdate的变量.学会欣赏add_months(),last_day(),interval,trunc(sysdate, 'MM'),等.
  • 隔离其他用户的测试数据.从头开始构建它.尽可能使用独特的价值观.
  • 只需根据需要创建尽可能多的测试数据.体积测试是一项不同的责任.
  • 当测试更改数据的过程时,为每个单元测试创​​建特定记录.
  • 另外:不要依赖一次测试的成功输出来提供另一次测试的输入.
  • 在测试程序时,只需在适当的时候报告单元测试之间的数据共享记录.
  • 尽可能共享框架数据(例如,引用的主键).
  • 使用自由文本字段(名称,描述,注释)来标识哪些测试使用该记录.
  • 最大限度地减少创建新记录所涉及的工作:
    • 仅分配测试套件所需的值和表的约束;
    • 尽可能使用默认值;
    • 程序化尽可能多.

其他需要注意的事项:

  • 设置测试夹具可能是一项耗时的练习.如果您有大量数据,请考虑构建一个过程来设置静态数据,每个会话可以运行一次,并且只包含易失性数据ut_setup.在测试只读功能时,这尤其有用.
  • 请记住,创建测试数据本身就是一项编程练习,因此容易出错.
  • 使用utplsql的所有功能. utAssert.EqQuery,utAssert.EqQueryValue,utAssert.EqTable,utAssert.EqTabCountutAssert.Eq_RefC_Query都是非常实用的功能,当谈到推断性数据的值.
  • 当诊断测试运行不符合我们期望的方式时,获取所使用的数据会很有用.因此,考虑进行一个空洞的ut_teardown过程并在开始时清理测试数据ut_setup.

处理遗留代码

评论加里的帖子让我想起了另一件你可能觉得有用的事情.Steven F将ulplsql写成了JUnit的PL/SQL实现,JUnit是Test First运动的Java先锋.然而,TDD的技术也可以应用于大量遗留代码(在此上下文中,遗留代码是没有任何单元测试的任何程序集).

要记住的关键是你不必立即将所有东西都置于单元测试之下.逐步开始.为新东西构建单元测试,Test First.在应用更改之前,对要更改的位进行单元测试,因此您知道在进行更改后它们仍然有效.

在这个领域有很多想法,但(不可避免地,如果可耻的话)它主要来自OO程序员.Michael Feathers是主要的一员.阅读他的文章有效地使用遗留代码.如果你觉得它有用,他随后写了一本同名的书.