首页 > Linux操作系统 > Linux操作系统 > utPLSQL示例一
考虑以下情况:存储过程运行一些代码,然后通过参数列表返回结果。此时,可以编写一个测试单元,分析OUT和IN OUT参数的值;存储过程运行一些代码,修改了应用中的其他部分(例如表或者文件),参数列表不包含用于分析是否成功执行的参数。因此为了测试是否成功,需要分析/比较被修改的数据结构。
以下过程接受两个日期参数并返回它们之间的秒数。
/*file calc_secs_between.sp */ CREATE OR REPLACE PROCEDURE calc_secs_between ( date1 IN DATE, date2 IN DATE, secs OUT NUMBER) IS BEGIN -- 24 hours in a day, -- 60 minutes in an hour, -- 60 seconds in a minute... secs := (date2 - date1) * 24 * 60 * 60; END; /
编译成功之后,创建测试包:
SQL> SET SERVEROUTPUT ON FORMAT WRAPPED
SQL> exec utGen.testpkg ('calc_secs_between')
以上语句会在屏幕上产生下面的输出:
CREATE OR REPLACE PACKAGE ut_calc_secs_between
IS
PROCEDURE ut_setup;
PROCEDURE ut_teardown;
-- For each program to test...
PROCEDURE ut_CALC_SECS_BETWEEN;
END ut_calc_secs_between;
/
CREATE OR REPLACE PACKAGE BODY ut_calc_secs_between
IS
PROCEDURE ut_setup
IS
BEGIN
NULL;
END;
PROCEDURE ut_teardown
IS
BEGIN
NULL;
END;
-- For each program to test...
PROCEDURE ut_CALC_SECS_BETWEEN IS
BEGIN
CALC_SECS_BETWEEN (
DATE1 => ''
,
DATE2 => ''
,
SECS => ''
);
utAssert.this (
'Test of CALC_SECS_BETWEEN',
'
);
END ut_CALC_SECS_BETWEEN;
END ut_calc_secs_between;
/
也可以直接生成两个单独的文件存储包规范与包体,ut_calc_secs_between.pks与ut_calc_secs_between.pkb,方法如下:
SQL> exec utGen.testpkg ('calc_secs_between ', output_type_in => utGen.c_file)通过以上方式,utPLSQL能够在每次测试之前自动编译代码。编辑文件,添加各种用例,内容如下:
PROCEDURE ut_CALC_SECS_BETWEEN
IS
secs PLS_INTEGER;
BEGIN
CALC_SECS_BETWEEN (
DATE1 => SYSDATE
,
DATE2 => SYSDATE
,
SECS => secs
);
utAssert.eq (
'Same dates',
secs,
0
);
CALC_SECS_BETWEEN (
DATE1 => SYSDATE
,
DATE2 => SYSDATE+1
,
SECS => secs
);
utAssert.eq (
'Exactly one day',
secs,
24 * 60 * 60
);
END ut_CALC_SECS_BETWEEN;
然后运行测试:
SQL> exec utplsql.test ('calc_secs_between')
.
> SSSS U U CCC CCC EEEEEEE SSSS SSSS
> S S U U C C C C E S S S S
> S U U C C C C E S S
> S U U C C E S S
> SSSS U U C C EEEE SSSS SSSS
> S U U C C E S S
> S U U C C C C E S S
> S S U U C C C C E S S S S
> SSSS UUU CCC CCC EEEEEEE SSSS SSSS
.
SUCCESS: "calc_secs_between"当然,还可以继续测试其他参数条件。
以下是一个更复杂的情况。存储过程截断了指定表的所有数据行,定义如下:
/*file truncit.sp */ CREATE OR REPLACE PROCEDURE truncit ( tab IN VARCHAR2, sch IN VARCHAR2 := NULL ) IS BEGIN EXECUTE IMMEDIATE 'truncate table ' || NVL (sch, USER) || '.' || tab; END; /
这个过程的测试不能简单地通过检查返回值决定是否成功,而是应该检查表中还存在多少行数据。以下函数能够返回表中的数据行(也可以使用utAssert.eqqueryvalue):
/*file tabcount.sf */
CREATE OR REPLACE FUNCTION tabcount (
sch IN VARCHAR2,
tab IN VARCHAR2)
RETURN INTEGER
IS
retval INTEGER;
BEGIN
EXECUTE IMMEDIATE
'SELECT COUNT(*) FROM ' || sch || '.' || tab
INTO retval;
RETURN retval;
EXCEPTION
WHEN OTHERS
THEN
RETURN NULL;
END;
/然后生成测试包,并修改包体:
SQL> SET SERVEROUTPUT ON FORMAT WRAPPED
SQL> exec utGen.testpkg ('truncit', output_type_in => utGen.c_file)为了进行测试,需要截断一个表。这是一个不可逆的操作,因此可以在设置程序中创建一个“临时”表,并在清除程序中删除它。然后运行测试并使用tabCount验证结果:
/*file ut_truncit.pkb */
CREATE OR REPLACE PACKAGE BODY ut_truncit
IS
PROCEDURE ut_setup
IS
BEGIN
EXECUTE IMMEDIATE
'CREATE TABLE temp_emp AS SELECT * FROM employee';
END;
PROCEDURE ut_teardown
IS
BEGIN
EXECUTE IMMEDIATE
'DROP TABLE temp_emp';
END;
-- For each program to test...
PROCEDURE ut_TRUNCIT IS
BEGIN
TRUNCIT (
TAB => 'temp_emp'
,
SCH => USER
);
utAssert.eq (
'Test of TRUNCIT',
tabcount (USER, 'temp_emp'),
0
);
END ut_TRUNCIT;
END ut_truncit;
/与存储过程一样,考虑一下情况:函数返回标量值(数字、日期、字符串、布尔值)。此时,可以直接将函数调用嵌套在utAssert断言程序的调用中;函数返回非标量值,例如对象或者集合。此时,需要调用该函数,并验证返回结构的内容;函数返回一个值,同时执行了其他操作,这些操作的成功与否没有通过返回值体现。要想充分测试这种函数(存在“副作用”)可能会非常困难,因为必须考虑各种情况。
以下定义了一个包中的函数:
/*file str.pks and str.pkb */
CREATE OR REPLACE PACKAGE str
IS
FUNCTION betwn (
string_in IN VARCHAR2,
start_in IN PLS_INTEGER,
end_in IN PLS_INTEGER
)
RETURN VARCHAR2;
END str;
/函数str.betwn返回字符串string_in的一个字串,起始位置和结束位置分别为start_in和end_in。
然后生成了一个测试包并修改单元测试程序的内容,如下所示:
/*file ut_str.pkb */
CREATE OR REPLACE PACKAGE BODY ut_str
IS
PROCEDURE ut_setup
IS
BEGIN
NULL;
END;
PROCEDURE ut_teardown
IS
BEGIN
NULL;
END;
-- For each program to test...
PROCEDURE ut_betwn IS
BEGIN
utAssert.eq (
'Typical Valid Usage',
str.betwn ('this is a string', 3, 7),
'is is'
);
utAssert.eq (
'Test Negative Start',
str.betwn ('this is a string', -3, 7),
'ing'
);
utAssert.isNULL (
'Start bigger than end',
str.betwn ('this is a string', 3, 1)
);
END ut_betwn;
END ut_str;
/
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/24945919/viewspace-743236/ ,如需转载,请注明出处,否则将追究法律责任。