2011-06-10 48 views
20

在Java项目中,JUnit测试执行安装,测试和拆卸。即使在使用内存数据库嘲笑真正的数据库时,通常也会回滚事务或从内存中删除数据库,并在每次测试之间重新创建数据库。由于一个测试不会在可能影响下一个测试的环境中留下工件,因此可以为您提供测试隔离。每个测试都以已知的状态开始,不能流入另一个测试。如何实现测试隔离测试Oracle PL/SQL?

现在我已经有了一个Oracle数据库构建,可以创建1100个表和400K的代码 - 很多pl/sql包。我想不仅测试数据库安装(完全 - 从头开始​​创建,部分 - 从以前的数据库升级等),并确保所有的表和其他对象处于安装后我期望的状态,但也是在pl/sql上运行测试(我不确定我会怎么做前者 - 建议?)。

我想这一切都从詹金斯运行CI,以便通过回归测试捕捉开发错误。

首先,我必须使用企业版本而不是XE,因为XE不支持Java SP和对Oracle Web Flow的依赖。即使我消除了这些依赖关系,构建通常需要1.5小时才能加载(完整构建)。

那么如何在这种环境下实现测试隔离呢?为每个测试使用交易并将其回滚?好的,那些提交它们的pl/sql程序呢?

我想过备份和恢复以在每次测试之后重置数据库,或者在每次测试之间重新创建整个数据库(过于剧烈)。两者都不切实际,因为它需要花费一个多小时才能安装。这样做每个测试是过度杀伤和疯狂。

有没有一种方法可以在数据库模式中在沙中绘制一条线,然后将其滚回到该时间点? Sorta就像一个大的“撤消”功能。除了expdp/impdp或rman之外的东西。也许整个方法都关闭了。建议?其他人如何做到这一点?

对于CI或小型生产升级窗口,最终测试套件必须在合理的时间内运行(30分钟将是理想的)。

是否有产品可能有助于实现这种“撤消”能力?

+0

你可以捕捉的DB(道路的克隆速度比好处exp/imp或rman),然后在克隆上运行测试。 (询问您的系统管理员) – tbone 2011-06-14 15:29:54

回答

9

在Oracle中,您可以使用闪回技术将服务器恢复到某个时间点。

http://download.oracle.com/docs/cd/B28359_01/backup.111/b28270/rcmflash.htm

+1

闪回表是一项需要企业版许可证的功能:http://download.oracle.com/docs/cd/B28359_01/license.111/b28287/editions.htm#CJACGHEB所以它不是普遍适用的解决方案。此外,数据库和/或表格必须配置为支持闪回。 – APC 2011-06-11 16:28:42

11

凯文·麦科马克发表在服务器实验室博客关于使用Maven和Hudson PL/SQL持续集成测试的文章。 Check it out。测试组件的关键要素是Steven Feuerstein's utPlsql框架,它是PL/SQL中JUnit概念的实现。

需要重置我们的测试夹具是PL/SQL测试中的一个大问题。有帮助的一件事是观察良好实践并避免在存储过程中进行提交:事务控制应仅限于调用堆栈的最外层部分。对于那些只需发出提交的程序(可能因为它们执行DDL而隐含),总会有一个测试夹具发出DELETE语句。处理关系完整性使得编写代码非常棘手。

另一种方法是使用数据泵。您似乎放弃impdp,但Oracle也为其提供了PL/SQL API,DBMS_DATAPUMP。我在这里建议它,因为它提供了在运行导入之前垃圾清除任何现有数据的功能。所以我们可以有一个导出的数据集作为我们的测试夹具;执行SetUp是一个运行数据泵作业的问题。你不需要在TearDown中做任何事情,因为整理开始时就会发生整理。

3

对于1100个表和400K的代码,1.5个小时似乎很长时间。我显然不知道你的环境的细节,但根据我的经验,我敢打赌你可以缩短到5到10分钟。下面是我见过的与Oracle的两个主要安装脚本问题:

1.操作被分解成小块

你有更多的开销将会有更多的步骤。例如,你要尽可能多地巩固这样的代码:

替换:

create table x(a number, b number, c number); 
alter table x modify a not null; 
alter table x modify b not null; 
alter table x modify c not null; 

有了:

create table x(a number not null, b number not null, c number not null); 

替换:

insert into x values (1,2,3); 
insert into x values (4,5,6); 
insert into x values (7,8,9); 

有了:

insert into x 
select 1,2,3 from dual union all 
select 4,5,6 from dual union all 
select 7,8,9 from dual; 

如果您在不同位置运行脚本和数据库,则尤其如此。当你乘以10,000时,这个微小的网络延迟开始变得重要。我所知道的每一个Oracle SQL工具都会一次发送一条命令。

2.开发人员可以共享一个数据库

这比一个技术性修复一个长期的过程解决方案,但你必须时刻启动。大多数使用Oracle的地方只安装在少数服务器上。然后它变成一个稀缺资源,必须小心管理。人们争吵,角色不清楚,事情没有得到解决。

如果这是您的环境,请立即停止每个笔记本电脑的疯狂并安装Oracle。花几百美元给每个人个人版(与企业版具有相同的功能)。为每个人提供他们需要的工具,持续的改善将最终解决您的问题。


此外,对于模式“撤消”,您可能希望查看可移动的表空间。我从来没有使用它,但据说这是一个安装系统更快的方式 - 只需复制和粘贴文件,而不是导入。类似地,也许某种类型的虚拟化可以提供帮助 - 创建操作系统和数据库的快照。

0

虽然Oracle闪回是一个企业版的功能是基于在所有版本中提供,即Oracle日志矿工的技术:

http://docs.oracle.com/cd/B28359_01/server.111/b28319/logminer.htm#i1016535

我很想知道是否有人用它来提供测试隔离功能测试,即查询v $ LOGMNR_CONTENTS以从与测试开始相对应的时间点获取UNDO语句列表。

数据库需要在归档模式和在JUnit测试用例与

@Startup 

注释将调用DBMS_LOGMNR.START_LOGMNR的方法。该测试将与

@Teardown 

注释会查询V $ LOGMNR_CONTENTS找到UNDO语句列表的方法运行,然后。这些将通过JDBC执行。事实上,UNDO语句的查询和执行可以提取到PLSQL存储过程中。必须考虑执行语句的顺序。

我觉得这允许提交事务这是其中一个可怕的很多的bug可以在IE参照完整性蠕变,主键冲突等