utPLSQL用户指南四

上一个,utResult包

utAssert包包含以下过程与函数。

  • 通用“Assert This”过程。utAssert.this。
  • 检查NULL与NOT NULL。utAssert.isnull、utAssert.isnotnull。
  • 检查标量值的相等性。utAssert.eq。
  • 检查数据库表的相等性。utAssert.eqtable。
  • 检查表中数据量的相等性。utAssert.eqtabcount。
  • 检查查询结果的相等性。utAssert.eqquery。
  • 检查查询与单个值的相等性。utAssert.eqqueryvalue。
  • 检查文件的相等性。utAssert.eqfile。
  • 检查数据库管道的相等性。utAssert.eqpipe。
  • 检查集合的相等性。utAssert.eqcoll、utAssert.eqcollapi。
  • 检查过程或函数抛出的异常。utAssert.throws。
  • 检查上一个断言成功或失败。utAssert.previous_passed、utAssert.previous_failed。
  • 检查DBMS_OUTPUT输出集合的相等性。utAssert.eqoutput。
  • 检查数据库对象的存在性。utAssert.objexists、utAssert.objnotexists。
  • 检查RefCursor与查询的相等性。utAssert.eq_refc_query。
  • 检查RefCursor与数据库表的相等性。utAssert.eq_refc_table。

在utAssert断言程序之前(或者断言程序中)调用测试用例,以便记录测试结果并执行断言程序。以下是一个简单的示例。
PROCEDURE ut_BETWNSTR IS
BEGIN
utAssert.eq (
'Typical valid usage',
BETWNSTR(
STRING_IN => 'abcdefg'
,
START_IN => 3
,
END_IN => 5
),
'cde'
);
END;

注释:所有的utAssert断言都在ut_assertion表中定义,实际代码存储在utAssert包中。

1、通用断言参数与特性

许多断言程序拥有类似的参数,如下表所示。

 msg_in 断言失败时显示的信息。这是第一个参数,必选。
 check_this_in 要检查的值。如果是一个布尔表达式,通常是对被测试方法的调用。
 against_this_in 对于相等性断言,断言程序将会比较check_this_in与against_this_in的值。
 null_ok_in 如果将NULL与NULL比较看作测试成功,设置为TRUE;否则设置为FALSE。
 raise_exc_in 如果允许断言程序抛出未处理的异常,设置为TRUE。

2、通用“Assert This”断言程序

这个最常用的断言程序接收一个布尔表达式参数。

PROCEDURE this (
      msg_in          IN   VARCHAR2,
      check_this_in   IN   BOOLEAN,
      null_ok_in      IN   BOOLEAN := FALSE,
      raise_exc_in    IN   BOOLEAN := FALSE,
      register_in     IN   BOOLEAN := TRUE -- 2.0.1
   );

以下是一个检查布尔表达式的示例。

 
 

也可以使用该断言注册一个失败的测试,通常用于异常部分。

 
 

通常,应该避免使用utAssert.this,而使用专用的断言程序,参考下文。

3、检查NULL与NOT NULL

使用以下断言检查某个值为NULL或者NOT NULL。

 
 

这些断言用于检查标量表达式(字符串、日期、数字以及布尔值)为NULL或者NOT NULL,如下所示。

 
 

4、检查标量值的相等性

如果需要比较两个日期、字符串、数字或者布尔值,使用utAssert.eq断言程序。

 
 

如果该测试允许比较两个NULL值,为null_ok_in传入TRUE。如果希望在失败时抛出异常并且停止测试,为raise_exc_in传入TRUE。
PROCEDURE ut_emp_dept_lookuprowcount
IS l_rowcount1 PLS_INTEGER;
l_rowcount2 PLS_INTEGER;
BEGIN
-- Run baseline code.
SELECT COUNT (*)
INTO l_rowcount1
FROM employee
WHERE department_id = 30; -- Compare to program call:
l_rowcount2 :=
te_employee.emp_dept_lookuprowcount (30); -- Test results
utassert.eq (
'Successful EMP_DEPT_LOOKUPROWCOUNT',
l_rowcount2,
l_rowcount1
);
END;

