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,它记录了测试的结果。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/24945919/viewspace-744419/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/24945919/viewspace-744419/
3万+

被折叠的 条评论
为什么被折叠?



