1、将测试代码放入被测试的包中
有时候,通常是程序包很小并且测试程序代码数量有限,不需要为测试代码创建一个单独的包。此时,可以将设置程序、清除程序以及单元测试程序放入被测试的包中。接下来看两个例子。
1.1、测试一个简单的字符串函数
假设一个字符串包中只存在一个函数(参见str.pks与str.pkb文件):
/*file str.pks */
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;
/现在需要测试该函数。因为不想创建一个单独的包,直接修改包规范。如下所示:
CREATE OR REPLACE PACKAGE str
IS
FUNCTION betwn (
string_in IN VARCHAR2,
start_in IN PLS_INTEGER,
end_in IN PLS_INTEGER
)
RETURN VARCHAR2;
PROCEDURE ut_setup;
PROCEDURE ut_teardown;
-- For each program to test...
PROCEDURE ut_betwn;
END str;
/包体与测试一中的“测试一个标量函数”示例相同。但是执行测试时,需要告诉utPLSQL,测试代码位于被测试包中。
SQL> exec utconfig.showconfig
=====================================================
utPLSQL Configuration for SCOTT
Directory: e:\openoracle\utplsql\utinstall\examples
Autcompile? Y
Manual test registration? N
Prefix = ut_
=====================================================
PL/SQL procedure successfully completed.
SQL> exec utPLSQL.test ('str', samepackage_in => TRUE)
.
> 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: "str"1.2、测试集合元素
utPLSQL提供了utAssert.eqColl与utAssert.eqCollAPI程序用于测试集合。
例如,考虑包fileIO:它实现了UTL_FILE包的一个路径特性。也就是说,当请求打开文件时,程序搜索按照顺序搜索每一个路径直到找到文件或者完成列表中的路径。以下是包规范的内容:
/*file filepath1.pkg */ CREATE OR REPLACE PACKAGE fileIO IS c_delim CHAR(1) := ';'; dirs dirs_tabtype := dirs_tabtype (); -- Unit test list ut_dirs dirs_tabtype := dirs_tabtype (); PROCEDURE setpath (str IN VARCHAR2, delim IN VARCHAR2 := c_delim); FUNCTION path RETURN VARCHAR2; FUNCTION pathlist RETURN dirs_tabtype; FUNCTION open (file IN VARCHAR2, loc IN VARCHAR2 := NULL)
RETURN UTL_FILE.FILE_TYPE; -- Unit test code in same package PROCEDURE ut_setup; PROCEDURE ut_teardown; PROCEDURE ut_setpath; END; /
以上包中声明了一个公共集合,fileIO.dirs,用于存储路径。由于它是在包规范中声明的,可以使用utAssert.eqColl过程(如果集合隐藏在包体中,应该使用utAssert.eqCollAPI)。测试代码也位于该包中。同时声明了另一个公共的集合,fileIO.ut_dirs,将会把它与fileIO.setPath产生的路径进行比较。
以下是测试程序的实现:
PROCEDURE ut_setpath IS BEGIN /* Populate base collection */ ut_dirs.DELETE; ut_dirs.EXTEND(2); ut_dirs(1) := 'c:\temp'; ut_dirs(2) := 'e:\demo'; /* Call setpath to do the work */ setpath ('c:\temp;e:\demo'); utAssert.eqColl ( 'Valid double entry', 'fileio.dirs', 'fileio.ut_dirs' ); END;
该测试程序由三步组成:直接赋值生成测试集合;调用setPath程序生成事实集合;调用断言程序比较两个集合。注意传递给断言程序的是集合的名称。utAssert使用动态SQL创建一个“即时”PL/SQL块来比较集合的值。
2、使用非默认的前缀
utPLSQL默认的前缀是“ut_”,但并不是必须使用该前缀。有时候可能不想使用默认的前缀。例如,假设已经编写了一个包含10个过程的包,每个过程都已经包含了一个“ut_”前缀(它可能代表“Unified Tecnologies”或者“Underside Treatment”等等)。
因为该前缀没有硬编码到utPLSQL中,可以很容易地指定自己的前缀。可以在运行一个测试时指定,例如:
SQL> utPLSQL.test ('te_employee', prefix_in => 'test_');也可以在添加包到测试套件中时指定前缀,例如:
SQL> utPackage.add ('mysuite', 'mypackage' prefix_in => 'test_');当然,如果指定了一个非默认的前缀,也必须在构建测试包时使用该前缀。例如:
SQL> utGen.testpkg('mypackage' prefix_in => 'test_');要查看使用非默认前缀的包的示例,参见test_te_employee.pks与test_te_employee.pk文件。
3、创建并运行测试套件
通常,应用程序包含多个包。为了测试应用,必须测试所有的包。utPLSQL通过提供测试套件来简化这个操作。
以下是一个定义了用于PL/Vision的测试套件(部分)的示例脚本。PL/Vision是RevealNet的活动PL/SQL知识库中的一个代码库。
/*file plvision.tst */
BEGIN
-- Define a test suite for PL/Vision
utsuite.add ('PLVision');
-- Add packages for testing
utpackage.add (
'PLVision', 'PLVstr', dir_in => 'e:\openoracle\utplsql\examples');
utpackage.add (
'PLVision', 'PLVdate', dir_in => 'e:\openoracle\utplsql\examples');
END;
/这是一个非常简单的测试套件定义。除了指定测试包代码的位置之外,都采用了默认值。
此外,还可以在参数seq_in中指定包的测试顺序。也可以指定在被测试的源码包中查找测试代码,等等。
BEGIN
utsuite.add ('PLVision');
utpackage.add ('PLVision',
'PLVstr',
dir_in => 'e:\openoracle\utplsql\examples',
seq_in => 1,
samepackage_in => TRUE
);
utpackage.add ('PLVision',
'PLVdate',
dir_in => 'e:\openoracle\utplsql\examples',
seq_in => 2,
samepackage_in => TRUE
);
END;
/