《存储过程的测试》由会员分享,可在线阅读,更多相关《存储过程的测试(26页珍藏版)》请在金锄头文库上搜索。
1、许多基于 Windows 的系统都使用了 SQL Server 作为后台组件。待测程序 (AUT:Application Under Test)或者待测系统(SUT:System Under Test)经常通过存储过 程来访问数据库。对于这些应用场景,可以把 SQL 存储过程想象成应用程序的辅助 函数。有两种基本的方法可以用来编写针对 SQL 存储过程的轻量级的自动化测试。第一种方法是在原始的 SQL 环境中编写自动化测试代码,也就是说测试套件代 码(harness code)用于 T-SQL 语言来编写的,并且在类似于查询分析器(QueryAnalyzer)或 者 Management St
2、udio 这样的程序里被执行。第二种方法是在.NET 环境下编写自动测试代码,测试套件代码是用 C#或者其 他.NET 语言来编写的,并且在诸如命令行程序等常规的 Windows 环境下被执行。此次介绍如何使用原始的 SQL 环境来测试 SQL 存储过程。问题问题如何创建 SQL 数据库以及表结构以用来保存测试用例的输入数据和测试结果。设计设计编写 T-SQL 脚本,创建一个数据库然后创建一些表用来保存测试用例的输入数 据和测试结果。如果想通过 SQL 认证的方式连接到上一步创建的数据库,则要创建 一个专用的 SQL 登录账号,然后在查询分析器里或者通过 osql.exe 运行 T-SQL 脚
3、本。方案方案下面的脚本创建了一个叫 dbTestCasesAndResults 的数据库,它包括一个用于存 储测试用例数据的表和一个胜于存储测试结果的表,以及一个专用的 SQL 登录账号, 这个账号便于程序通过 Windows 认证或者 SQL 认证的方式连接数据库。下面来看代 码。第一步设定当前的数据库为 SQLServer 的主数据库(master database)。当创建一 个新的用户数据库的时候,这一步是必不可少的。如果要创建的数据库已经存在, 系统就会给一个错误,为了防止这种错误,可以在 试图删除新数据库的旧版本之前 通过查询 sysdatabases 表来检查旧版的数据库是否存在
4、。然后可以通过数据库创建用 于测试用例存储的数据库。用于创 建数据库的语句有许多可选的参数,但是对于轻 量级的自动测试来说,接受这些参数的默认值通常就可以满足需要了。-makeDbTestCasesAndResults.sqluse mastergoif exists(select * from sysdatebases where name = dbTestCasesAndResults)drop database dbTestCasesAndResultsgoif exists(select * from sysxlogins where name = testLogin)exec sp_
5、droplogin testLogingocreate database dbTestCasesAndResultsgouse dbTestCasesAndResultsgocreate table tblTestCases(caseID char(4) primary key,input char(3) not null,- an empIDexpected int not null)go-下面插入的是用于 usp_StatusCode 的测试用例数据-也可以通过 BCP,DTS,或者 C#程序从文本文件读入insert into tblTestCases values(0001,e11,7
6、7)insert into tblTestCases values(0002,e22,77) should be 66insert into tblTestCases values(0003,e33,99)insert into tblTestCases values(0004,e44,88)gocreate table tblResults(caseID char(4) not null,result char(4) null,whenRen datetime not null)goexec sp_addlogin testLogin,secretgoexec sp_grantdbacces
7、s testLogingogrant select,insert,delete on tblTestCases to testLogingogrant select,insert on tblResult to testLogingo注解注解SQL 数据库支持两种不现的安全模 式:使用 Windows 认证可以通过 Windows 账号 ID 和密码连接数据库,使用混合模式认证可以通过 SQL 登录 ID 和 SQL 密码 来连接数据库。如果想要通过 SQL 认证来连接数据库,应该使用系统存储过程 sp_addlogin()创建一个 SQL 登录账号以及相应的密 码。如果要删除一个 SQL 登
8、录账 号,可以先查询 sysxlogin()表检查相应的账号是否存在,然后调用 sp_droplogin()来 删除这个账号。 创建好一个 SQL 登录账号以后,应该赋予登录账号连接数据库的许 可。然后需要针对数据库里的表,赋予登录账号与 SQL 语句相关的权限许可,比 如: SELECT,INSERT,DELETE 以及 UPDATE。SQL 登录账号很容易与 SQL 用户搞混。SQL 登录账号是服务器范 围的对象, 它用来控制针对装有 SQL Server 的机器的连接许可。而 SQL 用户是数据库范围的对 象,它用来控制数据库以及它所包含的表,存储过程和其他一些对象的权限许可。 当为一个
9、 SQL 登录账号分配权限的时候,会自动创建一个同名的 SQL 用户。所以最 终会有一个 SQL 登录账号和一个 SQL 用户,两个名字相同并且相互关联。尽管也可 以上让 不同名的账号和用户相互关联,但是这太容易让人迷惑了,所以最好还是使 用名字相同的默认机制。为了测试存储过程而测试用例存储结构的时 候,必须决定在什么时候以及如何 往表中插入胜于测试用例的那些数据。最简单的办法是在创建表的时候直接加入用 于测试用例的数据。使用本解决方案所演示的 INSERT 语句可以很快的完成这件事 情。但是,在测试的过程中几乎肯定要在很多地方碰上需要添加或者移除测试用例 数据的情况,所以更灵活的方法是在后面
10、 使用 BCP(Bulk Copy Program),DTS(Data Transformation Services)或者一个辅助的 C#程序来插入数据。如果想要插入以及删除 测试用例数据,那么就应当针对存储测试用例数据的那张表为 SQL 登录账号赋予 INSERT 和 DELETE 的权限许可。这个用于创建测试用例和存储测试结果的脚本可以通过几种方法来运行,一种 方法是在查询分析器程序里打开并通过 Excute 命令。第二种方法是使用 OSQL.EXE 程序来执行这个 SQL 脚本问题问题如何使用 BCP 从一个文本文件把测试用例数据导入到 SQL 表设计设计创建一个 BCP 格式的文件用
11、于把想导入的文本文件信息映射到目标 SQL 表,然 后把上述格式的文件作为参数传给命令行工具 bcp.exe。方案方案假设 SQL 表定义如下: create table tblTestCases(caseID char(4) primary key,input char(3) not null,expected int not null)还有一个包含测试用例数据的文本文件叫作 newData.dat0020,e13,660021,e14,770022,e15,880023,e16,990024,e17,66创建一个叫 newData.fmt 的 BCP 格式的文件,这个文件采用制表符(tab
12、)作为分 隔符。8.031 SQLCHAR 0 4 “,“ 1 caseID SQL_Latin1_General_CP1_CI_AS2 SQLCHAR 0 3 “,“ 2 input SQL_Latin1_General_CP1_CI_AS3 SQLCHAR 0 2 “rn“ 3 excepted SQL_Latin1_General_CP1_CI_AS用于导入测试用例数据的命令如下:C:bcp.exe dbTestCasesAndResults.tblTestCases in newData.dat -fnewData.fmt -S. -UtestLogin -Psecret此命令的意思是
13、针对数据库 dbTestCasesAndResults 里的表 tblTestCases 运行 BCP 程序,把 newData.dat 里的数 据按照 newData.fmt 所定义的格式映射导入到上述 表中。这些命令是针对本地的 SQLServer 所执行的,连连数据库的时候使用叫作 testLogin 的 SQL 登录账号,SQL 密码是 secret。使用这种技术,关键是要理解 bcp.exe 程序所使用的格式文件的结 构。这个文 件的第 1 行只有一个单独的值用来表示 sql server 的版本号。SQL Server 7.0 的版本 号是 7.0,SQL Server 2000
14、的版本号是 8.0,SQL Server2005 的版本号是 9.0。格式文 件的第二行是一个整数值,它表示格式文件中映射实际开始的行号。第 3 行以后的 的内容都是映射信息。每个映射 行(mapping line)有 8 个列。前 5 个列代表与输入数 据(本例中指文件文件)有关信息。后 3 个列代表要导入的目标信息(本例中指 SQL 表)。 第一列其实就是从 1 开始 的系列数字。这些值总是 1、2、3 等,依此类推。(这些数 字以及其他一些 BCP 格式文件里的信息看上去是没有必要的,但是在其他一些情况 下确实会用到它 们。)映射行里的第二列是要导入的数据类型。当从文本文件导入数 据的时
15、候,不管这个值代表的是什么,它的类型总是 SQLCHAR。第三例是前缀长 度 (prefix length)。这是当进行从 SQL 到 SQL 数据拷贝时,BCP 用于优化的一个相 当复杂的参数。幸运的是,当把文本数据导入 SQL 的时候,前缀总长度值总 是 0.第 四列表示输入字段字符的最大长度。第五列表示字段分隔会,在此用逗号来分割所 有的字段。比如说,如果输入数据文件的字段是用制表符来分割,应该在 映射文件 中指定为t。第六列到第八列指代的是目标 SQL 表,而不是输入文件。第六列和第 七列分别指 SQL 表里相应列的顺序和名称。映射行第八列用来指定 要使用的 SQL 排序规则。注解注解
16、使用 BCP 工具可以高效地以自动化的方式把测试用例数据从文本文件引入 到 SQL 测试用例表中。特别注意,测试用例的数据文件在数据块的最后一行之后一定 不能再有换行符。如果有换行符,就会被 BCP 解释成一个新的空行。而用于 映射的 格式文件在最后一行之后一定要有一个换行符。如果没有这个换行符,BCP 就不会 读入映射文件的最后一行。即使文本文件的数据格式与 SQL 表的结果不完全吻合,也可以通过 BCP 工具从 文本文件导入数据。换句话说,即使文本文件的数据与相应的 SQL 列顺序不一致或 者文本文件的数据有多作的字段,仍然可以使用 BCP 工具来导入数据,例如:0020,66,useless,e130021,77,no-need,e140022,88,go-away,e150023,99,drop-it,e16这个文件有些额外的信息并不想将其导入,而且各个字段(caseID,expected value,unneeded data,input value)的顺序也和 SQL 列(caseID