5、检查数据库表的相等性

测试DML操作时,需要在数据库表中检查操作的结果。utAssert.eqtable可以比较另个表的内容。

 
 

其中,check_this_in与against_this_in是表或视图的名称。可以提供可选的WHERE从句限制进行比较的数据行。以下是一个示例,它调用了eqTable两次,测试不同的条件。

 
 

6、检查表中数据量的相等性

如果只是简单地检查表中数据的行数,使用utAssert.eqtabcount。

 
 

参数参见utAssert.eqtable。以下测试比较表CD_COLLECTION与表U_TEST_5_1中给定条件下的行数。

 
 

7、检查查询结果的相等性

程序utAssert.eqquery比较两个查询(由check_this_in与against_this_in指定)的结果。这样可以不需要构建具有预置数据的表。

 
 

以下是一个示例。

 
 

8、检查查询与单个值的相等性

utAssert.eqqueryvalue用于比较查询结果与某个给定值,定义如下。

 
 

其中,check_query_in是检查的查询,against_value_in是比较的值。如果查询返回多个值,错误信息会进行说明。同样,如果查询结果返回了错误的值,错误信息会描述两个值。以下示例比较表中的最大值与给定的数字值。

 
 

9、检查文件的相等性

许多程序产生输出信息到操作系统文件中,或者写入数据到文件中以便测试结果。eqfile过程使用UTL_FILE包比较两个文件的内容。注意:UTL_FILE包使用前需要进行配置

 
 

如果不指定目录against_this_dir,使用check_this_dir设置。以下是一个使用eqFile的示例,参见ut_DEPARTMENT2file.pkg文件。

 
 

10、检查数据库管道的相等性

数据管道提供了一个在不同会话之间传递数据的便利机制。使用eqpipe检查管道中的内容。

PROCEDURE eqpipe (
      msg_in            IN   VARCHAR2,
      check_this_in     IN   VARCHAR2,
      against_this_in   IN   VARCHAR2,
      check_nth_in      IN   VARCHAR2 := NULL,
      against_nth_in    IN   VARCHAR2 := NULL,
      raise_exc_in      IN   BOOLEAN := FALSE
   );

要检查代码的管道内容,需要再生成一个管道进行比较。参考employee_pipe.pkg文件。

 
 

11、检查集合的相等性

使用eqColl过程比较在包规范中定义的集合。使用eqCollAPI过程比较在包体中定义的集合,它利用包体中的程序(以及API)访问并操作集合。它们的定义如下。

/* Direct access to collections */
   PROCEDURE utAssert.eqcoll (
      msg_in IN VARCHAR2,
      check_this_in IN VARCHAR2, /* pkg1.coll */
      against_this_in IN VARCHAR2, /* pkg2.coll */
      eqfunc_in IN VARCHAR2 := NULL,
      check_startrow_in IN PLS_INTEGER := NULL,
      check_endrow_in IN PLS_INTEGER := NULL,
      against_startrow_in IN PLS_INTEGER := NULL,
      against_endrow_in IN PLS_INTEGER := NULL,
      match_rownum_in IN BOOLEAN := FALSE,
      null_ok_in IN BOOLEAN := TRUE,
      raise_exc_in IN BOOLEAN := FALSE
   );
 
   /* API based access to collections */
   PROCEDURE utAssert.eqcollapi (
      msg_in IN VARCHAR2,
      check_this_pkg_in IN VARCHAR2,
      against_this_pkg_in IN VARCHAR2,
      eqfunc_in IN VARCHAR2 := NULL,
      countfunc_in IN VARCHAR2 := 'COUNT',
      firstrowfunc_in IN VARCHAR2 := 'FIRST',
      lastrowfunc_in IN VARCHAR2 := 'LAST',
      nextrowfunc_in IN VARCHAR2 := 'NEXT',
      getvalfunc_in IN VARCHAR2 := 'NTHVAL',
      check_startrow_in IN PLS_INTEGER := NULL,
      check_endrow_in IN PLS_INTEGER := NULL,
      against_startrow_in IN PLS_INTEGER := NULL,
      against_endrow_in IN PLS_INTEGER := NULL,
      match_rownum_in IN BOOLEAN := FALSE,
      null_ok_in IN BOOLEAN := TRUE,
      raise_exc_in IN BOOLEAN := FALSE
   );

