1、IBM Rational软件测试工具实验报告目录IBM Rational软件测试工具实验报告1实验一 使用Rational Purify工具测试代码中内存相关错误2实验二 使用Rational Quantify对程序代码做性能分析15实验三 使用Rational PureCoverage对程序代码做性能分析23实验四 Rational Performance Tester 的基本使用30实验五 Rational Performance Tester 中数据池的使用54实验六 Rational Performance Tester 中调度的使用67实验七 Rational Functional
2、Tester的使用90实验一 使用Rational Purify工具测试代码中内存相关错误一、目的和要求1了解应用程序代码中与内存有关的错误,以及由此引发的后果;2掌握Rational Purify的基本设置;3掌握Rational Purify的基本操作方法,学会使用该工具;4能够分析Rational Purify输出的内存错误报告。二、实验内容1学习讲义01,掌握Rational Purify的使用方法;2完成以下实验: (1)分析以下C程序代码,找出其中的内存错误(用注释说明错误类型);#include using namespace std;int main() char * str1
3、 = hello; char * str2 = new char5; char * str3 = str2; coutstr2endl; strcpy(str2,str1); coutstr2Run3.3 选择可执行文件ex1.exe,点击run按钮3.4 程序的运行结果:从程序运行的结果上看,第一行的输出不是预期的结果,按照以往的经验,在c/c+程序中输出了非预期的字符和乱码往往是因为数组越界读取造成的或者是指针在分配内存区域后未经初始化就直接读取造成的。3.5 查看和保存报告在程序运行结束后,Rational Purify会为我们生成一份报告,具体内容如图:保存错误报告:点击保存(4)分析
4、Rational Purify输出的内存错误报告。对内存错误报告0逐条分析:4.1 Rational Purify报告在源程序exp1.cpp的第10行存在UMR(未初始化的内存读)错误:原因分析:虽然char * str2 = new char5;这句代码完成了对内存的初始化,但是并没有为字符数组中的每个字符赋初值,而在C语言中,对于变量来讲,没有赋初值意味着这个变量的值是随机的,因为C语言的变量没有默认值。所以输出的内容中第一行有乱码,这行乱码就是源代码第10行执行后输出的。以上三条UMR错误描述的是同一个问题。4.2 Rational Purify报告在源程序exp1.cpp的第10行存
5、在ABR(内存越界读)错误:原因分析: C语言中字符串是以“0”作为结束标志的,当输出语句遇到第一个“0”时就会认为字符串已经结束,然后就会终止读取,否则将一直读取下去,直到遇到“0”或者操作系统检测到程序读取了不该读取的内容之后终止程序运行为止。在源程序中,虽然指针str2指向的内存正确的申请了内存,但却没有对字符数组的每个元素进行初始化(应当有这样的习惯和意识:在C语言中,变量声明的时候一定要赋初值)。一开始没有初始化字符数组的每个元素为“0”,这就导致了在读取str2指向的字符数组时cout发生了越界,程序无休止的向下读,期望碰到“0”终止读取。发生这样的情况是非常危险的,轻则导致乱码输
6、出,重则导致程序异常终止。所以声明变量(尤其是指针变量)后,记得赋初值。4.3 Rational Purify报告在源程序exp1.cpp的第10行存在IPR(非法指针读)错误:原因同4.2,不再赘述。4.4 Rational Purify报告在源程序exp1.cpp的第12行存在ABW(数组越界写)错误:原因分析:C语言中字符串是以“0”作为结束标志的,当输出语句遇到第一个“0”时就会认为字符串已经结束,然后就会终止读取,否则将一直读取下去,直到遇到“0”或者操作系统检测到程序读取了不该读取的内容之后终止程序运行为止。在源程序中,按照C语言的规则“hello”这个字符串应该是占6个字节大小(
7、包括“0”),而指针str2指向的内存区域中只有5个字节的大小。Strcpy是string.h头文件中的一个函数,其作用是字符串拷贝,strcpy(str2,str1);这句代码试图将占6个字节的“hello”字符串放入str2所指向的存储空间(只有5个字节大小)之中,这样的操作必然导致数组越界,越界的部分被写到了指针str2指示的区域之外,这样的操作会造成比越界读更严重的后果,严重的时候可能因为破坏了其他程序的内存空间造成其他程序崩溃和操作系统异常。这类错误相对比较隐蔽,不一定每次都会引起操作系统报警,但是问题一旦出现就有可能造成严重的后果。4.5 Rational Purify报告在源程序
8、exp1.cpp的第18行存在FMR(空闲内存读)错误:原因分析:从图中可以看出,程序在第7行为指针str2指向的内存区域分配了5个字节大小的空间,但是程序在第16行使用了delete关键字,在C+中delete相当于c语言中的free,是释放内存空间用的。由于程序执行到第18行的时候,str2指向的内存空间已经在第16行释放,所以程序读取了已经释放的内存(空闲内存就是指已经释放的内存),这样的事情是不应该发生的,程序应当读取已经分配的内存空间,对于已经释放的内存空间不应该去读取。这样的操作也是容易发生问题的,因为已经释放的内存存储的内容很可能不是指针指向的数据类型的,在读取时可能因为类型不匹
9、配导致程序发生问题,或者已经释放的这片内存已经不归这个程序所有也是有可能的,取出的内容可能会是乱码或者直接引起程序崩溃。4.6 Rational Purify报告在源程序exp1.cpp的第18行存在FMW(空闲内存写)错误:原因分析:正如4.5分析的那样,空闲内存写比空闲内存读危害更大,因为写操作本身就带有一定的破坏性。如果写到了其他正常程序的内存空间还会导致其他程序崩溃。4.7 Rational Purify报告在源程序exp1.cpp的第20行存在FFM(再次释放已经释放的内存)错误:原因分析:char * str3 = str2;这句代码使得str2和str3指向同一块内存空间,在程序
10、的第16行释放了str2指向的内存,也就间接释放了str3指向的内存。在20行再次尝试释放str3指向的内存空间就有会出现FFM(再次释放已经释放的内存)错误。综合上述分析,源代码中存在以下错误:#include using namespace std;int main() char * str1 = hello; char * str2 = new char5; char * str3 = str2; coutstr2endl; /UMR、ABR、IPR strcpy(str2,str1); /ABW coutstr2endl; /ABR delete str2; str20+=2; /FM
11、R、FMW delete str3; /FFM getchar(); return 0;实验二 使用Rational Quantify对程序代码做性能分析一、目的和要求1了解应用程序性能的相关概念;2掌握Rational Quantify的基本设置;3掌握Rational Quantify的基本操作方法,学会使用该工具;4能够分析Rational Quantify输出的性能分析报告。二、实验内容1学习讲义02,掌握Rational Quantify的使用方法;2阅读以下C程序,该程序对二维数组中的每行进行排序,行与行之间不排序,完成以下实验: #include using namespace
12、std;const int N=3;void sort(int iArrayNN) int iRow,iCol,iCur,iMin,iMinAdd,iTemp; for( iRow = 0; iRow N; iRow+ ) for( iCol =0 ; iCol N-1;iCol+ ) iMin = iArrayiRowiCol; iMinAdd = iCol; /在当前行中,从当前元素开始往后找最小的元素 for( iCur = iCol + 1; iCur N ;iCur+ ) if( iArrayiRowiCur iMin ) iMin = iArrayiRowiCur; iMinAdd
13、 = iCur; /在当前行中,从当前元素开始往后找最小的元素 iArrayiRowiMinAdd = iArrayiRowiCol; iArrayiRowiCol = iMin; /对每行进行排序 int main()int ANN;int i,j;cout请输入N*N个整数:endl;for( i = 0; i N ; i+ ) for( j = 0; jAij; cout对每行排序前的数组为:endl;for( i = 0; i N ; i+ ) for( j = 0; j N ; j+ ) coutAij ; coutendl;sort(A);cout对每行排序后的数组为:endl;f
14、or( i = 0; i N ; i+ ) for( j = 0; j N ; j+ ) coutAij ; cout“用户组”在用户组的调度元素详细信息界面中设置用户名、组的大小(按照百分比或设置实际用户数)、运行用户组的位置。如创建两组用户:一组为个人组singleUser,一组为院系用户组groupUser。4.设置用户组运行的测试右键单击用户组,在快捷菜单中选择“添加”-“测试”,弹出“选择性能测试”对话框。选择用户组要进行的测试,点击“确定”按钮。添加完成后效果如图:5.设置延迟时间设置延迟后,每个测试都会延迟相应的时间,方便地控制用户的动作。右键单击用户组,在快捷菜单中选择“添加”
15、-“延迟”,在延迟的调度元素中设置延迟的时间。设置延迟时间为1000毫秒(即一秒):设置延迟之后的效果:6设置循环次数(脚本的迭代次数)性能调度只包含了用户组和测试,用户组中每个测试会按顺序执行。循环提供了比简单顺序执行更加复杂的控制,增加循环可以按照一定的迭代重复测试,可以设置测试运行的频度。右键单击用户组,在快捷菜单中选择“添加”-“循环”,在循环的调度元素详细信息中设置迭代次数。设置了循环之后,为循环添加测试:选择之前录制的测试脚本生成的测试:为循环添加测试之后的效果:7.设置随机选择器右键点击用户组,在快捷菜单中选择“添加” “随机选择器”,在随机选择器的调度元素详细信息中设置迭代次数
16、 按“添加”键,添加加权块,并输入加权块的权重。 输入加权块的名称和权重:设置了随机选择器后,需要为加权块添加测试 添加好之后的状态:8.设置一些性能调度选项启用资源监视,并设置要监视的资源(主要是CPU、内存、磁盘和网络):点击添加:如图,我已经添加了:内存、物理磁盘、处理器和流量统计(网络)。增加监视后的效果:启用性能需求:收集响应时间数据:9.启动性能调度10.性能调度结果实验七 Rational Functional Tester的使用一、目的和要求1学会使用Rational Functional Tester进行功能测试;2学会使用RFT录制和回放脚本;3学会给脚本添加验证点,学会使
17、用数据池。二、实验内容选定一个Java应用程序,录制功能测试脚本并回放。然后给脚本设置数据池和验证点,回放脚本观察实验现象,生成并分析测试报告。1.对待测程序的说明和准备工作待测程序是我编写的“中北商城”项目,该程序是一个基于JavaSE GUI的小程序(如果没有JRE环境请自行安装)。该程序包括客户端和服务器两个部分。启动时请先启动服务器端程序,管理员有三个账号:编号用户名密码1张三1232李四4563王五789请以三个账号中的任意一个登陆后开始操作!加入一些商品信息:输入若干商品信息之后:此时千万不要关掉服务器端,否则客户端将无法登陆!请将服务器端窗口最小化!登陆客户端,注册一个账号,输入
18、用户名和密码之后点击注册按钮:然后再点击登录按钮,登陆成功后看到管理员录入的商品列表:此时管理员端的登陆用户数变为1:退出客户端:点击退出登录,点击是:此时管理员处在线用户数显示0:如果上述操作没有出现问题,说明环境一切正常!查看D盘下的store文件夹,里面会有一些数据:这些数据在程序运行时不可以删除!当程序运行完成后就可以删除了!准备工作完成后就可以录制脚本了!2.启动RFT,新建Rational Functional Test项目点击桌面上的,打开Rational Functional Tester,选择工作空间后确定:进入RFT主界面:单击菜单栏上的“文件”-“新建”-“Functio
19、nal Test项目”输入项目名,点击完成:新建项目完成后的效果:3.录制脚本接下来要录制的是用户登录,进行购物后结算购物车的脚本。由于我的程序使用较高版本的JDK编译,可能会造成RFT提示找不到主类的错误:这是因为RFT自带的JRE版本过低,而低版本JRE无法识别高版本JDK编译出来的主类,所以录制脚本前需要将默认的JRE换成自己的JRE环境。具体方法如下:点击菜单栏-“配置”-“启用环境进行测试”在进行环境设置之前,点击“搜索”按钮,找出所有的JRE:如图是已经找到的JRE环境:选择新的jdk1.7作为运行时环境(JDK中本身就包含JRE环境),启用它并设置为缺省值。点击“完成”。点击菜单
20、栏“配置”-“配置应用环境进行设置”点击添加选择自己的应用程序:选择Java应用程序,点击“下一步”:点击浏览选择自己的程序:点击打开:这一步注意:一定要选定自己的jdk:点击完成:截止目前为止,录制前的准备工作就绪,可以录制脚本了右击项目名称,点击“使用记录器记录脚本”:编辑脚本名称,点击下一步:点击完成开始录制脚本:弹出一个小窗口:点击按钮启动应用程序:点击“确定”按钮启动应用程序,输入正确的用户名和密码【之前注册的】,点击登录按钮:随意买一些商品:点击某个商品,然后点击“查看商品详细信息”按钮:点击加入购物车:再买一些:查看购物车:点击“结账”按钮,提示购买成功,并显示总金额!购物车被清
21、零:点击退出登录按钮:点击“是”关闭程序。然后单击结束脚本录制。4.回放脚本点击工具栏上面的按钮回放脚本。采用默认的日志名称,点击下一步。点击完成:点击确定:脚本回放完成后弹出日志:RFT的日志目录下也出现了对应的日志文件:5.测试项目的导出选择保存脚本和日志文件,保存到桌面,然后点击完成。桌面上生成对应压缩文件:6.添加数据池使用数据池重新购买商品:编号商品名称购买数量1iPhone 6s Plus 64G32小米充电宝 14000mah103Mac Book Pro 15寸新款2点击菜单栏“文件”-“新建”-“测试数据池”编辑数据池名称:向数据池中加入数据:然后再给脚本添加数据池关联,在脚
22、本资源管理器中添加:选择刚创建的数据池user:点击菜单栏上的“脚本”-“查找字面值并替换为数据池引用”将字面值“2”替换为数据池中购买数量一列:以此类推,将字面值iPhone 6s Plus 64G换成商品名称一列。回放脚本,注意将数据池迭代次数改为“重复直到完成”:回放过程中可以看到数据池中的值会循环输入,回放完成后可以查看日志:日志显示回放过程中没有问题。7.添加验证点再录制一个脚本,使用王凯登陆。登陆成功后添加第一个验证点,对购物车中商品数量进行验证,刚登陆的时候购物车中商品数量应该为0。此验证点可以通过。然后购买2个手表,添加到购物车,再对购物车中的商品数量进行检测,此时数量应该是2,但是由于程序内部逻辑有错误,这里会显示1,因为程序计算的实际上是商品的种类而不是数量。所以第二个验证点无法通过。执行脚本,从日志可以发现感刚刚设置的验证点一个通过,一个不通过,完全符合预期: