-
自动化测试用例设计的原则
2012-11-26 13:14:43
自动化测试用例设计的原则
很多公司在实施自动化测试的过程中,往往会把所有的手工测试用例作为自动化测试用例,并且直接进行脚本的开发工作,甚至有些公司不写自动化测试用例,直接想当然地开发测试脚本,这些都是极其不规范的做法,甚至很有可能是导致最后自动化测试项目失败的最大原因。那么问题就来了,为什么不能使用手工测试用例完全替代自动化测试用例呢?有以下几点原因,同时也是自动化测试用例的设计原则
● 原则1:自动化测试用例的范围往往是核心业务流程或者重复执行率较高的。
在选取自动化测试用例范围时,很多测试工程师或者上级领导可能心里会过分依赖自动化测试,会认为自动化测试就应该覆盖所有的手工测试用例,自动化测试的覆盖率就应该达到百分之百。其实恰好相反,这样的想法往往会导致自动化测试最终失败。在一些大型项目中,往往测试用例的数量会很庞大,而且如果遇到一些繁杂的被测程序(特别是C/S架构),脚本开发工作往往会相当耗时间,并且很多测试用例甚至根本就不能通过自动化来实现。举些例子,现在很多公司自动化测试都是刚起步,对自动化测试的了解程度只是停留在字面上,在公司对测试也不是非常重视的情况下,当然不太愿意去花精力招一个具有自动化测试开发经验的工程师,很多还是停留在使用工具的录制回放功能来完成自动化测试。正是存在这样的技术限制情况下,往往在实施中,会出现很多录制回放不能解决的问题,测试工具完全无法识别测试对象,无法识别一些特殊的加密测试控件。还有,如果项目的变更频率,测试用例数量大的话,增加了后期的维护工作量等,都是造成最终失败的一些隐患。投入越大,损失越大。因此,往往我们会选取最核心的一些业务路径或者是重复执行率较高的一些手工测试用例进行自动化测试,这样能够充分发挥出自动化测试的优势。
● 原则2:自动化测试用例的选择一般以“正向”为主。
手工测试用例分正常情况和异常情况,在设计的时候,可能往往会去设计很多异常情况来验证程序是否有Bug,并且一个正常情况的测试用例往往会对应几十个非正常情况的测试用例,而每种异常情况的测试用例都会有各种各样的预期结果。在自动化测试中,很多人喜欢将正常情况称为“正向”;反之,异常情况则称为“反向”。下面,我们试想以下,如果将这些异常情况全部转化、反应到自动化测试脚本中,那肯定需要非常繁琐的判断才能做到。这个对于自动化测试工程师来说,其现有的工作量还是今后的脚本维护量都是不可小视的。对于整个自动化测试项目来说,如果每个异常情况都要写进脚本中,那真的是花了大价钱买一堆小东西,小东西真正能发挥大作用的毕竟很少。因此,真正在自动化测试项目实施中,往往会舍弃反向用例,个别比较重要的除外。使每个东西都能发挥其最大的作用才是企业最想看到的。功能自动化测试主要还是用于回归测试,回归测试的目的就是保证新增功能后老功能是否能够正常继续运作。而自动化测试则是让测试人员从繁琐又枯燥的重复手工测试中解放出来,这就是目的和目标。
原则3:不是所有手工测试用例都可以使用自动化测试来实现的。
这里纠正许多测试从业人员的一个错误观念,刚接触测试自动化的普遍都会认为手工测试用例全部要转化为自动化测试用例,但是在真正实施的时候,却发现很多测试用例是自动化无法实现的,或者有些测试用例根本就没有必要去自动化的。例如,有些用例会牵涉到硬件设备辅助的,最简单的例子就是用例执行过程中需要使用刷卡机才能获取卡号信息(如果有技术能力,当然不排除自行开发接口供测试工具调用,但毕竟能有技术实力做到这一步的不多,能有这样的重视程度的更不多);再比如,有些测试用例是需要与合作机构进行互动联调,联调时是需要和对方实时沟通,以及根据具体情况给予响应的,这些情况多数还是只能使用手工人为地来完成。当然,决定是否转化为自动化测试,必须事先有一个规范文档来定义哪些是需要转化为自动化测试哪些是不需要的,否则测试工程师就会不知所措,没有一个标准。一旦有了这个标准,自动化测试工程师就可以严格按照文档里的流程去完成需要转化部分的自动化测试用例的脚本开发工作了。
原则4:手工测试用例可以不用回归原点,而自动化用例往往是必须的。
很多有经验的自动化测试从业人员一定有这样的经历,很多时候脚本写完后,第一次执行没有任何问题,而第二次执行时立刻就会报错,原因就是没有回归原点。所谓回归原点就是执行的测试用例最终需要恢复其在执行前的初始状态,如果没有回归原点,就会把此脚本称之为死脚本。举个最简单的例子,比如添加用户功能,我们都知道每个用户名都是唯一的,当写完一个添加用户的脚本之后,执行第一次没有问题,因为执行前此用户还不存在,但是当执行第二次时,程序就会出现用户重复而报错,此时这个添加用户的脚本就失去了它的价值,在这种情况下,我们就需要在自动化测试用例的最后加上删除这个用户的步骤,这样在下次执行用例时就不会出现用户重复的情况了。当然,除了回归原点,还可以使用另一种方式进行,那就是初始化数据,比如ATM机取款,假设需要执行取款100元的操作,而银行卡余额是120元,当测试脚本第一次执行时可能没有任何问题,但是第二次系统就会报余额不足,这样就成为了死脚本,解决方案有两种:一种是直接进行初始化数据,每次执行用例之前都重置下余额(只需大于100即可);第二种方法可以在用例执行前,先查询下余额是否大于100,若大于等于则继续,若小于则做一笔充值100的操作,这样即可解决。两种方式可以看具体情况使用,数据初始化方便,但有时候初始化之后可能会影响到其他自动化测试用例的执行,而第二种方式相对在脚本上需要稍微花点功夫。究竟使用哪种方式还需要具体情况具体分析。总之,在执行自动化测试用例之前做好数据准备,这也是自动化测试的关键步骤。
原则5:自动化测试用例和手工测试用例不同,不需要每个步骤都写预期结果。
在手工测试用例的设计过程中,几乎每一个测试步骤都有一个预期结果。但是,在自动化测试用例的设计中并不采用,在自动化测试用例中,只有准备在测试脚本中设置成检查点的步骤才有预期结果,其他所有的步骤只将它看作一个步骤,这样做的好处是一目了然、目的明显、层次分明,以后写测试脚本直接跟着自动化测试用例就行了。因为经过前面的探讨应该已经知道,自动化测试中并不是所有的东西都需要验证的。所以,作者在前面的章节中也提到过,基本上手工测试用例多多少少都要进行一些转换的,就是因为它们之间的格式是不一致的。举一个简单的例子,假设需要设计一个注册页面的自动化测试用例,有10几个表单需要填写,在手工测试用例中,每个表单的填写都一定会有预期结果,因为它的确在检查每一项是对了还是错了,只是用的是你的眼睛在检查而已,所以速度非常的快,甚至你自己潜意识都忽略了其实你已经检查了。但是,在自动化测试中,我们知道如果你要检查,那一定需要写代码,如果每项都检查,那代码量有多大是可想而知的,不是说做不到,只是这样做根本不符合自动化测试的特点。所以,绝大部分时候,这些在自动化测试中可有可无的检查,我们全部“不检查”,只当做一个业务流程和步骤,是不需要设立预期结果的。
-
QTP模拟鼠标键盘事件
2012-11-23 18:05:22
1 鼠标事件1.1 使用自带的Click方法每个对象都有自带的Click方法,通过其中第三个参数指定具体的鼠标事件(左键、右键、中建)例如: Browser("New Page").page("New Page").WebElement("html tag:=Form").Click 0,0,micRightBtn注意:Click方法的前两个参数是相对坐标,即相对于对象控件左上角的坐标。然而执行脚本时常常发现右键功能无法回放,常常被当做左键处理。这需要通过设置回放级别解决。Setting.WebPackage("ReplayType") = 2 '根据鼠标事件回放Browser("百度一下,你就知道").Page("百度一下,你就知道").WebEdit("wd").Set "张三"Browser("百度一下,你就知道").Page("百度一下,你就知道").WebButton("百度一下").Click 0,0,micRightBtnwait 3Setting.WebPackage("ReplayType") = 1 '根据键盘事件回放1.2 使用自带的FireEvent方法Browser("百度一下,你就知道").Page("百度一下,你就知道").WebButton("百度一下").FireEvent "click",0,0,micRightBtn具体使用参考QTP的帮助吧,需要提醒一下,右键菜单的弹出对应的是"oncontextmenu"事件,这个帮助里没有提到,当然依赖于开发的代码实现。1.3 使用Windows底层的mouse_event如果上面的方法仍然不管用,就要采用更底层的方法了。不过这种方式不推荐,因为mouse_event识别的是绝对坐标,你还需要在调用mouse_event前获取对象的绝对坐标。需要说明的是,如果没有使用MOUSEEVENTF_ABSOLUTE,函数默认的是相对于鼠标当前位置的点,用0,0表示,会被认为是当前鼠标所在的点。Extern.Declare micVoid, "mouse_event", "user32.dll", "mouse_event", micByte,micByte,micDWord,micULongExtern.mouse_event MOUSEEVENTF_RIGHTDOWN,0,0,01.4 使用mercury.devicereplaySet devReplay = CreateObject("mercury.devicereplay")devReplay.MouseClick absx+4,absy+4,22 键盘事件2.1 SendKeys最常用的模拟键盘操作的事件就是SendKeys了,具体说明一样参考QTP的帮助。需要说明的是QTP帮助中的例子,需要做一些调整,QTP中执行不需要显示指定Wscript执行shell命令,否则会报错。正确的例子如下:Set WshShell = CreateObject("WScript.Shell")WshShell.SendKeys "{DOWN}"WshShell.SendKeys "{CAPSLOCK}"wait 3WshShell.SendKeys "{CAPSLOCK}"当然我们也可以先定义一个function,然后每次都调用这个function。Public Function sendKeys(stringWord)Dim WSHOn Error Resume NextSet WSH = CreateObject("WScript.Shell")WSH.SendKeys stringWordSet WSH = NothingEnd FunctionsendKeys ("{CAPSLOCK}") '这里注意括号中的写法wait 3sendKeys ("{CAPSLOCK}") '这里注意括号中的??2.2 Mercury.DeviceReplaySet devReplay = CreateObject("mercury.devicereplay")devReplay.SendString("a")2.3 使用Windows底层的keybd_eventExtern.Declare micVoid, "keybd_event", "user32.dll", "keybd_event", micByte,micByte,micDWord,micULongExtern.keybd_event 42,0,0,0注意一下这里的第一个参数是10进制的。SendKeys的使用要方便一点,但是稳定性不如后者Function RtClick( Obj )absx = Obj.GetROProperty("abs_x")absy = Obj.GetROProperty("abs_y")Set devReplay = CreateObject("mercury.devicereplay")devReplay.MouseClick absx+4,absy+4,2set devReplay = nothingEnd Function -
QTP 常用函数总结
2012-11-23 18:00:39
'获取当前日期Public Function Get_Date()Dim currentDatecurrentDate = DateGet_Date = currentDateEnd Function'调用print Get_Date()'获取当前时间Public Function Get_Time()Dim currentTimecurrentTime = TimeGet_Time = currentTimeEnd Function'调用print Get_Time'随机函数生成'输入值:生成值范围 i~j'返回值:随机数Public Function Get_RandNum(fromNum,toNum)If (fromNum<0) Or (toNum<0) ThenMsgBox "只接受大于零的输入"ElseIf fromNum>toNum thenMsgBox "起始值必须小于结束值"ElseDim RunTimeRandomize '初始化随机生成器,该生成器具有根据系统计时器得到的随机种子RunTime = Int((10 * Rnd) + 1) 'Rnd本身的值是由随机种子得到的介于0--1之间的随机数Dim MyValue,iFor i = 1 To RunTimeRandomizeMyValue = Int(((toNum - fromNum + 1) * Rnd) + (fromNum))NextGet_randNum=MyValueEnd IfEnd Function'调用print Get_RandNum(0,100)'值交换函数Public Sub swap(byref a,byref b)Dim cc = aa = bb = cEnd Sub'调用Dim a,ba=3b=6swap a,bprint "a="&aprint "b="&b'是质数返回true,否则返回falseFunction IsPrimeNumber(num)Dim i,flagflag = trueIf num = 1 Thenflag = FalseElseIf num < 1 ThenMsgBox "只能接受大于0的数"flag = FalseElseFor i = 2 To (num - 1)If ((num Mod i) = 0) Thenflag = FalseExit ForEnd IfNextEnd IfIsPrimeNumber = flagEnd Function'调用print IsPrimeNumber(7)'读指定文本文件指定行内容Function ReadLine(pathway, rowcount)Dim fso,myfile,i,flagflag = 1Set fso=CreateObject("scripting.FileSystemObject")If fso.FileExists(pathway) thenSet myfile = fso.openTextFile(pathway,1,false)Elseflag = 0End IfFor i=1 to rowcount-1If Not myfile.AtEndOfLine Thenmyfile.SkipLineEnd IfNextIf flag = 1 thenIf Not myfile.AtEndOfLine ThenReadLine = myfile.ReadLineElseReadLine = "文本越界"End Ifmyfile.closeElseReadLine = "文件不存在"End IfEnd Function'调用print ReadLine("E:\zhang\QTP\vbs.txt", 3)'随机生成字符串,需要用到上边的随机数函数Function MakeString(inputlength)Dim I,x,B,AIf IsNumeric(inputlength) ThenFor I = 1 To inputlengthA = Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")Randomizex=Get_RandNum(0,35)B = A(x)makestring =makestring +BNextMakeString = makestringelsemsgbox ("只接受数字输入")End IfEnd Function'调用print MakeString(5)'启动资源管理器Sub ZYGLQ()Dim WshShellset WshShell = CreateObject("Wscript.Shell")WshShell.SendKeys "^+{ESC}"Set WshShell = nothingEnd Sub'启动运行Sub Run()Dim WshShellset WshShell = CreateObject("Wscript.Shell")WshShell.SendKeys "^{ESC}R"Set WshShell = nothingEnd Sub'发送电子邮件Function SendMail(SendTo, Subject, Body, Attachment)Dim ol,mailSet l=CreateObject("Outlook.Application")Set Mail=ol.CreateItem(0)Mail.to=SendToMail.Subject=SubjectMail.Body=BodyIf (Attachment <> "") ThenMail.Attachments.Add(Attachment)End IfMail.Sendol.QuitSet Mail = NothingSet l = NothingEnd Function'去掉字符串中的重复项Function NoRepeat(Inp,Sp)Dim aa,flag,words,length,i,j,k,sp1,sp2,ccaa = InpDoflag = Falsewords = Split(aa,Sp)length = UBound(words)For i = 0 To (length -1)sp1 = words(i)For j = (i+1) To lengthsp2 = words(j)If sp1 = sp2 Thenflag = Trueaa = ""For k = 0 To (j-1)aa = aa & words(k) & spNextFor k = (j + 1) To lengthaa = aa & words(k) & spNextcc = Len(aa)aa = Left(aa,(cc - 1))End IfNextIf flag = True ThenExit ForEnd ifNextLoop Until flag = falseNoRepeat = aaEnd Function'求字符串长度(中文算2个西文字符)Function GetLen(Str)Dim singleStr, i, iCountiCount = 0For i = 1 to len(Str)singleStr = mid(Str,i,1)If asc(singleStr) < 0 TheniCount = iCount + 2ElseiCount = iCount + 1End IfNextGetLen = iCountEnd Function'运行指定程序Sub RunApp(command)Dim WshShellset WshShell = CreateObject("Wscript.Shell")WshShell.Exec commandEnd Sub'求下一天是几号的函数Function Nextday(ByVal inputday)Dim temp, num, OPYear, OPMonth, OPDay, ret, flagtemp = Split(CStr(inputday), "-")num = UBound(temp) + 1PYear = temp(0)PMonth = temp(1)PDay = temp(2)flag = 0If PMonth = 1 Or PMonth = 3 Or PMonth = 5 Or PMonth = 7 Or PMonth = 8 Or PMonth = 10 Or PMonth = 12 ThenIf OPDay > 31 Or OPDay < 1 Thenflag = 1End IfElseIf PMonth = 4 Or PMonth = 6 Or PMonth = 9 Or PMonth = 11 ThenIf OPDay > 30 Or OPDay < 1 Thenflag = 1End IfElseIf ISLeapYear(OPYear) ThenIf OPDay > 29 Or OPDay < 1 Thenflag = 1End IfElseIf OPDay > 28 Or OPDay < 1 Thenflag = 1End IfEnd IfEnd IfIf flag = 1 Or num <> 3 ThenMsgBox "输入参数不对劲", , "Nextday函数提示"ElseIf PMonth = 1 Or PMonth = 3 Or PMonth = 5 Or PMonth = 7 Or PMonth = 8 Or PMonth = 10 Or PMonth = 12 Then 'big monthIf PDay = 31 ThenPDay = 1If PMonth = 12 ThenPMonth = 1PYear = OPYear + 1ElsePMonth = OPMonth + 1PYear = OPYearEnd IfElsePDay = OPDay + 1End IfElseIf PMonth = 4 Or PMonth = 6 Or PMonth = 9 Or PMonth = 11 Then 'small monthIf PDay = 30 ThenPDay = 1If PMonth = 12 ThenPMonth = 1PYear = OPYear + 1ElsePMonth = OPMonth + 1PYear = OPYearEnd IfElsePDay = OPDay + 1End IfElse 'FebruaryIf ISLeapYear(OPYear) ThenIf PDay = 29 ThenPDay = 1If PMonth = 12 ThenPMonth = 1PYear = OPYear + 1ElsePMonth = OPMonth + 1PYear = OPYearEnd IfElsePDay = OPDay + 1End IfElseIf PDay = 28 ThenPDay = 1If PMonth = 12 ThenPMonth = 1PYear = OPYear + 1ElsePMonth = OPMonth + 1PYear = OPYearEnd IfElsePDay = OPDay + 1End IfEnd IfEnd Ifret = OPYear & "-" & OPMonth & "-" & OPDayNextday = retEnd IfEnd Function'是否闰年Function ISLeapYear(ByVal inYear)If ((inYear Mod 4 = 0 And inYear Mod 100 <> 0) Or inYear Mod 400 = 0) ThenISLeapYear = TrueElseISLeapYear = FalseEnd IfEnd Function'计算两个日期之间相隔几天Function Days(ByVal SourceData, ByVal DesData)Dim flag, temp1, temp2, OPYear1, OPYear2, OPMonth1, OPMonth2, OPDay1, OPDay2, i, tempDaytemp1 = Split(SourceData, "-")temp2 = Split(DesData, "-")If ((UBound(temp1) + 1) <> 3) Or ((UBound(temp2) + 1) <> 3) ThenMsgBox "输入参数不对劲", , "Days函数提示"End IfOPYear1 = temp1(0)OPMonth1 = temp1(1)OPDay1 = temp1(2)OPYear2 = temp2(0)OPMonth2 = temp2(1)OPDay2 = temp2(2)If CInt(OPYear1) <> CInt(OPYear2) ThenIf CInt(OPYear1) > CInt(OPYear2) Thenflag = "big"ElseIf CInt(OPYear1) < CInt(OPYear2) Thenflag = "small"End IfElseIf CInt(OPMonth1) <> CInt(OPMonth2) ThenIf CInt(OPMonth1) > CInt(OPMonth2) Thenflag = "big"ElseIf CInt(OPMonth1) < CInt(OPMonth2) Thenflag = "small"End IfElseIf CInt(OPDay1) <> CInt(OPDay2) ThenIf CInt(OPDay1) > CInt(OPDay2) Thenflag = "big"ElseIf CInt(OPDay1) < CInt(OPDay2) Thenflag = "small"End IfElseflag = "="End IfEnd IfEnd IfIf (flag = "big") Theni = 1tempDay = DesDataDotempDay = Nextday(tempDay)i = i + 1Loop Until tempDay = SourceDatai = i - 1ElseIf (flag = "small") Theni = 1tempDay = SourceDataDotempDay = Nextday(tempDay)i = i + 1Loop Until tempDay = DesDatai = i - 1Elsei = 0End IfDays = iEnd Function'检查身份证号是否正确Function Identification(Text1)xian = Text1If (Not IsNumeric(Left(Text1, 15)) And Not IsNumeric(Left(Text1, 18))) Or Text1 = "" ThenIdentification = FalseExit FunctionEnd Iflenx = Len(Trim(Text1))If lenx = 15 Or lenx = 18 ThenIf lenx = 15 Thenyy = "19" & Mid(xian, 7, 2)mm = Mid(xian, 9, 2)dd = Mid(xian, 11, 2)aa = Right(xian, 1)End IfIf lenx = 18 Thenyy = Mid(xian, 7, 4)mm = Mid(xian, 11, 2)dd = Mid(xian, 13, 2)aa = Right(xian, 1)End IfIf CInt(mm) > 12 Or CInt(dd) > 31 ThenIdentification = FalseExit FunctionElseIdentification = TrueExit FunctionEnd IfElseIdentification = FalseExit FunctionEnd IfEnd Function'检查是否存在数字Function checkString (myString)checkString = FalseDim myChrFor myChr = 48 to 57If InStr(myString,Chr(myChr)) > 0 ThencheckString = TrueExit FunctionEnd IfNextEnd Function'查询Access数据库字符出现次数Function Access_GetCount(DBlocation,TableName,Value)set con=createobject("adodb.connection")con.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" & DBlocationset record = createobject("adodb.recordset")sql="select * from " & TableNamerecord.open sql,conDOif(record("name")=Value)thennum=num+1end Ifrecord.MoveNextloop until record.eof=Truerecord.closeset record=Nothingcon.closeset con=NothingIf num = 0 ThenAccess_GetCount = 0ElseAccess_GetCount = numEnd IfEnd Function'按ASCII码值冒泡排序Function BubbleSort(VString,Spl,Func)Dim Str,StrLength,i,jStr = Split(VString,Spl)StrLength = UBound(Str) + 1For i = 1 To (StrLength-1)For j = (i+1) To StrLengthIf Func = 1 thenIf Asc(Str(i-1)) < Asc(Str(j-1)) ThenCall Swap(Str(i-1),Str(j-1))End IfElseIf Asc(Str(i-1)) > Asc(Str(j-1)) ThenCall Swap(Str(i-1),Str(j-1))End IfEnd IfNextNextj = ""For i = 1 To StrLengthj = j & Str(i-1) & SplNextj = Left(j,(StrLength * 2 -1))BubbleSort = jEnd Function''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''以下为仅QuickTest适用函数'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''让QTP运行时保持最小化Public Sub QTP_Small()Dim objQTPWinSet bjQTPWin = GetObject("" , "QuickTest.Application")objQTPWin.WindowState = "Minimized"Set bjQTPWin = NothingEnd Sub'恢复QTP窗口Public Sub QTP_Big()Dim objQTPWinSet bjQTPWin = GetObject("" , "QuickTest.Application")objQTPWin.WindowState = "Restored"Set bjQTPWin = NothingEnd Sub'写文件函数(追加)'输入值:写入内容Public Function QTP_WriteFile(pathway,words)Dim fileSystemObj,fileSpec,logFile,waySet fileSystemObj = CreateObject("Scripting.FileSystemObject")fileSpec = pathwaySet logFile = fileSystemObj.OpenTextFile(fileSpec, 8, true)logFile.WriteLine (CStr(words))logFile.CloseSet logFile = NothingEnd Function'写文件函数(改写)'输入值:写入内容Public Function QTP_WriteFile_Change(pathway,words)Dim fileSystemObj,fileSpec,logFile,waySet fileSystemObj = CreateObject("Scripting.FileSystemObject")fileSpec = pathwaySet logFile = fileSystemObj.OpenTextFile(fileSpec, 2, true)logFile.WriteLine (CStr(words))logFile.CloseSet logFile = NothingEnd Function'读Excel文件元素Public Function QTP_Read_Excel(pathway,sheetname,x,y)Dim srcData,srcDoc,retset srcData = CreateObject("Excel.Application")srcData.Visible = Trueset srcDoc = srcData.Workbooks.Open(pathway)srcDoc.Worksheets(sheetname).Activateret = srcDoc.Worksheets(sheetname).Cells(x,y).valuesrcData.Workbooks.CloseWindow("text:=Microsoft Excel").CloseQTP_Read_Excel = retEnd Function'写Excel文件元素并保存退出Public Function QTP_Write_Excel(pathway,sheetname,x,y,content)Dim srcData,srcDoc,sp1,sp2,num,use,a1,a2,a3set srcData = CreateObject("Excel.Application")srcData.Visible = Trueset srcDoc = srcData.Workbooks.Open(pathway)srcDoc.Worksheets(sheetname).ActivatesrcDoc.Worksheets(sheetname).Cells(x,y).value = content' sp1 = Split(pathway,".")' sp2 = Split(sp1(0),"\")' num = UBound(sp2)' use = sp2(num)' Set a1 = Description.Create()' a1("text").value="Microsoft Excel - " + use + ".xls"' a1("window id").value="0"' Set a3 = Description.Create()' a3("Class Name").value="WinObject"' a3("text").value= use + ".xls"' Window(a1).WinObject(a3).Type micCtrlDwn + "s" + micCtrlUpDim WshShellSet WshShell=CreateObject("Wscript.Shell")WshShell.SendKeys "^s"wait(1)srcData.Workbooks.CloseSet srcDoc = nothingWindow("text:=Microsoft Excel").CloseEnd Function'定时停留弹出框函数Sub QTP_Msgbox(Value,waitTime,Title)Dim WshShellSet WshShell = CreateObject("WScript.Shell")WshShell.Popup Value, waitTime, TitleSet WshShell = nothingEnd Sub'改变Excel的单元格颜色Public Function QTP_Change_Color(pathway,sheetname,x,y,color)Dim srcData,srcDoc,sp1,sp2,num,use,a1,a2,a3set srcData = CreateObject("Excel.Application")srcData.Visible = Trueset srcDoc = srcData.Workbooks.Open(pathway)srcDoc.Worksheets(sheetname).ActivateIf color = "red" ThensrcDoc.Worksheets(sheetname).Cells(x,y).Interior.color=vbredElseIf color = "green" ThensrcDoc.Worksheets(sheetname).Cells(x,y).Interior.color=vbgreenElseMsgBox "输入的颜色参数不正确,只接收""red""和""green"""End IfDim WshShellSet WshShell=CreateObject("Wscript.Shell")WshShell.SendKeys "^s"wait(1)srcData.Workbooks.CloseSet srcDoc = nothingWindow("text:=Microsoft Excel").CloseEnd Function'捕获当前屏幕(截图)Public Function QTP_Capture(pathway)Dim datestampDim filenamedatestamp = Now()filename = Environment("TestName")&"_"&datestamp&".png"filename = Replace(filename,"/","")filename = Replace(filename,":","")filename = pathway + "\" + ""&filenameDesktop.CaptureBitmap filename'Reporter.ReportEvent micFail,"image","<img src='" & filename & "'>"End Function''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''QuickTestPlus 帮助文件对于Excel库函数 仅QTP适用''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Dim ExcelApp 'As Excel.ApplicationDim excelSheet 'As Excel.worksheetDim excelBook 'As Excel.workbookDim fso 'As Scripting.FileSystemObjectFunction CreateExcel() 'As Excel.ApplicationDim excelSheet 'As Excel.worksheetSet ExcelApp = CreateObject("Excel.Application") 'Create a new excel ObjectExcelApp.Workbooks.AddExcelApp.Visible = TrueSet CreateExcel = ExcelAppEnd FunctionSub CloseExcel(ExcelApp)Set excelSheet = ExcelApp.ActiveSheetSet excelBook = ExcelApp.ActiveWorkbookSet fso = CreateObject("Scripting.FileSystemObject")On Error Resume Nextfso.CreateFolder "C:\Temp"fso.DeleteFile "C:\Temp\ExcelExamples.xls"excelBook.SaveAs "C:\Temp\ExcelExamples.xls"ExcelApp.QuitSet ExcelApp = NothingSet fso = NothingErr = 0On Error GoTo 0End SubFunction SaveWorkbook(ExcelApp, workbookIdentifier, path) 'As StringDim workbook 'As Excel.workbookOn Error Resume NextSet workbook = ExcelApp.Workbooks(workbookIdentifier)On Error GoTo 0If Not workbook Is Nothing ThenIf path = "" Or path = workbook.FullName Or path = workbook.Name Thenworkbook.SaveElseSet fso = CreateObject("Scripting.FileSystemObject")If InStr(path, ".") = 0 Thenpath = path & ".xls"End IfOn Error Resume Nextfso.DeleteFile pathSet fso = NothingErr = 0On Error GoTo 0workbook.SaveAs pathEnd IfSaveWorkbook = 1ElseSaveWorkbook = 0End IfEnd FunctionSub SetCellValue(excelSheet, row, column, value)On Error Resume NextexcelSheet.Cells(row, column) = valueOn Error GoTo 0End SubFunction GetCellValue(excelSheet, row, column)value = 0Err = 0On Error Resume NexttempValue = excelSheet.Cells(row, column)If Err = 0 Thenvalue = tempValueErr = 0End IfOn Error GoTo 0GetCellValue = valueEnd FunctionFunction GetSheet(ExcelApp, sheetIdentifier) 'As Excel.worksheetOn Error Resume NextSet GetSheet = ExcelApp.Worksheets.Item(sheetIdentifier)On Error GoTo 0End FunctionFunction InsertNewWorksheet(ExcelApp, workbookIdentifier, sheetName) 'As Excel.worksheetDim workbook 'As Excel.workbookDim worksheet 'As Excel.worksheet'In case that the workbookIdentifier is empty we will work on the active workbookIf workbookIdentifier = "" ThenSet workbook = ExcelApp.ActiveWorkbookElseOn Error Resume NextErr = 0Set workbook = ExcelApp.Workbooks(workbookIdentifier)If Err <> 0 ThenSet InsertNewWorksheet = NothingErr = 0Exit FunctionEnd IfOn Error GoTo 0End IfsheetCount = workbook.Sheets.Countworkbook.Sheets.Add , sheetCountSet worksheet = workbook.Sheets(sheetCount + 1)If sheetName <> "" Thenworksheet.Name = sheetNameEnd IfSet InsertNewWorksheet = worksheetEnd FunctionFunction CreateNewWorkbook(ExcelApp)Set NewWorkbook = ExcelApp.Workbooks.Add()Set CreateNewWorkbook = NewWorkbookEnd FunctionFunction OpenWorkbook(ExcelApp, path)On Error Resume NextSet NewWorkbook = ExcelApp.Workbooks.Open(path)Set penWorkbook = NewWorkbookOn Error GoTo 0End FunctionSub ActivateWorkbook(ExcelApp, workbookIdentifier)On Error Resume NextExcelApp.Workbooks(workbookIdentifier).ActivateOn Error GoTo 0End SubSub CloseWorkbook(ExcelApp, workbookIdentifier)On Error Resume NextExcelApp.Workbooks(workbookIdentifier).CloseOn Error GoTo 0End SubFunction CompareSheets(sheet1, sheet2, startColumn, numberOfColumns, startRow, numberOfRows, trimed) 'As BooleanDim returnVal 'As BooleanreturnVal = TrueIf sheet1 Is Nothing Or sheet2 Is Nothing ThenCompareSheets = FalseExit FunctionEnd IfFor r = startRow to (startRow + (numberOfRows - 1))For c = startColumn to (startColumn + (numberOfColumns - 1))Value1 = sheet1.Cells(r, c)Value2 = sheet2.Cells(r, c)If trimed ThenValue1 = Trim(Value1)Value2 = Trim(Value2)End IfIf Value1 <> Value2 ThenDim cell 'As Excel.Rangesheet2.Cells(r, c) = "Compare conflict - Value was '" & Value2 & "', Expected value is '" & Value1 & "'."Set cell = sheet2.Cells(r, c)cell.Font.Color = vbRedreturnVal = FalseEnd IfNextNextCompareSheets = returnValEnd Function'写入word文件Sub QTP_WriteWord(pathway,content)Dim oWord,oRange,oDocSet Word = CreateObject("Word.Application")oWord.documents.open pathway,forwriting, TrueSet Doc = oWord.ActiveDocumentSet Range = oDoc.contentoRange.insertafter contentoWord.ActiveDocument.Save' Dim WshShell' Set WshShell=CreateObject("Wscript.Shell")' WshShell.SendKeys "^s"' wait(1)oWord.Application.Quit TrueSet Range = NothingSet Doc = NothingSet Word = NothingEnd Sub -
QTP无法打开IE
2012-11-23 17:58:20
问题描述:
1,在QTP打开的情况下,ie经常性的打不开。。
但是进程中有印象,而且一个ie进程耗去50%的cpu
2,录制脚本时,内容为空。
原因:
QTP在IE中录制脚本是依靠一个叫BHOManager Class的动态链接库来完成的。当这个控件没有被加载,或者被禁用时,就会出现上述症状。
解决方法:
启用该控件。打开IE,在菜单中选择[工具]/[Internet选项]进入Internet配置界面。选择[程序]/[管理加载项],查看目前加载的ActiveX 的情况。当看到存在BHOManager Class并且其状态是“禁用”时,点击“启用”开启这个功能,并保存后退出即可解决问题。当在管理加载项里找不到BHOManger Class这个加载项时,如果你安装了QTP,那么在C:\WINDOWS\system32下会存在一个叫BHOManager.dll的动态链接库,或者可以直接在计算机里搜索BHOManager.dll,然后查看其路径。加载这个dll,加载方法为:点击[开始]/[运行],输入cmd,然后定位到dll所在目录,键入regsvr32 BHOManager.dll命令,即可注册此dll。
-
QTP快捷键
2012-11-23 09:58:07
在编写QTP代码时遇到多行注释,查询下快捷键多行注释为:ctrl+M 取消多行注释:ctrl+shift+M, 进一步把快捷键总结了,以下文字为转载而来, 其中QTP快捷键部分原来文字有与我使用的QTP10不符合的,都一一改正并验证过。vb部分原样转载而来。
QTP快捷键
文件菜单
新建 > 测试= CTRL + N
新建 > 业务组件CTRL + SHIFT + N
新建 > 函数库ALT + SHIFT + N
新建 > 应用程序区域CTRL +Alt + N
打开 > 测试CTRL + O
打开 > 业务组件CTRL + SHIFT + O
打开 > 应用程序区域CTRL + ALT + O打开 >函数库ALT + SHIFT + N
保存CTRL + S
将测试导出到 Zip 文件CTRL + ALT + S
从 Zip 文件导入测试CTRL + ALT + I
打印CTRL + P
编辑菜单
剪切CTRL + X (仅限 EV)
复制CTRL + C
粘贴CTRL + V
删除DEL
撤消CTRL + Z (仅限 EV)
重复CTRL + Y (仅限 EV)
重命名操作F2
查找CTRL + F (仅限 EV)
替换CTRL + H (仅限 EV)
转至CTRL + G (仅限 EV)
书签CTRL + B (仅限 EV)
完成字CTRL + 空格键(仅限 EV)
参数信息CTRL + SHIFT + 空格键
(仅限 EV)
将“With”应用到脚本CTRL + W(仅限 EV)
删除“With”语句CTRL + SHIFT + W (仅限 EV)
插入菜单
检查点 > 标准检查点F12
输出值 > 标准输出值CTRL + F12
步骤 > 步骤生成器F7
新建步骤F8 或 INS (仅限 KV)
块后的新步骤SHIFT + F8 (仅限 KV)
注意: KV = 关键字视图
EV = 专家视图
应用程序区域菜单
录制F3
运行F5
停止F4
模拟录制ALT + SHIFT + F3
低级录制CTRL + SHIFT + F3
步骤菜单
对象属性CTRL + ENTER
值配置选项在输入值上按 CTRL + F11
(仅限 KV)
输出选项在输出值上按 CTRL + F11
(仅限 KV)
调试菜单
暂停PAUSE
单步执行F11
单步跳过F10
单步退出SHIFT + F11
插入/ 删除断点F9
清除所有断点CTRL + SHIFT + F9
数据表选项
编辑 > 剪切CTRL + X
编辑 > 复制CTRL + C
编辑 > 粘贴CTRL + V
编辑 > 清除 > 内容CTRL + DEL
编辑 > 插入CTRL + I
编辑 > 删除CTRL + K
编辑 > 向右填充CTRL + R
编辑 > 向下填充CTRL + D
编辑 > 查找CTRL + F
编辑 > 替换CTRL + H
数据 > 重新计算F9
插入多行值编辑单元格时按 CTRL + F2
激活上一个/ 下一个数据表CTRL + PAGEUP/
CTRL + PAGEDOWN
常规选项
查看关键字视图/ 专家视图CTRL + TAB
打开步骤或数据表单元格的上下文
菜单
SHIFT + F10 右键下边的代码是完全转载过来,留作后用,没做验证
VB快捷键
命令
快捷键
说明
编辑.分行
Enter Shift + Enter
插入一个新行。
编辑.折叠到定义
Ctrl + M,Ctrl + O
自动确定在代码中创建区域(如过程)的逻辑边界,然后隐藏它们。
编辑.注释选定内容
Ctrl + K,Ctrl + C
使用编程语言的正确注释语法将代码的当前行标记为注释。
编辑.删除水平空白
Ctrl + K,Ctrl + \
折叠选定内容中的空白,如果没有选定内容,则删除与光标相邻的空白。
编辑.编排文档格式
Ctrl + K,Ctrl + D
按“选项”对话框“文本编辑器”部分中的语言的“格式设置”窗格中的指定,应用该语言的缩进和空格格式设置。
编辑.格式化选定内容
Ctrl + K,Ctrl + F
根据周围的代码行,正确缩进选定的代码行。
编辑.注释选定内容
Ctrl + M,Ctrl + H
隐藏选定文本。信号图标标记隐藏文本在文件中的位置。
编辑.插入制表符
Tab
将文本行缩进指定数量的空格,如 5 个。仅在 .NET Framework 设计器中可用。
编辑.剪切行
Ctrl + Y
将选择的所有行(或当前行,如果未选择任何行)剪切到剪贴板。
编辑.删除行
Ctrl + Shift + Y
删除所有选定行或当前行(如果没有选定行)。
编辑.上开新行
Ctrl + Enter
在插入点之上插入一个空行。
编辑.下开新行
Ctrl + Shift + Enter
在插入点之下插入一个空行。
编辑.行转置
Shift + Alt + T
将包含插入点的行移动到下一行之下。
编辑.改写模式
Insert
改写文档中已有的字符,而不是插入字符。仅在文本编辑器中可用。
编辑.停止隐藏当前区域
Ctrl + M,Ctrl + U
移除当前选定区域的大纲显示信息。
编辑.停止大纲显示
Ctrl + M,Ctrl + P
从整个文档中移除所有大纲显示信息。
编辑.交换定位点
Ctrl + R,Ctrl + P
交换当前选定内容的定位点与结束点。
编辑.左缩进
Shift + Tab
将选定行左移一个制表位。仅在 .NET Framework 设计器中可用。
编辑.切换所有大纲显示
Ctrl + M,Ctrl + L
在隐藏和显示状态之间切换所有以前被标记为隐藏的文本部分。
编辑.切换书签
Ctrl + K,Ctrl + K
在当前行处设置或移除书签。
编辑.切换大纲显示展开
Ctrl + M,Ctrl + M
在隐藏和显示状态之间切换当前选定的隐藏文本部分。
编辑.切换任务列表快捷方式
Ctrl + K,Ctrl + H
在当前行处设置或移除快捷方式。
编辑.取消注释选定内容
Ctrl + K,Ctrl + U
从代码的当前行中移除注释语法。
编辑.查看空白
Ctrl + R,Ctrl + W
显示或隐藏空格和制表符标记。
编辑.字转置
Ctrl + Shift + T
对调插入点两边的单词。
视图.显示引用
Alt + F12
执行区分大小写的全字符号搜索并在“查找符号结果”窗口中显示结果。
-
HTTP协议
2010-04-30 15:34:25
HTTP协议2007年03月03日 星期六 16:05计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求信息和服务,HTTP目前协议的版本是1.1.HTTP是一种无状态的协议,无状态是指Web浏览器和Web服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后Web服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息.HTTP遵循请求(Request)/应答(Response)模型。(2) Web浏览器向Web服务器发送请求命令。HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则。计算机专家设计出HTTP,使HTTP客户(如Web浏览器)能够从HTTP服务器(Web服务器)请求信息和服务,HTTP目前协议的版本是1.1.HTTP是一种无状态的协议,无状态是指Web浏览器和Web服务器之间不需要建立持久的连接,这意味着当一个客户端向服务器端发出请求,然后Web服务器返回响应(response),连接就被关闭了,在服务器端不保留连接的有关信息.HTTP遵循请求(Request)/应答(Response)模型。Web浏览器向Web服务器发送请求,Web服务器处理请求并返回适当的应答。所有HTTP连接都被构造成一套请求和应答。HTTP使用内容类型,是指Web服务器向Web浏览器返回的文件都有与之相关的类型。所有这些类型在MIME Internet邮件协议上模型化,即Web服务器告诉Web浏览器该文件所具有的种类,是HTML文档、GIF格式图像、声音文件还是独立的应用程序。大多数Web浏览器都拥有一系列的可配置的辅助应用程序,它们告诉浏览器应该如何处理Web服务器发送过来的各种内容类型。HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:(1) 建立TCP连接在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80(2) Web浏览器向Web服务器发送请求命令一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令例如:GET/sample/hello.jsp HTTP/1.1(3) Web浏览器发送请求头信息浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。(4) Web服务器应答客户机向服务器发出请求后,服务器会客户机回送应答,HTTP/1.1 200 OK应答的第一部分是协议的版本号和应答状态码(5) Web服务器发送应答头信息正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。(6) Web服务器向浏览器发送数据Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据(7) Web服务器关闭TCP连接一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码Connection:keep-aliveTCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。HTTP请求格式当浏览器向Web服务器发出请求时,它向服务器传递了一个数据块,也就是请求信息,HTTP请求信息由3部分组成:l 请求方法URI协议/版本l 请求头(Request Header)l 请求正文下面是一个HTTP请求的例子:GET/sample.jspHTTP/1.1Accept:image/gif.image/jpeg,*/*Accept-Language:zh-cnConnection:Keep-AliveHost:localhostUser-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)Accept-Encoding:gzip,deflateusername=jinqiao&password=1234(1) 请求方法URI协议/版本请求的第一行是“方法URL议/版本”:GET/sample.jsp HTTP/1.1以上代码中“GET”代表请求方法,“/sample.jsp”表示URI,“HTTP/1.1代表协议和协议的版本。根据HTTP标准,HTTP请求可以使用多种请求方法。例如:HTTP1.1支持7种请求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet应用中,最常用的方法是GET和POST。URL完整地指定了要访问的网络资源,通常只要给出相对于服务器 -
新手必看《自动化测试工具介绍LR篇》
2008-07-20 09:49:13
Mercury LoadRunner 是一种预测系统行为和性能的负载测试工具。通过以模拟上千万用户实施并发负载及实时性能监测的方式来确认和查找问题,LoadRunner 能够对整个企业架构进行测试。通过使用LoadRunner ,企业能最大限度地缩短测试时间,优化性能和加速应用系统的发布周期。
目前企业的网络应用环境都必须支持大量用户,网络体系架构中含各类应用环境且由不同供应商提供软件和硬件产品。难以预知的用户负载和愈来愈复杂的应用环境使公司时时担心会发生用户响应速度过慢,系统崩溃等问题。这些都不可避免地导致公司收益的损失。Mercury Interactive 的 LoadRunner 能让企业保护自己的收入来源,无需购置额外硬件而最大限度地利用现有的IT 资源,并确保终端用户在应用系统的各个环节中对其测试应用的质量,可靠性和可扩展性都有良好的评价。
LoadRunner 是一种适用于各种体系架构的自动负载测试工具,它能预测系统行为并优化系统性能。LoadRunner 的测试对象是整个企业的系统,它通过模拟实际用户的操作行为和实行实时性能监测,来帮助您更快的查找和发现问题。此外,LoadRunner 能支持广范的协议和技术,为您的特殊环境提供特殊的解决方案。
轻松创建虚拟用户
使用LoadRunner 的Virtual User Generator,您能很简便地创立起系统负载。该引擎能够生成虚拟用户,以虚拟用户的方式模拟真实用户的业务操作行为。它先记录下业务流程(如下订单或机票预定),然后将其转化为测试脚本。利用虚拟用户,您可以在Windows ,UNIX 或Linux 机器上同时产生成千上万个用户访问。所以LoadRunner能极大的减少负载测试所需的硬件和人力资源。另外,LoadRunner 的TurboLoad 专利技术能。
提供很高的适应性。TurboLoad 使您可以产生每天几十万名在线用户和数以百万计的点击数的负载。
用Virtual User Generator 建立测试脚本后,您可以对其进行参数化操作,这一操作能让您利用几套不同的实际发生数据来测试您的应用程序,从而反映出本系统的负载能力。以一个订单输入过程为例,参数化操作可将记录中的固定数据,如订单号和客户名称,由可变值来代替。在这些变量内随意输入可能的订单号和客户名,来匹配多个实际用户的操作行为。
LoadRunner 通过它的Data Wizard 来自动实现其测试数据的参数化。Data Wizard 直接连于数据库服务器,从中您可以获取所需的数据(如定单号和用户名)并直接将其输入到测试脚本。这样避免了人工处理数据的需要,Data Wizard 为您节省了大量的时间。
为了进一步确定您的Virtual user 能够模拟真实用户,您可利用LoadRunner 控制某些行为特性。例如,只需要点击一下鼠标,您就能轻易控制交易的数量,交易频率,用户的思考时间和连接速度等。
创建真实的负载
Virtual users 建立起后,您需要设定您的负载方案,业务流程组合和虚拟用户数量。用LoadRunner 的Controller,您能很快组织起多用户的测试方案。Controller 的Rendezvous 功能提供一个互动的环境,在其中您既能建立起持续且循环的负载,又能管理和驱动负载测试方案。
而且,您可以利用它的日程计划服务来定义用户在什么时候访问系统以产生负载。这样,您就能将测试过程自动化。同样您还可以用Controller 来限定您的负载方案,在这个方案中所有的用户同时执行一个动作---如登陆到一个库存应用程序----来模拟峰值负载的情况。另外,您还能监测系统架构中各个组件的性能---- 包括服务器,数据库,网络设备等----来帮助客户决定系统的配置。
LoadRunner 通过它的AutoLoad 技术,为您提供更多的测试灵活性。使用AutoLoad ,您可以根据目前的用户人数事先设定测试目标,优化测试流程。例如,您的目标可以是确定您的应用系统承受的每秒点击数或每秒的交易量。
定位性能问题
LoadRunner 内含集成的实时监测器,在负载测试过程的任何时候,您都可以观察到应用系统的运行性能。这些性能监测器为您实时显示交易性能数据(如响应时间)和其它系统组件包括application server, web server,网路设备和数据库等的实时性能。这样,您就可以在测试过程中从客户和服务器的双方面评估这些系统组件的运行性能,从而更快地发现问题。
再者,利用LoadRunner 的ContentCheck TM ,您可以判断负载下的应用程序功能正常与否。ContentCheck 在Virtual users 运行时,检测应用程序的网络数据包内容,从中确定是否有错误内容传送出去。它的实时浏览器帮助您从终端用户角度观察程序性能状况。
分析结果以精确定位问题所在
一旦测试完毕后,LoadRunner 收集汇总所有的测试数据,并为您提供高级的分析和报告工具,以便迅速查找到性能问题并追溯原由。使用LoadRunner 的Web 交易细节监测器,您可以了解到将所有的图象、框架和文本下载到每一网页上所需的时间。例如,这个交易细节分析机制能
够分析是否因为一个大尺寸的图形文件或是第三方的数据组件造成应用系统运行速度减慢。另外,Web 交易细节监测器分解用于客户端、网络和服务器上端到端的反应时间,便于确认问题,定位查找真正出错的组件。例如,您可以将网络延时进行分解,以判断DNS 解析时间,连接服务器或SSL 认证所花费的时间。通过使用LoadRunner 的分析工具,您能很快地查找到出错的位置和原因并作出相应的调整。
重复测试保证系统发布的高性能
负载测试是一个重复过程。每次处理完一个出错情况,您都需要对您的应用程序在相同的方案下,再进行一次负载测试。以此检验您所做的修正是否改善了运行性能。
Enterprise Java Beans的测试
LoadRunner 完全支持EJB 的负载测试。这些基于Java 的组件运行在应用服务器上,提供广泛的应用服务。通过测试这些组件,您可以在应用程序开发的早期就确认并解决可能产生的问题。
利用LoadRunner, 您可以很方便地了解系统的性能。 它的Controller 允许您重复执行与出错修改前相同的测试方案。它的基于HTML 的报告为您提供一个比较性能结果所需的基准,以此衡量在一段时间内,有多大程度的改进并确保应用成功。由于这些报告是基于HTML 的文本,您可以将其公布于您公司的内部网上,便于随时查阅。
最大化投资回报
所有Mercury Interactive 的产品和服务都是集成设计的, 能完全相容地一起运作。由于它们具有相同的核心技术,来自于LoadRunner和ActiveTest TM 的测试脚本,在Mercury Interactive 的负载测试服务项目中,可以被重复用于性能监测。借助Mercury Interactive的监测功能--Topaz TM 和ActiveWatch TM ,测试脚本可重复使用从而平衡投资收益。更重要的是,您能为测试的前期布署和生产系统的监测提供一个完整的应用性能管理解决方案。
支持无线应用协议
随着无线设备数量和种类的增多,您的测试计划需要同时满足传统的基于浏览器的用户和无线互联网设备,如手机和PDA。LoadRunner 支持2 项最广泛使用的协议:WAP和I-mode。此外,通过负载测试系统整体架构,LoadRunner 能让您只需要通过记录一次脚本,就可完全检测上述这些无线互联网系统。
支持Media Stream应用
LoadRunner 还能支持Media Stream应用。为了保证终端用户得到良好的操作体验和高质量Media Stream,您需要检测您的Media Stream应用程序。使用LoadRunner ,您可以记录和重放任何流行的多媒体数据流格式来诊断系统的性能问题,查找原由,分析数据的质量。
完整的企业应用环境的支持。
LoadRunner 支持广泛的协议,可以测试各种IT 基础架构。 -
转:关于测试的一些技巧和经验
2008-07-19 10:58:52
在制定测试计划的时候,就要考虑到测试的风险,并抉择要执行哪些测试,并放弃哪些测试;测试计划的评审应该让开发人员参与;测试模型的制作应该尽可能贴近用户,或者站在用户的使用立场上来观测软件,此时应该能发现更多的问题。
由于测试发现问题,在解决问题后还要重新测试,因此测试的时间可能会比实际更长一些
识别和注意少数重要的方面,而忽略多数次要的方面,有时候少数的问题足以致命,这些问题将是软件测试结果中重要性最高的错误。
错误的定位有时是很难的,要找出必然发生的前因后果,而不至于因为描述错误而误导开发人员。有时候确实存在错误不能重建的问题。解决办法之一是在错误报告中给予说明。
对错误的描述,应该是准确、完整而简练。因为描述的问题或者不完整的描述会引起开发人员的误解,其后果是可以想见的。
有时有经验的测试人员凭借直觉就可以发现一些问题,这可称为“错误猜测”。
测试人员容易犯2种错误:一是测试人员发生判断错误,将本没有错误的系统行为报告为错误,或者将错误指定了过高的严重级别,或者过高估计了问题的严重性,这样会引起开发人员的不信任,产生一种象“狼来了”一样的效果;二是测试人员将错误的严重性或优先级定得过低,从而产生“测试逃逸”,这样会造成产品质量的风险。以上两种错误应该尽量避免 -
Linux下常用网络配置命令
2008-07-19 10:40:26
1、 ifconfig
可以使用ifconfig命令来配置并查看网络接口的配置情况。
例如:
(1) 配置eth0的IP地址, 同时激活该设备。
#ifconfig eth0 192.168.1.10 netmask 255.255.255.0 up
(2) 配置eth0别名设备eth0:1的IP地址,并添加路由。
#ifconfig eth0 192.168.1.3
#route add –host 192.168.1.3 dev eth0:1
(3) 激活设备。
#ifconfig eth0 up
(4) 禁用设备。
#ifconfig eth0 down
(5) 查看指定的网络接口的配置。
#ifconfig eth0
(6) 查看所有的网络接口配置。
#ifconfig
2、 route
可以使用route命令来配置并查看内核路由表的配置情况。
例如:
(1) 添加到主机的路由。
#route add –host 192.168.1.2 dev eth0:0
#route add –host 10.20.30.148 gw 10.20.30.40
(2) 添加到网络的路由。
#route add –net 10.20.30.40 netmask 255.255.255.248 eth0
#route add –net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
#route add –net 192.168.1.0/24 eth1
(3) 添加默认网关。
#route add default gw 192.168.1.1
(4) 查看内核路由表的配置。
#route
(5)删除路由。
#route del –host 192.168.1.2 dev eth0:0
#route del –host 10.20.30.148 gw 10.20.30.40
#route del –net 10.20.30.40 netmask 255.255.255.248 eth0
#route del –net 10.20.30.48 netmask 255.255.255.248 gw 10.20.30.41
#route del –net 192.168.1.0/24 eth1
#route del default gw 192.168.1.1
对于1和2两点可使用下面的语句实现:
Ifconfig eth0 172.16.19.71 netmask 255.255.255.0
Route 0.0.0.0 gw 172.16.19.254
Service network restart
3、 traceroute
可以使用traceroute命令显示数据包到达目的主机所经过的路由。
例如:
#traceroute www.sina.com.cn
4、 ping
可以使用ping 命令来测试网络的连通性。
例如:
#ping www.sina.com.cn
#ping –c 4 192.168.1.12
5、 netstat
可以使用netstat命令来显示网络状态信息。
例如:
(1) 显示网络接口状态信息。
#netstat –i
(2) 显示所有监控中的服务器的Socket和正使用Socket的程序信息。
#netstat –lpe
(3) 显示内核路由表信息。
#netstat –r
#netstat –nr
(4) 显示TCP/UDP传输协议的连接状态。
#netstat –t
#netstat –u
6、 hostname
可以使用hostname命令来更改主机名。例如;
#hostname myhost
7、 arp
可以使用arp命令来配置并查看arp缓存。例如:
(1) 查看arp缓存。
#arp
(2) 添加一个IP地址和MAC地址的对应记录。
#arp –s 192.168.33.15 00:60:08:27:CE:B2
(3) 删除一个IP地址和MAC地址的对应缓存记录。
#arp –d192.168.33.15
标题搜索
我的存档
数据统计
- 访问量: 55810
- 日志数: 29
- 建立时间: 2008-05-20
- 更新时间: 2014-05-09