其中,eqColl特有的参数如下表。

 参数 描述
 msg_in 测试失败时显示的信息
 check_this_in 被检查的集合名称。格式:package.collection。也就是说,集合必须在包规范中定义。
 against_this_in 参照的集合名称。格式:package.collection。也就是说,集合必须在包规范中定义。

eqCollAPI特有的参数如下表。

 参数 描述
 msg_in 测试失败时显示的信息。
 check_this_pkg_in 包含被测试集合的包名。
 against_this_pkg_in 包含参照集合的包名。
 countfunc_in 包中返回集合的行数的函数名称。
 firstrowfunc_in 包中返回集合第一行的函数名称。
 lastrowfunc_in 包中返回集合最后一行的函数名称。
 nextrowfunc_in 包中返回集合下一行的函数名称。
 getvalfunc_in 包中返回集合指定行的内容的函数名称。

以上两个过程共同的参数如下表。


 参数 描述
 eqfunc_in 判断数据行的内容是否相同的函数。如果参数为NULL,使用标准的相等性检查。这对于标量值有效,但不能用于记录表等。
 check_startrow_in 被测试集合中参与比较的第一行。如果为NULL,从集合的首行开始。
 check_endrow_in 被测试集合中参与比较的最后一行。如果为NULL,比较到集合的末行结束。
 against_startrow_in 参照集合中参与比较的第一行。如果为NULL,从集合的首行开始。
 against_endrow_in 参照集合中参与比较的最后一行。如果为NULL,比较到集合的末行结束。
 match_rownum_in 设置为TRUE时两个集合中参与比较的行号必须相同。如果为FALSE,行号可以不同,但是对应行内容必须相同。
 null_ok_in 设置为TRUE时,两个NULL集合返回测试成功。
 raise_exc_in 设置为TRUE时,如果测试失败,断言将会抛出一个异常并停止测试。

以下是一个使用utAssert.eqColl的示例,参见filepath1.pkg文件。

 
 

12、检查过程或函数抛出的异常

有时候过程或者函数被设计为在特定情况下抛出异常。utAssert.throws用于测试这种情况。

 
 

其中,check_call_in是执行的过程或函数调用,包括参数和结束的分号。参数against_exc_in是期望抛出的异常,可以是命名异常,或者SQLCODE代码。

以下示例显示了两种用法。

 
 

注意对字符串参数的引用和结束的分号。

13、检查上一个断言成功或失败

有时候,过程可能执行了大量的操作,例如执行了多个表的插入和更新。要测试这些修改,需要多个utAssert断言。有可能在测试失败时输出整个屏幕的错误信息。为了避免这种情况,只显示一个错误信息,可以使用previous_passed函数和previous_failed函数。它们返回上一个断言成功或失败的布尔参数。

 
 

14、检查DBMS_OUTPUT输出集合的相等性

utAssert.eqoutput过程补充了utOutput包,允许比较DBMS_OUTPUT.CHARARR类型的集合。与eqColl和eqCollAPI断言不同,eqoutput运行比较本地定义的集合。

 
 

第一个版本比较两个集合,第二个比较集合与分隔字符串。分隔符在参数line_delimiter_in中指定,如果指定为NULL(默认),分隔符为回车符。因此,要测试如下的集合mybuff:

mybuff(0) := 'Zidane';
mybuff(1) := 'Ronaldo';
mybuff(2) := 'Kahn';

可以使用如下参数。

against_this_in => 'Zidane|Ronaldo|Kahn';
line_delimiter_in => '|';

或者

against_this_in =>
'Zidane
Ronaldo
Kahn';
line_delimiter_in => NULL;

