博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Testcomplete4测试delphi应用程序的实现

Posted on 2006-12-01 22:54  luzao  阅读(1435)  评论(6编辑  收藏  举报

                                       Testcomplete4测试delphi应用程序的实现

                                                                                             Authorwuguofeng

                                                                                                  Date2006-10-06

Testcomplete能进行单元测试、性能测试、功能测试,能很好的识别Borland DelphiC++BuilderSybase
PowerBuilder
Java .NET开发的应用程序,像TDBGrid这种难以处理和不是标准的Win32控件也可以很好的支
持。
Testcomplete有强大的脚本编写能力,支持Jscript C++ScriptC#ScriptDelphiSriptVBScript等多种脚本
语言,还能实时的对脚本进行语法检查。下面通过一个实际的例子如何使用
testcomplete4Delphi应用程序进行
脚本的录制;建立图片、属性值的检查点;向
TDBGrid控件输入和获取信息;从CSV文件中读取用例数据;从
数据库中获取预期结果。

         被测程序“MastApp”是安装Delphi时自带的一个示例程序,在Delphi的安装目录\ Borland\Delphi6\Demos\Db
下可以找到

 

测试任务是:

1、新建一个订单,选择一个被开订单的消费者名称,验证显示的消费者号码(CustNo)和地址是否正确;
2、从产品信息界面的列表中获得所有的产品编号(PartNo),并随机的选择一个产品编号输入到订单详细列表
的PartNo字段中。
3、从CSV文件中读取数量(Qty)和折扣(Discount)输入到订单详细列表中,从列表中获取销售单价
(SellPrice),计算出预期总额,并与实际显示的总额(ExtPrice)进行比较。
4、查询数据库验证录入的订单信息有没有正确的保存。
在脚本录制之前把三个testcomplete对Delphi的扩展库文件加入到被测程序的项目中,这三个文件:
TCOpenApp.pas、tcOpenAppClasses.pas、tcPublicInfo.pas在testcomplete的安装目录Automated QA\TestComplete 4
\Open Apps\Delphi&BCB下可以找到,并在Delphi的编译器的Project菜单下Options进行如下设置:

 
把Linker tab 页的Include TD32 debug info勾上,然后重新编译生成新的应用程序。这些操作只是针对Delphi开发
的应用程序。
       现在开始脚本的录制,运行testcomplete4,单击菜单“File”|“New”|“New Project”,在弹出的“Create New
Project”界面中选择“General-Purpose Test Project”模板,项目名称、保存路径、测试套名称自己定,脚本语言选
择“DelphiScript”,单击“OK”,“Finish”,现在已经新建完成了一个测试项目,在左边的“Project Explorer”资
源管理器中的“TestedApps”上单击右键点击“Add”|“New Item”把被测程序加进来,在被测程序名上右击,点
击“Run”运行被测程序,单击工具栏上的 录制按钮开始脚本的录制,录制的脚本如下:
procedure Test1;
 var p1 : OleVariant;
 var w1 : OleVariant;
 var w2 : OleVariant;
begin
 p1 :
= Sys.Process('mastapp');
 p1.VCLObject('MainForm').VCLObject('OrderBtn').Click(42, 28);
 w1 := p1.VCLObject('EdOrderForm').VCLObject('HeaderPanel');
 w1.VCLObject('CompanyCombo').Click(150, 10);
 w2 := p1.Window('TPopupDataList', '', 1);
 w2.VScroll.Pos := 0;
 w2.Click(
5561);
  
//对CustNo建立了一个属性值检查点。
 
if not Objects.Compare(Sys.Process('mastapp').VCLObject('EdOrderForm').VCLObject('HeaderPanel').VCLObject('CustNoEdit'), 'VCLObject_CustNoEdit_') then
Log.Error('Objects are not identical.');
  //对消费者地址建立了一个图片检查点。
if not
Regions.Compare(
'addres.bmp',Sys.Process('mastapp').VCLObject('EdOrderForm').VCLObject('HeaderPanel').VCLObject('CustAdd1Edit')) then
 Log.Error('The regions are not identical.');
 w1.VCLObject('SoldByCombo').Click(99, 8);
 w2 := p1.Window('TPopupDataList', '', 1);
 w2.VScroll.Pos := 0;
 w2.Click(
4249);
 w1.VCLObject(
'ItemsGrid').Click(47, 26);
end;
上面通过脚本录制创建了两个检查点,创建属性值检查点的方法是单击“Recording”工具栏上的“Stores object
properties”

在弹出的“Add Text to Script”界面上单击“Add”把自动生成的代码添加到脚本中。
创建图片检查点的方法类似,只是单击“Recording”工具栏上的 ,单击 保存图片。
       在脚本中编写两个函数:“readfile”、“queryDb”
//========================================================
 
//函数readfile用于读取指定文件的内容并传给数组
 
//输入参数filename是要获取内容的文件名
 
//输出参数Result
 
//========================================================
 
function readfile(filename: string):olevariant;
 
const
 forreading 
=1;
 forwriteing 
=2;
 forappending
=8;
 var 
 fs,f :olevariant;
 
//在testcomplete中定义数组必须指定数组的长度,这是一个很不方便的地方。
 txtary : 
array[1..3]of string ;
 i : 
integer;
 begin
    fs:
=sys.oleobject('scripting.filesystemobject');
    f:=fs.opentextfile(filename,forreading,true);
    
while not f.atendofstream do
    begin
    
for i:=1 to 3 do
    begin
    txtary[i]:
=f.readline;
    
end;
    
end;
    result:
=txtary; 
 
end;
 
//==============================================================
 
//函数 queryDb 从数据库中获取数据
 
//输入参数 databasename指定的数据库名,cmdtxt所要执行的命令语句。
 
//输出参数result类型为数据集
 
//==============================================================
function queryDb(databasename: string,cmdtxt:string):olevariant;
var
cmd : olevariant;
S:
string;
begin
  { cmd:
=ado.createadocommand;
   
//访问Access数据库使用下面的连接信息。
   cmd.connectionstring:
='provider=microsoft.jet.oledb.4.0;data source=' + databasename;
   //查询MSSQL数据库使用下面的连接信息。
 
// cmd.connectionstring:='provider=SQLOLEDB;persist security info=false;data source='+ 
   //databasename +';user id=sa;password=sa;initial catalog=this4';
   cmd.commandtype:=cmdtext;
   cmd.commandtext:
=cmdtxt;
   result:
=cmd.execute;}
 
//BDE数据库使用下面的代码。
   cmd:
=BDE.createquery;
   cmd.databasename:
=databasename;
 cmd.sql:
=cmdtxt;
 cmd.open;
 cmd.first;
 S:
='';
 while not VarToBool(cmd.EOF) do
 begin
    
for i := 0 to cmd.FieldCount - 1 do
      S :
= S + cmd.Field(i).AsString ;
    
// S := S + Chr(13+ Chr(10);
     cmd.next; 
     
end;
     result:
=S;
end

对脚本进行扩充修改如下:
procedure main;
 
const
 fi
='c:\GridData.csv';
 var p1,w1,w2 : OleVariant;
 pic,facttotal,expecttotal,subtotal :olevariant;
 var ds:olevariant;
 var i,x,y: 
integer;
 inqty:
integer;           //输入的数量
 indis:
string;            //输入的折扣
 noary : 
array[1..59];    //用于保存所有的产品编号,数组必须定义长度真是不方便.
 caseary :
array[1..4];    //保存从文件读取的用例数据
 partary :
array[1..4];    //保存定单的产品编号
 tmp,datastr,sqlstr,dbname,itemtotal: 
string;
 partcut,orderno:olevarint;
begin
 p1 :
= Sys.Process('mastapp');
 p1.VCLObject('MainForm').VCLObject('OrderBtn').Click(42, 28);
 w1 := p1.VCLObject('EdOrderForm').VCLObject('HeaderPanel');
 w1.VCLObject('CompanyCombo').Click(150, 10);
 w2 := p1.Window('TPopupDataList', '', 1);
 w2.VScroll.Pos := 0;
 w2.Click(
5561);
 
if not Objects.Compare(Sys.Process('mastapp').VCLObject('EdOrderForm').VCLObject('HeaderPanel').VCLObject('CustNoEdit'), 'VCLObject_CustNoEdit_') then
    Log.Error('Objects are not identical.');
 if not  Regions.Compare('addres.bmp', Sys.Process('mastapp').VCLObject('EdOrderForm').VCLObject('HeaderPanel').VCLObject('CustAdd1Edit')) then
Log.Error('The regions are not identical.');
 w1.VCLObject('SoldByCombo').Click(99, 8);
 w2 := p1.Window('TPopupDataList', '', 1);
 w2.VScroll.Pos := 0;
 w2.Click(
4249);
 
//使订单Grid获得焦点,这里使用的是坐标值但并不影响Grid的识别,
 
//因为它是相对于Grid的位置而不是整个屏幕。 
 w1.VCLObject(
'ItemsGrid').Click(47, 26);
 w2 := w1.VCLObject('ItemsGrid'); 
 //获得产品信息界面中所有的产品编号,保存在数组noary中。
 w1:
=p1.VCLObject('SearchDlg').VCLObject('DBGrid1');
 //通过DBGrid的dataset数据集属性取得数据。
 ds:
=w1.datasource.dataset;
 ds.first;
 
while not vartobool(ds.eof) do
 begin
 
for i:=1 to ds.recordcount do 
    begin
      noary[i]:
=ds.fields.fields[0].asvariant;
      ds.next;
    
end;
 
end
 
//调用读文件函数
   caseary:
= readfile(fi);
   subtotal:
=0;
   
//向定单列表中插入数据,vararrayhighbound函数获得数组的长度。
   
for x:=1 to vararrayhighbound(caseary,1do
   begin 
    tmp:
=caseary[x];
    
//POS函数用来取得","在字符串中第一次出现的位置
    
//COPY函数从字符串中截取指定位置和长度的字符
    y:
=pos(',',tmp);
    inqty:=copy(tmp,0,y-1);
    indis:
=copy(tmp,y+1,length(tmp));
    
//单击界面上的新增按钮
p1.VCLObject(
'EdOrderForm').VCLObject('Speedbar').VCLObject('DBEditBtns').VCLObject('TNavButton_5').click;
    //随机获取一个产品编号,输入DBGrid中                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
    i:
=random(2,59);
    w2.keys(noary[i]);
    w2.keys(
'[Enter]');
    partary[x]:=noary[i];
    w2.keys(
'[Right][Right]');
    //获取DBGrid中的单价。
    pic:
=w2.selectedfield.text;
    w2.keys(
'[Right]');
    //输入数量。
    w2.keys(inqty);
    w2.keys(
'[Enter]');
    w2.keys('[Right]');
    //输入折扣。
    w2.keys(indis);
    w2.keys(
'[Enter]');
    w2.keys('[Right]'); 
   //获得界面实际显示的小计。
    facttotal:
=w2.selectedfield.text;
    subtotal:
=subtotal+facttotal;
    
//计算预期的小计,vartofloat类型转换函数。
    expecttotal:
=(vartofloat(pic)*inqty-(vartofloat(pic)*inqty*(strtofloat(indis)*0.01)));
    
//实际的与预期的进行对比。
    
if facttotal=expecttotal then
      
//向测试结果报告中写入信息。
      
log.message('第 '+ inttostr(x) +' 订单小计计算正确')
      else
      
log.error('第 '+ inttostr(x) +' 订单小计计算错误,实际显示的:'+ vartostr(facttotal)+',预期的:'+vartostr(expecttotal));
   w2.keys('[Left][Left][Left][Left][Left]');
   end
  
//单击保存按钮。   
   w1:
=p1.VCLObject('EdOrderForm').VCLObject('HeaderPanel'); 
   w1.VCLObject('PostBtn').click;
 //获得定单号。
   orderno:
=p1.VCLObject('EdOrderForm').VCLObject('DBText1').text;                                                      
   dbname:='dbdemos';
   //调用数据库查询函数,查出数据库中的订单总额。 
   sqlstr:
='select itemstotal from orders where orderno='+orderno;
   itemtotal:=querydb(dbname,sqlstr);
  
//查询数据库中订单详细数量。
   sqlstr:
='select count(*) from items where orderno='+orderno;
   partcut:=querydb(dbname,sqlstr); 
  
//比较实际的与数据库中的总额。
   
if itemtotal=subtotal then
      
log.message('数据库中的总金额正确')
   else
      
log.error('数据库中的总金额错误'); 
  //比较订单的详细数量。
   
if partcut=vararrayhighbound(partary,1then 
      
log.message('数据库中的明细正确')
   else
      
log.error('数据库中的明细错误'); 
end;
 
相关宝贝
★经典双珠地短袖POLO衫 紫色
¥99.00元
★经典双珠地短袖POLO衫 紫色 点击这里给我发消息
★经典双珠地短袖POLO衫 法国蓝色
¥99.00元
★经典双珠地短袖POLO衫 法国蓝色 点击这里给我发消息
★经典双珠地短袖POLO衫 橙色
¥99.00元
★经典双珠地短袖POLO衫 橙色 点击这里给我发消息
★经典双珠地短袖POLO衫 浅黄色
¥99.00元
★经典双珠地短袖POLO衫 浅黄色 点击这里给我发消息
★经典双珠地短袖POLO衫 玫瑰粉色
¥99.00元
★经典双珠地短袖POLO衫 玫瑰粉色 点击这里给我发消息
★经典双珠地短袖POLO衫 紫罗兰色
¥99.00元
★经典双珠地短袖POLO衫 紫罗兰色点击这里给我发消息
★经典双珠地短袖POLO衫 薰衣草色
¥99.00元
★经典双珠地短袖POLO衫 薰衣草色 点击这里给我发消息
★经典双珠地短袖POLO衫 湖蓝色
¥99.00元
★经典双珠地短袖POLO衫 湖蓝色 点击这里给我发消息