-
白盒测试中的六种覆盖方法zhuan
2009-08-12 13:47:39
白盒测试中的六种覆盖方法摘要:白盒测试作为测试人员常用的一种测试方法,越来越受到测试工程师的重视。白盒测试并不是简单的按照代码设计用例,而是需要根据不同的测试需求,结合不同的测试对象,使用适合的方法进行测试。因为对于不同复杂度的代码逻辑,可以衍生出许多种执行路径,只有适当的测试方法,才能帮助我们从代码的迷雾森林中找到正确的方向。本文介绍六种白盒子测试方法:语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、条件组合覆盖、路径覆盖。
白盒测试的概述
由于逻辑错误和不正确假设与一条程序路径被运行的可能性成反比。由于我们经常相信某逻辑路径不可能被执行, 而事实上,它可能在正常的情况下被执行。由于代码中的笔误是随机且无法杜绝的,因此我们要进行白盒测试。
白盒测试又称结构测试,透明盒测试、逻辑驱动测试或基于代码的测试。白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及里面是如何运作的。白盒的测试用例需要做到:
·保证一个模块中的所有独立路径至少 被使用一次
·对所有逻辑值均需测试 true 和 false
·在上下边界及可操作范围内运行所有循环
·检查内部数据结构以确保其有效性
白盒测试的目的:通过检查软件内部的逻辑结构,对软件中的逻辑路径进行覆盖测试;在程序不同地方设立检查点,检查程序的状态,以确定实际运行状态与预期状态是否一致。
白盒测试的特点:依据软件设计说明书进行测试、对程序内部细节的严密检验、针对特定条件设计测试用例、对软件的逻辑路径进行覆盖测试。白盒测试的实施步骤:
1.测试计划阶段:根据需求说明书,制定测试进度。
2.测试设计阶段:依据程序设计说明书,按照一定规范化的方法进行软件结构划分和设计测试用例。
3.测试执行阶段:输入测试用例,得到测试结果。
4.测试总结阶段:对比测试的结果和代码的预期结果,分析错误原因,找到并解决错误。白盒测试的方法:总体上分为静态方法和动态方法两大类。
静态分析是一种不通过执行程序而进行测试的技术。静态分析的关键功能是检查软件的表示和描述是否一致,没有冲突或者没有歧义。
动态分析的主要特点是当软件系统在模拟的或真实的环境中执行之前、之中和之后 , 对软件系统行为的分析。动态分析包含了程序在受控的环境下使用特定的期望结果进行正式的运行。它显示了一个系统在检查状态下是正确还是不正确。在动态分析技术中,最重要的技术是路径和分支测试。下面要介绍的六种覆盖测试方法属于动态分析方法。白盒测试的优缺点
1. 优点
·迫使测试人员去仔细思考软件的实现
·可以检测代码中的每条分支和路径
·揭示隐藏在代码中的错误
·对代码的测试比较彻底
·最优化2. 缺点
·昂贵
·无法检测代码中遗漏的路径和数据敏感性错误
·不验证规格的正确性六种覆盖方法
首先为了下文的举例描述方便,这里先给出一张程序流程图。(本文以1995年软件设计师考试的一道考试题目为例,图中红色字母代表程序执行路径)。
1、语句覆盖
1)主要特点:语句覆盖是最起码的结构覆盖要求,语句覆盖要求设计足够多的测试用例,使得程序中每条语句至少被执行一次。
2)用例设计:(如果此时将A路径上的语句1—〉T去掉,那么用例如下)
X Y 路径 1 50 50 OBDE 2 90 70 OBCE 3)优点:可以很直观地从源代码得到测试用例,无须细分每条判定表达式。
4)缺点:由于这种测试方法仅仅针对程序逻辑中显式存在的语句,但对于隐藏的条件和可能到达的隐式逻辑分支,是无法测试的。在本例中去掉了语句1—〉T去掉,那么就少了一条测试路径。在if结构中若源代码没有给出else后面的执行分支,那么语句覆盖测试就不会考虑这种情况。但是我们不能排除这种以外的分支不会被执行,而往往这种错误会经常出现。再如,在Do-While结构中,语句覆盖执行其中某一个条件分支。那么显然,语句覆盖对于多分支的逻辑运算是无法全面反映的,它只在乎运行一次,而不考虑其他情况。
2、判定覆盖
1)主要特点:判定覆盖又称为分支覆盖,它要求设计足够多的测试用例,使得程序中每个判定至少有一次为真值,有一次为假值,即:程序中的每个分支至少执行一次。每个判断的取真、取假至少执行一次。
2)用例设计:
X Y 路径 1 90 90 OAE 2 50 50 OBDE 3 90 70 OBCE 3)优点:判定覆盖比语句覆盖要多几乎一倍的测试路径,当然也就具有比语句覆盖更强的测试能力。同样判定覆盖也具有和语句覆盖一样的简单性,无须细分每个判定就可以得到测试用例。
4)缺点:往往大部分的判定语句是由多个逻辑条件组合而成(如,判定语句中包含AND、OR、CASE),若仅仅判断其整个最终结果,而忽略每个条件的取值情况,必然会遗漏部分测试路径。
3、条件覆盖
1)主要特点:条件覆盖要求设计足够多的测试用例,使得判定中的每个条件获得各种可能的结果,即每个条件至少有一次为真值,有一次为假值。
2)用例设计:
X Y 路径 1 90 70 OBC 2 40 OBD 3)优点:显然条件覆盖比判定覆盖,增加了对符合判定情况的测试,增加了测试路径。
4)缺点:要达到条件覆盖,需要足够多的测试用例,但条件覆盖并不能保证判定覆盖。条件覆盖只能保证每个条件至少有一次为真,而不考虑所有的判定结果。
4、判定/条件覆盖
1)主要特点:设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身所有可能结果也至少出现一次。
2)用例设计:
X Y 路径 1 90 90 OAE 2 50 50 OBDE 3 90 70 OBCE 4 70 90 OBCE 3)优点:判定/条件覆盖满足判定覆盖准则和条件覆盖准则,弥补了二者的不足。
4)缺点:判定/条件覆盖准则的缺点是未考虑条件的组合情况。
5、组合覆盖
1)主要特点:要求设计足够多的测试用例,使得每个判定中条件结果的所有可能组合至少出现一次。
2)用例设计:
X Y 路径 1 90 90 OAE 2 90 70 OBCE 3 90 30 OBDE 4 70 90 OBCE 5 30 90 OBDE 6 70 70 OBDE 7 50 50 OBDE 3)优点:多重条件覆盖准则满足判定覆盖、条件覆盖和判定/条件覆盖准则。更改的判定/条件覆盖要求设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身的所有可能结果也至少出现一次。并且每个条件都显示能单独影响判定结果。
4)缺点:线性地增加了测试用例的数量。
6、路径覆盖
1)主要特点:设计足够的测试用例,覆盖程序中所有可能的路径。
2)用例设计:
X Y 路径 1 90 90 OAE 2 50 50 OBDE 3 90 70 OBCE 4 70 90 OBCE 3)优点:这种测试方法可以对程序进行彻底的测试,比前面五种的覆盖面都广。
4)缺点:由于路径覆盖需要对所有可能的路径进行测试(包括循环、条件组合、分支选择等),那么需要设计大量、复杂的测试用例,使得工作量呈指数级增长。而在有些情况下,一些执行路径是不可能被执行的,如:
If (!A)B++;
If (!A)D--;这两个语句实际只包括了2条执行路径,即A为真或假时候对B和D的处理,真或假不可能都存在,而路径覆盖测试则认为是包含了真与假的4条执行路径。这样不仅降低了测试效率,而且大量的测试结果的累积,也为排错带来麻烦。
总结
白盒测试是一种被广泛使用的逻辑测试方法,是由程序内部逻辑驱动的一种单元测试方法。只有对程序内部十分了解才能进行适度有效的白盒测试。但是贯穿在程序内部的逻辑存在着不确定性和无穷性,尤其对于大规模复杂软件。因此我们不能穷举所有的逻辑路径,即使穷举也未必会带来好运(穷举不能查出程序逻辑规则错误,不能查出数据相关错误,不能查出程序遗漏的路径)。
那么正确使用白盒测试,就要先从代码分析入手,根据不同的代码逻辑规则、语句执行情况,选用适合的覆盖方法。任何一个高效的测试用例,都是针对具体测试场景的。逻辑测试不是片面的测试正确的结果或是测试错误的结果,而是尽可能全面地覆盖每一个逻辑路径。
-
python语言
2009-05-27 14:03:21
python从一开始就是用类设计的,它是一门真正的纯面向对象的语言。
python是一门支持脚本编程的语言
用它来写脚本确实很棒的,你甚至会想用python脚本代替掉你所有的比处理文件,shell脚本和一些简单的程序。但是它远远超出了一门脚本语言。
1)对于python来说,作用域是通过缩进来确定的。
列如:
##interpreter:if.py
response="yes"
if response=="yes":
print"affirmative"
val=1
print "continuing……"
##~
<#代表注释>
2)python的if语句不一定要括号,"条件语句"使用冒号结束.
3)通常python每行只有一个语句(你也可以使用分号在一行上放置多个语句并把它们分开)
4)内置容器
容器之于编程语言的重要地位是通过把他们构建入语言核心来使其得到承认的:链表和关联数组(即映射表,字典,哈希表)都成了基本的数据类型.这使这门语言更加优雅.
5)python不需要任何类型说明,对象只要有名字就可以了,python会根据你使用它们的方式判断出其类型.
6)函数
在python里创建一个函数,需要用到def关键字,接下来是函数名和参数列表,然后是一个冒号表示函数体的开始.
由于是弱类型语言,所以函数签名的里并没有类型信息,它只是指定了函数名称和参数标签但是没有返回类型和参数类型.
7)python支持操作符重载,当+操作运用到不同的数据类型时,自动转意.
8)字符串
.1可以用单引号,双引号来表示字符串.可嵌套.
.2三个双引号连用.这种语法把他们之间的所有东西都引起来,包括新的行.
print """You're just poundingtwococonut halves together."""
.3一个字符串右边的r字符表示这个字符串是个"raw字符串",也就是说按照字面来解释反斜杠,所以你就不用再加个额外的反斜杠了.
print r'c:\python\lib\utils'
.4字符串替换,对于任何字符串,只需在字符全后面加上一个"%"和用来做替代的值.
print "The number is %d" % val
9)类
用class关键字定义类
class XXX:
def XXX:
self代替this指代的参数(当然可以自定义,一般默认的都认识)
class Simple:
def __init__(self, str):
print"Inside the Simple constructor"
self.s = str
def show(self):
def show(self):
def showMsg(self, msg):
print msg + ':',
self.show()
if __name__ == "__main__":
x = Simple("constructor argument")
x.show()
x.showMsg("A message")
##~
上面的第一个方法有它的特别之处,所有以双下划线开始并且结束的标示符都是特殊的。对于上面的情况来说,它定义了构造函数,当创建对象的的时候它会自动被调用,就像C++和Java那样。然而,在上例下半部分你会看到,对象的创建就像一次使用类名称的函数调用。Python宽松(spare)的语法会让你觉得C++或者Java里的new 关键字其实都不是必需的。
后一部分的所有代码被一个if语句隔开(set off) 了,这个if语句检查__name__这个东西是不是等于__main__。再说一次,双下划线意味着特殊的名字。使用if的原因是因为每一个文件都有可能在另外的程序里被用作库模块(马上就会讲到模块)。在那种情况下,你只需要那些定义好了的类,而不想让文件下半部分的代码被执行。这个特殊的if语句只有当你直接运行这个文件的时候才为真,也就是说,如果你在命令行输入:
Python SimpleClass.py
然而,如果这个文件是被另外一个程序作为一个模块引入的,那__main__的代码就不会被执行。
10)继承
而对Python来说,使用继承的唯一理由是为了继承一个实现——为了重用属于基类的代码。
如果你打算从某个类继承下来,你必须告诉Python把那个类引入的你的新文件。Python像Java那样对命名空间(name spaces)进行强有力的(aggressively)控制,而且风格也和Java类似(尽管如此,Python 保留着它一贯的简单性)。每次创建一个文件的时候,你就隐含的创建了一个和该文件同名的模块(类似于Java里的package)。这么一来,package关键字在Python里也不需要了。当你想要使用某个模块的时候,只要用import关键字,并且给出模块的名字就可以了。Python会搜索PYTHONPATH,Java用同样的方法搜索CLASSPATH(但是由于某种原因,Python并没有像Java那样的缺陷),然后读取搜索到的文件。要引用某个模块的函数或者类,你需要给出模块名称,接着是一个句号,然后是函数名或者类名。如果你觉得给出确切的名称太麻烦,你可以用:
#from module import name(s)
这里,“names(s)”可以是由逗号分开的一组名称。
from SimpleClass import Simple
class Simple2(Simple):
def __init__(self, str): -
转)vbs之createobject大全收藏
2009-04-22 16:23:45
ADO对象
Connection
Command
RecordSet
Record
Stream
Server.CreateObject("scrīpting.FileSystemObject")
Server.CreateObject("scrīpting.Dictionary") HashTable
Server.CreateXObject("Word.Application") //Server
ActiveXObject("Word.Application") //Client
Server.CreateObject("Excel.Application") //Server
ActiveXObject("Excel.Application") //Client
CreateObject("PowerPoint.Application")
Server.CreateObject("Microsoft.XMLHTTP")
Server.CreateObject("Microsoft.XMLDOM")
Server.CreateObject("MSXML2.XMLHTTP.4.0")
Server.CreateObject("Wscrīpt.Shell")
Server.CreateObject("wscrīpt.network")
Server.CreateObject("MSWC.AdRotator")
CreateObject("Excel.Sheet")
MS FrontPage: oFP = CreateObject("FrontPage.Application")
MS Access: oAccess = CreateObject("Access.Application")
MS Graph: oGraph = CreateObject("MSGraph.Application")
CreateObject("PhotoShop.Application")
CreateObject("SQLDMO.SQLServer")
CreateObject("SQLDMO.Login")
CreateObject("SQLDMO.Backup")
CreateObject("SQLDMO.User")
Server.CreateObject("SQLDMO.BackupDevice")
Server.CreateObject("SQLDMO.Database")
Server.CreateObject("SQLDMO.Restore")
Server.CreateObject("MSMQ.MSMQQueueInfo")
CreateObject("MSMQ.MSMQQuery")
Server.CreateObject("ixsso.Query")
Server.CreateObject("ixsso.Util")
AccPac Advantage Corporate:
oAccPac=CreateObject("ACCPAC.xapiSession")
AccPac Report Master for Windows:
oImpApp=CreateObject("Impromptu.Application.30")
BarTender:
oBarTender = CreateObject("BarTender.Application")
CrystalReports:
oCRApplication = createobject ("CrystalRuntime.Application")
This doesn't invoke an IDE actually.
EUDORA:
oEud = CreateObject("Eudora.EuApplication.1")
FaxMaker:
oFax = CREATEOBJECT("fmfaxapi.application")
GroupWise:
oGroupWise = CreateObject("NovellGroupWareSession")
LotusNotes:
oNotes = CreateObject("Notes.NotesSession")
oNotes = CreateObject("Notes.NotesUIWorkspace")
oNotes = CreateObject("Lotus.Notessession") (Domino 5.0.3)
MS Common Dialog:
oCommmonDialog = CreateObject("MSComDlg.CommonDialog") && !!! You can't directly create this object without a development licence, so for dynamically doing it on another machine, see below. -- PeterCrabtree
MS Internet Explorer:
oIE = CreateObject("InternetExplorer.Application")
IEAutomationExample
MS MapPoint:
oMapPoint = CreateObject("MapPoint.Application")
MSN Messenger:
oMessenger = CREATEOBJECT("MSNMessenger.MessengerApp")
MS NetMeeting:
oNetMeeting=CREATEOBJECT("netmeeting.app.1")
MS Outlook:
oOutlook = CreateObject("Outlook.Application")
MS Outlook Express: None - It is not a COM server!
MS PowerPoint:
oPP = CreateObject("PowerPoint.Application")
MS Project:
oProj = CreateObject("msProject.Application")
MS SourceSafe:
oVSS = CreateObject("SourceSafe.0")
MS Word:
oWord = CreateObject("Word.Application")
MS Visio:
oVisio = CreateObject("Visio.Application")
MS VisualCPlusPlus: (VC++)
oCpp = CreateObject("MSDev.Application")
MS VisualFoxpro:
oVFP = CreateObject("VisualFoxPro.Application")
MS WindowsscrīptingHost:
oWSH = CreateObject("Wscrīpt.Shell")
Novell GroupWise:
oGroupWise = CreateObject("NovellGroupWareSession")
PCAnywhere (host):
oPCAHost = CreateObject("WinAWSvr.BeHostDataManager")
PCAnywhere (remote):
oPCARem = CreateObject("WinAWSvr.RemoteDataManager")
QuickBooks:
QBSessionManager = CreateObject("QBFC2.QBSessionManager")
RationalRose:
oRose = CreateObject("Rose.Application")
TAPIFax:
oTAPIFax = CreateObject('FaxServer.FaxServer')
WindowsShell:
oWSH = CreateObject("Shell.Application")
Windows Media Player:
oWMP = CREATEOBJECT("WMPlayer.OCX")
oPlayList = oWmp.PlaylistCollection.GetAll()
oWmp.currentPlaylist = oPlayList.Item(0) && Zero based array
*!* Music starts!
Windows Messenger:
oMessenger = CREATEOBJECT("Messenger.MessengerApp")
WinFax:
oWinFax = CreateObject("WinFax.SDKSend")
WinPrint :
oWinPrint = CreateObject("WinPrint.WinPrintX")
SQL-DMO object:
loSQL = CREATEOBJECT("SQLDMO.Application")
Others:
scrīpting Shell:
oShell = CreateObject("Wscrīpt.Shell")
scrīpting Network Object:
oNet = CreateObject("Wscrīpt.Network")
scrīpting Regular Expression Parser:
oReg = CreateObject("VBscrīpt.RegExp")
SQL DMO SQL Server:
CreateObject("SQLDMO.SQLServer") -
转VBS控制Excel常见方法
2009-03-03 10:04:32
(一) 使用动态创建的方法
首先创建 Excel 对象,使用ComObj:
oExcel = CreateObject( "Excel.Application" )
1) 显示当前窗口:
oExcel.Visible = True2) 更改 Excel 标题栏:
oExcel.Caption = "应用程序调用 Microsoft Excel"3) 添加新工作簿:
oExcel.WorkBooks.Add4) 打开已存在的工作簿:
oExcel.WorkBooks.Open( "C:\Excel\Demo.xls" )5) 设置第2个工作表为活动工作表:
oExcel.WorkSheets(2).Activate
或
oExcel.WorksSheets( "Sheet2" ).Activate6) 给单元格赋值:
oExcel.Cells(1,4).Value = "第一行第四列"7) 设置指定列的宽度(单位:字符个数),以第一列为例:
oExcel.ActiveSheet.Columns(1).ColumnsWidth = 58) 设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例:
oExcel.ActiveSheet.Rows(2).RowHeight = 1/0.035 ' 1厘米9) 在第8行之前插入分页符:
oExcel.WorkSheets(1).Rows(8).PageBreak = 110) 在第8列之前删除分页符:
oExcel.ActiveSheet.Columns(4).PageBreak = 011) 指定边框线宽度:
oExcel.ActiveSheet.Range( "B3:D4" ).Borders(2).Weight = 3
1-左 2-右 3-顶 4-底 5-斜( \ ) 6-斜( / )12) 清除第一行第四列单元格公式:
oExcel.ActiveSheet.Cells(1,4).ClearContents13) 设置第一行字体属性:
oExcel.ActiveSheet.Rows(1).Font.Name = "隶书"
oExcel.ActiveSheet.Rows(1).Font.Color = clBlue
oExcel.ActiveSheet.Rows(1).Font.Bold = True
oExcel.ActiveSheet.Rows(1).Font.UnderLine = True14) 进行页面设置:
a.页眉:
oExcel.ActiveSheet.PageSetup.CenterHeader = "报表演示"
b.页脚:
oExcel.ActiveSheet.PageSetup.CenterFooter = "第&P页"
c.页眉到顶端边距2cm:
oExcel.ActiveSheet.PageSetup.HeaderMargin = 2/0.035
d.页脚到底端边距3cm:
oExcel.ActiveSheet.PageSetup.HeaderMargin = 3/0.035
e.顶边距2cm:
oExcel.ActiveSheet.PageSetup.TopMargin = 2/0.035
f.底边距2cm:
oExcel.ActiveSheet.PageSetup.BottomMargin = 2/0.035
g.左边距2cm:
oExcel.ActiveSheet.PageSetup.LeftMargin = 2/0.035
h.右边距2cm:
oExcel.ActiveSheet.PageSetup.RightMargin = 2/0.035
i.页面水平居中:
oExcel.ActiveSheet.PageSetup.CenterHorizontally = 2/0.035
j.页面垂直居中:
oExcel.ActiveSheet.PageSetup.CenterVertically = 2/0.035
k.打印单元格网线:
oExcel.ActiveSheet.PageSetup.PrintGridLines = True15) 拷贝操作:
a.拷贝整个工作表:
oExcel.ActiveSheet.Used.Range.Copy
b.拷贝指定区域:
oExcel.ActiveSheet.Range( "A1:E2" ).Copy
c.从A1位置开始粘贴:
oExcel.ActiveSheet.Range.( "A1" ).PasteSpecial
d.从文件尾部开始粘贴:
oExcel.ActiveSheet.Range.PasteSpecial16) 插入一行或一列:
a. oExcel.ActiveSheet.Rows(2).Insert
b. oExcel.ActiveSheet.Columns(1).Insert17) 删除一行或一列:
a. oExcel.ActiveSheet.Rows(2).Delete
b. oExcel.ActiveSheet.Columns(1).Delete18) 打印预览工作表:
oExcel.ActiveSheet.PrintPreview19) 打印输出工作表:
oExcel.ActiveSheet.PrintOut20) 工作表保存:
if not oExcel.ActiveWorkBook.Saved then
oExcel.ActiveSheet.PrintPreview21) 工作表另存为:
oExcel.SaveAs( "C:\Excel\Demo1.xls" )22) 放弃存盘:
oExcel.ActiveWorkBook.Saved = True23) 关闭工作簿:
oExcel.WorkBooks.Close24) 退出 Excel:
oExcel.Quit(二) 使用VBS 控制Excle二维图
1)选择当第一个工作薄第一个工作表
set Sheet=oExcel.Workbooks(1).Worksheets(1)2)增加一个二维图
achart=oSheet.chartobjects.add(100,100,200,200)3)选择二维图的形态
achart.chart.charttype=44)给二维图赋值
set series=achart.chart.seriescollection
range="sheet1!r2c3:r3c9"
series.add range,true5)加上二维图的标题
achart.Chart.HasTitle=True
achart.Chart.ChartTitle.Characters.Text=" Excle二维图"6)改变二维图的标题字体大小
achart.Chart.ChartTitle.Font.size=187)给二维图加下标说明
achart.Chart.Axes(xlCategory, xlPrimary).HasTitle = True
achart.Chart.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "下标说明"8)给二维图加左标说明
achart.Chart.Axes(xlValue, xlPrimary).HasTitle = True
achart.Chart.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "左标说明"9)给二维图加右标说明
achart.Chart.Axes(xlValue, xlSecondary).HasTitle = True
achart.Chart.Axes(xlValue, xlSecondary).AxisTitle.Characters.Text = "右标说明"10)改变二维图的显示区大小
achart.Chart.PlotArea.Left = 5
achart.Chart.PlotArea.Width = 223
achart.Chart.PlotArea.Height = 108 -
qtp知识
2009-01-04 13:26:27
1 检查页面是否存在
对象exist可以检查某一个页面是否存在。
代码:
if Browser("…").Page(“…").Exist then
‘在运行结果中显示的报告, “micPass”的状态是通过, micFail是不通过
reporter.ReportEvent micPass ,“页面存在“,”通过“
else
reporter.ReportEvent micFail ,"页面不存在“,"不通过"
end if7.2 防止程序中断的方法
在回放脚本的时候,有时因为错误导致运行的脚本中断,不能自动运行。为了能达到真正无人职守的状态可以在脚本的最前面加上如下的代码:
On error resume next ‘遇到错误返回到脚本的下一行继续执行。
On error goto 0 ‘错误处理的控制权,平时是由QTP控制的(这个叫默认的),当有on error resume next 时,是交给on error处理,当on error goto 0时,就换给QTP7.3 同步点的设定
等待某一对象出现后继续执行,为了防止qtp找不到对象而设定同步点。有2种方法:1种是用wait加等待的时间,如wait 5(qtp等待5秒钟后继续执行)。另一种方法是等待要执行对象的出现,如果出现就继续执行,否则一直等待,代码如下:
y=......waitproperty("visible",true,10000)
If y=true then
‘执行下一条语句
else
’对象不出现就一直等待,直到过了10000秒后程序找不到对象报错
End if7.4 截屏
在优化脚本时,如果想查看某一页面在执行后的页面效果,可以采取截屏的办法截取当前的操作页面并保存到本地。代码:
desktop. capturebitmap “c:\***.bmp“,ture ’在脚本中想要查看的一行插入,运行后图片保存到设置的路径下
7.5 导入execl文件并参数化数据方法
Qtp自带了datatable表,可以把要参数化的数据写在里面,但这样写脚本和数据不能分离,后期不好维护脚本。现在采用从外部导入execl文件的方法导入数据。代码如下:
datatable.ImportSheet “D:\...\data.xls”,“sheet1”,“global“
‘第一个参数是要导入文件的路径,第二个是execl的第一个表格,第三个参数是在execl的全局范围内查找另外datatable对象还有很多操作,比如:获取表中字段的行数,插入表数据,删除数据等,下面是获取表中数据的代码:datatable("A","dtglobalsheet)
7.6 为描述性编程自动创建注释
当希望在每一个新建action时都增加一些头部说明,比如作者、创建日期、说明等信息,那么用action template 来实现最简单快捷。 方法:用记事本等文本编辑器,输入如下类似的内容: 'Company:东方般若 'Date: Date 然后将文件保存为ActionTemplate.mst,并存放到QTP安装目录下的dat目录。7.7 导入vbs文件
想要实现脚本的函数化,并更好的维护它,可以把一些公用的函数写到vbs里面,用qtp来调用它。
实现调用vbs的方法有2种:
1.函数executefile加vbs文件的路径
executefile “c:\...\funcation.vbs”2.设置QTP test/settings/resources/+函数目录
7.8 时间差函数
统计两个日期时间段之间的间隔,还有多少小时
Dim timediff
timediff=datediff(“H”,now,“2008-8-8” )
Print timediff
7.9 获取web下拉框中数据的行数和数据值
1.获取行数:首先将webtable添加到对象库中,查看对象库里有该webtable的属性后
count=Browser("…").Page("Page").Frame("…").WebTable("...").RowCount
Msgbox count ‘查看行数
2.获取数据值,
for i=1 to count
value=Browser("…").Page("Page").Frame("…").WebTable("...").getcelldata(i,1)
msgbox value
next
获取到列表中的数值后,qtp的对象库中没有这个WebElement的对象,一般采用描述性编程的方法获取对象,比如:用getcelldata获取的表中数据的innertext属性是“普通岗”,那么就可以用如下代码:
for i=1 to count
value=Browser("…").Page("Page").Frame("…").WebTable("...").getcelldata(i,1)
Browser(“…”).Page(“Page”).Frame(“…”). WebElement(“innertext:=“&value,”index:=1”).click
next7.10 对象获得焦点
判断某个webedit输入框是否获取了焦点,如果没有获取就给它焦点,然后输入数值。代码如下:if not browser("**").page(“**").webedit(“
**").object.isdisabled then
.object.focus
.object.set "输入数值“7.11 获取对象当前属性值
用GetROProperty可以获取对象的当前属性值,比如一些对象的属性经常发生变化,用getroproterty就能定位对象当前的属性状态来执行相应的操作。
Dim pro
pro= browser("**").page(“**").webedit(“
**“). GetROProperty(“property”,value)
Msgbox pro ‘弹出窗口,查看获取的属性。7.12 Systemutil对象的应用
利用systemutil可以实现的功能:回放qtp脚本时禁止鼠标和键盘的输入;打开应用程序或web;通过句柄关闭进程;通过进程名关闭进程等。下面的代码是打开百度网页:
systemutil.run “iexplore.exe”,“http://www.baidu.com”,“”,“”,“”,3 ‘打开百度的首页,最后面的参数“3” 代表打开ie后最大化
SystemUtil.CloseProcessByName(“iexplore.exe”) ‘关闭ie
7.13 Action的使用
action分为内部调用和外部调用2种方法:内部调用使用split划分;外部调用时被调用的action设置成share,并共享对象库。
split action:RunAction "action", oneIteration
7.14. 随即数在测试中有时会用到随即数,有多种方法:
第一种 :n=randomnumber.value(1,255) ’n的值从1到255之间随即产生第二种 :randomize ‘更新反回的数据 dim n
n=int (10*rnd())
msgbox n ‘n为10以内的整数
7.15 “is+*”类型功能
isarray'是否是数组 isconnected'判断QTP是否连接到TD isdate'是否是合法的日期类型 isempty'判断是否初始化 isNull'判断是否为空值 isNumeric'判断是否是数字型 isobject'判断是否一个功能对象 isready'判断设备是否准备就绪 isRootFolder'是否是根目录
7.16 对象库打开对象库resources->object repository,或者用快捷方式:ctrl+r来打开。
1.Qtp中的对象库和脚本是一一对应的,如果脚本中某个对象在对象库中不存在,则无法回放成功,会提示找不到对象。
2.对无法识别的对象用spy工具获得后添加到对象库中。
3.有时候脚本回放失败就是找不到对象的原因,可以通过用spy工具查看找不到对象的属性,然后打开对象库,比较二者的属性信息,如果属性有不相同的说明就是属性的原因,可以通过更改属性的方式统一对象属性。
7.17 调试脚本
1.脚本编写完毕,可以用按ctrl+f7来查看脚本是否有语法错误。
2. Msgbox和print:在回放脚本时可以方便的查看自己想看到的信息。
3.设置断点:为了测试某一小段脚本的功能,而当整个action很长的时
候,可以设置断点单步debug。
7.18 强制退出
遇到问题退出可以用exittest或 exit for,例如下面代码:Public function text_exit()
for i=0 to 10
if i=3 then
exittest
‘exit for
end if
next
End functionText_exit()
7.19 连接数据库_增删改
Dim conn,strSql '定义变量
set conn = CreateObject("ADODB.Connection") '创建连接
conn.ConnectionString="Provider=SQLOLEDB.1;Password=isaac121379;Persist Security Info=True;User ID=sa;Initial Catalog=WisdomCRM;Data source=192.168.12.29" '设置连接字符串
conn.open '开启连接
'strSql="insert into UM_User values(1,'UserID')" '设置插入语句
strSql="drop table TM_Task_14_Target"
'strSql="select * from UM_User"If conn.state=0 Then '如果连接状态为0,表示连接失败,写入reporter对象中,否则表示连接成功
Reporter.ReportEvent micFail,"testing","数据库连接失败"
conn.close
Set conn = nothing
else
Reporter.ReportEvent micPass,"testing","数据库连接成功"
conn.execute strSql '执行更新语句
conn.close
Set conn = nothing
End If
7.20 连接数据库_查
Dim conn,res,strSql '定义变量
set conn = CreateObject("ADODB.Connection") '创建连接
conn.ConnectionString="Provider=SQLOLEDB.1;Password=isaac121379;Persist Security Info=True;User ID=sa;Initial Catalog=WisdomCRM;Data source=192.168.12.29" '设置连接字符串
conn.open '开启连接
Set res = CreateObject("ADODB.RecordSet") '创建一个记录集对象
strSql="select * from UM_User" '设置查询雨具
If conn.state=0 Then '如果连接状态为0,表示连接失败,写入reporter对象中,否则表示连接成功
Reporter.ReportEvent micFail,"testing","数据库连接失败"
res.close '关闭结果集和连接,并且置为空
Set res = nothing
conn.close
Set conn = nothing
else
Reporter.ReportEvent micPass,"testing","数据库连接成功"
res.open strSql,conn '执行查询语句
res.MoveFirst '将记录集游标指到记录集的最开始
Do
Reporter.ReportEvent micPass,"file",cstr(res(0))+" : "+cstr(res(1)) '循环遍历查询结果,并且保持到reproter对象中,直到记录集到达末尾,循环结束
res.MoveNext
Loop until res.eof = true
res.close
Set res = nothing
conn.close
Set conn = nothing
End If
低级录制
在无法识别对象时使用
利用Vbs运行外部程序
WSH也就是用来解析Vbs的宿主,本身包含了几个个常用对象:
1、scrīpting.FileSystemObject —> 提供一整套文件系统操作函数
2、scrīpting.Dictionary —> 用来返回存放键值对的字典对象
3、Wscrīpt.Shell —> 提供一套读取系统信息的函数,如读写注册表、查找指定文件的路径、读取DOS环境变量,读取链接中的设置
4、Wscrīpt.NetWork —>
提供网络连接和远程打印机管理的函数。(其中,所有scrīpting对象都存放在SCRRUN.DLL文件中,所有的Wscrīpt对象都存放在WSHOM.ocx文件中。)
现在我们需要的是第三个对象,好了,让我们先连接一下对象看看,在记事本的编辑窗口中输入:
Set ōbjShell = CreateObject(“Wscrīpt.Shell”)
objShell.Run “notepad”
Objshell.run “calc”
自建日志
Public Sub logfile(message)
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fileSystemObj, fileSpec
Dim currentTime
currentDate = Date
currentTime = Time
testName = "log"
Set fileSystemObj = CreateObject("scrīpting.FileSystemObject")
fileSpec ="f:\log.txt"
If Not (fileSystemObj.FileExists(filespec)) Then
Set logFile = fileSystemObj.CreateTextFile(fileSpec, ForWriting, True)
logFile.WriteLine("###############################################")
logFile.WriteLine (currentDate & currentTime & " Test: " & environment.Value("TestName") )
logFile.WriteLin("######################################")
logFile.Close
Set logFile = Nothing
End If
Set logFile = fileSystemObj.OpenTextFile(fileSpec, ForAppending, False, True)
logFile.WriteLine (currentDate & " "& currentTime & " " & message)
logFile.Close
Set logFile = Nothing
Set fileSystemObj = Nothing
End Sub
logfile(“ok")
Vb6生成dll
Environment对象
检查页面文字显示颜色
Set Elements = Browser(“WisdomCRM客户关系管理系统”).Object.Document.all.tags(“div”)’tags(“td”)为在td中检查
For each Element in Elements
If Element.InnerText="执行团队" Then
strhtml=Element.Innerhtml
n=instr(strhtml,"color=red")
If n=0 Then
msgbox "Text color is red!"
exit for
End If
End If
Next
关闭重复的页面
Dim loginwin
Set loginwin = descrīption.Create() '创建对象名为loginwin的对象
loginwin( "name").value="WisdomCRM客户关系管理系统" ',对象属性及值
Set child=desktop.ChildObjects (loginwin)
cout=child.count
msgbox cout
For i=1 to cout
child(i-1).close '循环寻找这个对象
Next
获取当前测试的路径
Path = environment("TestDir")'获取当前测试的路径
msgbox path
获取本机ip
set IPConfigSet = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
("select IPAddress from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")for each IPConfig in IPConfigSet
if Not IsNull(IPConfig.IPAddress) then
for i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
Msgbox IPConfig.IPAddress(i)
next
end if
next
点亮对象
highlight
fireEvent用法
针对Link对象,onmouseover时间, 还有onchange, onclick, ondblclick, onblur, onfocus, onmousedown, onmouseup, onmouseout, onsubmit, onreset, onpropertychange事件可以使用
sendkeys实例
Set wshshell=createobject(“wscrīpt.shell”)
其使用格式为:object.SendKeys string “object”:表示WshShell对象 “string”:表示要发送的按键指令字符串,需要放在英文双引号中。 1.基本键 一般来说,要发送的按键指令都可以直接用该按键字符本身来表示,例如要发送字母“x”,使用“WshShell.SendKeys "x"”即可。当然,也可直接发送多个按键指令,只需要将按键字符按顺序排列在一起即可,例如,要发送按键“happy”,可以使用“WshShell.SendKeys "happy"”。
sendkeys实例
2.特殊功能键 对于需要与Shift、Ctrl、Alt三个控制键组合的按键,SendKeys使用特殊字符来表示: Shift---------WshShell.SendKeys "+" Ctrl---------WshShell.SendKeys "^" Alt---------WshShell.SendKeys "%" 由于“+”、“^”这些字符用来表示特殊的控制按键了,如何表示这些按键呢? 只要用大括号括住这些字符即可。例如: 要发送加号“+”,可使用“WshShell.SendKeys "{+}"” 另外对于一些不会生成字符的控制功能按键,也同样需要使用大括号括起来按键的名称,例如要发送回车键,需要用“WshShell.SendKeys "{ENTER}"”表示,发送向下的方向键用“WshShell.SendKeys "{DOWN}"”表示。 Space---------WshShell.SendKeys " " Enter---------WshShell.SendKeys "{ENTER}" ←---------WshShell.SendKeys "{RIGHT}" ↑---------WshShell.SendKeys "{UP}" F1---------WshShell.SendKeys "{F1}" Tips:如果需要发送多个重复的单字母按键,不必重复输入该字母,SendKeys允许使用简化格式进行描述,使用格式为“{按键 数字}”。例如要发送10个字母“x”,则输入“WshShell.SendKeys "{x 10}"”即可。先录制取得初始脚本,再做简单的修改和参数化,再进行封装形成可重用的函数,最后回放调试,形成了最终的脚本。