以下参数可以改变比较的方式。

  • ignore_case_in。比较时忽略大小写。
  • ignore_whitspace。比较时忽略空白符。

注意,以上断言只比较文本内容,不考虑集合中记录的编号是否连续,按照顺序进行比较。

15、检查数据库对象的存在性

以下断言检查数据库中的命名对象是否存在。

 
 

参数check_this_in指定要检查的对象名称。要检查其他模式下的对象,在该参数中加上模式名称和一个点号。‘ANOTHER.THATTHING’检查ANOTHER模式下THATTHING对象是否存在。

16、检查RefCursor与查询的相等性

如果过程或者函数返回REF CURSOR类型的数据,通常可能需要将它与一个查询进行比较。使用eq_refc_query可以避免构建一个带预置数据的临时表。

在调用比较断言之前需要指定被测试的过程或函数的参数。可以使用以下过程进行注册。

 
 

然后调用比较的断言过程。

 
 

其中,reg_In_Param、reg_InOut_Param以及reg_Out_Param特有的参数如下表。

 参数 描述
 par_pos 定义从1开始的参数位置,0代表返回值。
 par_type 指定返回值的数据类型,必须是以下之一:NUMBER、VARCHAR、CHAR或者REFCURSOR。
 params 保持参数值的本地变量,用于eq_refc_query。

eq_refc_query特有的参数如下表。


 参数 描述
 p_msg_nm 测试失败时显示的信息。
 proc_name 被测试的过程或者函数名称。
 params 被测试的过程或者函数的参数。
 cursor_position 进行检查的REF CURSOR参数的位置,从1开始,0指定为函数的返回值。
 qry 参照检查的SELECT语句。

注意,断言只比较记录自身,不关心游标中记录的下标是否连续,按照顺序进行比较。

17、检查RefCursor与数据库表的相等性

如果过程或者函数返回代表一个完整表或视图的REF CURSOR类型的数据,通常可能需要将它与一个表或视图进行比较。使用eq_refc_table可以避免构建一个带预置数据的临时表。

在调用比较断言之前需要指定被测试的过程或函数的参数。参见上一小节。eq_refc_table断言过程声明如下。

 
 

其中,table_name是参照检查的表名。

18、创建自定义的断言

如果PL/SQL支持继承,就可以扩展utAssert断言程序并使用多态进行定制。但是它缺少了这种特性,可以参照预置的断言编写自己的过程。为了将自定义的断言的测试结果集成到utResult包中,可以模拟utAssert.this过程。以下是2.2版的this过程定义。

PROCEDURE this (
      outcome_in      IN   ut_outcome.id%TYPE,
      msg_in          IN   VARCHAR2,
      check_this_in   IN   BOOLEAN,
      null_ok_in      IN   BOOLEAN := FALSE ,
      raise_exc_in    IN   BOOLEAN := FALSE ,
      register_in     IN   BOOLEAN := TRUE
   )
   IS
      l_failure   BOOLEAN
   :=    NOT check_this_in
      OR (    check_this_in IS NULL
          AND NOT null_ok_in
         );
   BEGIN
      /* START chrisrimmer 42694 */
      g_previous_pass := NOT l_failure;

      /* END chrisrimmer 42694 */

      IF utplsql2.tracing
      THEN
         utreport.pl (
               'utPLSQL TRACE on Assert: '
            || msg_in
         );
         utreport.pl ('Results:');
         utreport.pl (l_failure);
      END IF;

      -- Report results failure and success

      utresult2.report (
         outcome_in,
         l_failure,
         utplsql.currcase.pkg || '.' || utplsql.currcase.name || ': ' || msg_in,
            /* 2.0.10.2 Idea from Alistair Bayley msg_in */
         register_in,
         showing_results
      );

      IF      raise_exc_in
          AND l_failure
      THEN
         RAISE test_failure;
      END IF;
   END;

在自定义的断言中最重要的语句是utResult.report,它记录了测试的结果。

下一个,utGen包

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24945919/viewspace-744419/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/24945919/viewspace-744419/

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值