发布新日志

  • (转)实现LoadRunner多个场景的顺序执行

    2009-09-16 11:41:48

    应用场景
      假设有3个不同的测试场景,分别为并发登录、核心业务、可靠性测试,3个场景有先后执行顺序。由于白天测试机器另有用处,只能在晚上进行性能测试,这时我们的期望是能否把测试场景都设定好之后晚上自动运行,第二天我们回来看测试结果呢?
    答案是肯定的,可以有两种方式实现。

      第一种,相对简单
      充分利用LR Controller里面Group的功能。
      新建一个场景把3个脚本都添加进来,在Edit Schedule中选择“Schedule by Group”的方式,在StartTime中设置3个脚本的运行顺序为“Start when Group xxx finished”,并在“Scenario Start Time”中设定场景在晚上的运行启动时间。设定完定时执行场景后,点击StartScenario按钮,会出现一个倒计时窗口,这样在固定的某个时间上,测试场景中的3个脚本将乖乖的按照设定的先后顺序进行测试。注意,如果没有点击StartScenario按钮激活测试,是不会真正进行测试的。(感谢Athenst朋友的提醒,^_^)

      第二种,比较灵活
      我们把应用场景稍微扩展一下,假设其中1、3场景只有一个测试脚本,而核心业务场景由数据录入、数据查询、数据上报3个脚本组成,同样的,3个场景仍需按顺序进行测试。这时如果采用第一种方式,由于第2个场景有3个脚本,所以第三个脚本的启动时间就是一个问题了。由于Controller中每个脚本都对应一个Group,而且GroupName不能重复,这时第三个场景的StartTime中“Start when group finished”则只能是选择第二个场景中的某个Group,而并非是第二个场景的3个脚本都完成之后再进行,无法达到我们的初衷。
      这时,可以通过命令行的方式来进行。
      首先创建并设置好3个测试场景,再创建一个一个批处理程序按先后顺序调用这3个场景进行测试,最后通过Windows的定时任务设定批处理的执行时间。
      批处理示例如下:

    cls
    SET M_ROOT="D:\Program Files\MI\Mercury LoadRunner\bin\"
    %M_ROOT%\wlrun.exe -TestPath "D:\Program Files\MI\Mercury LoadRunner\scenario\Test\TestScen_1.lrs" -Run
    %M_ROOT%\wlrun.exe -TestPath "D:\Program Files\MI\Mercury LoadRunner\scenario\Test\TestScen_2.lrs" -Run
    %M_ROOT%\wlrun.exe -TestPath "D:\Program Files\MI\Mercury LoadRunner\scenario\Test\TestScen_3.lrs" -Run

      这种方式比较灵活,但需要注意在Result Settings中设置“Automatically create a results directory for each scenario execution”,以免后面的测试结果覆盖了前面的。


      另外补充一下,如果想对某个脚本进行50、100、150...等用户数递增的测试,也可以用以上方法实现,但需要注意的是将事务名称区分开以便进行分析。

  • (转)qtp 成为高手需要掌握常用com对象

    2009-09-16 10:32:11

    成为高手需要了解的基本com对象处理技术,了解常用的com对象的使用,如果你想成为高手,那么从下面对象开始吧:

    文件系统对象相关:
    ("scrīptING.FILESYSTEMOBJECT")

    应用:数据驱动技术常用,日志输入常用

    字典相关:
    ("scrīptING.DICTIONARY")

    应用:脚本配置控制开关 list对象item数据对比

    脚本外壳相关:
    ("Wscrīpt.SHELL")

    应用:最常用其中的sendkeys方法,利用在不可识别对象技术方面

    WINDOWS外壳相关:
    ("SHELL.APPLICATION")

     

    正则表达式相关:
    ("VBscrīpt.REGEXP")

    应用:网页解析,数据对比 验证点技术实现的一种

    编码与密码相关:
    ("scrīptPW.PASSWORD")
    ( "scrīptING.ENCODER" )

    应用:数据包传输测试过程中应用

    邮件发送的组件相关:
    ("JMAIL.MESSAGE")
    ("CDONTS.NEWMAIL")
    ("CDO.CONFIGURATION")
    ("EUDORA.EUAPPLICATION.1")
    ("NOVELLGROUPWARESESSION")

    应用:测试报告发送

    水晶报表相关:
     ("CRYSTALRUNTIME.APPLICATION")

    应用:测试报告美化,常用的是excel的报告输出,这种技术用的少

    IE浏览器相关:
    ("INTERNETEXPLORER.APPLICATION")

    应用:web测试用的比较多

    ADO相关:
    ("ADODB.CONNECTION")
    ("ADODB.COMMAND")
    ("ADODB.RECORDSET")
    ("ADODB.RECORD")
    ("ADODB.STREAM")
    ("DAO.DBENGINE.35")
    ("ADOX.CATALOG")
    ("ADOX.TABLE")

    应用:数据驱动,数据库验证,dao主要利用在access数据库处理

    SQL相关:
    ("SQLDMO.SQLSERVER")
    ("SQLDMO.LOGIN")
    ("SQLDMO.BACKUP")
    ("SQLDMO.USER")
    ("SQLDMO.BACKUPDEVICE")
    ("SQLDMO.DATABASE")
    ("SQLDMO.RESTORE")
    ("SQLDMO.APPLICATION")

    OFFICE相关:
    ("WORD.APPLICATION")
    ("EXCEL.APPLICATION")
    ("POWERPOINT.APPLICATION")
    ("EXCEL.SHEET")
    ("FRONTPAGE.APPLICATION")
    ("ACCESS.APPLICATION")
    ("MSGRAPH.APPLICATION")
    ("OUTLOOK.APPLICATION")

    应用:测试报告输出,数据驱动

    WMI相关:
    ("WBEMscrīptING.SWBEMDATETIME")
    ("WBEMscrīptING.SWBEMLOCATOR")
    ("WBEMscrīptING.SWBEMNAMEDVALUESET")
    ("WBEMscrīptING.SWBEMSINK", "SINK_")
    ("WBEMscrīptING.SWBEMREFRESHER")
    ("WBEMscrīptING.SWBEMLASTERROR")
    ("WBEMscrīptING.SWBEMOBJECTPATH")

    应用:初始化测试环境

    对象为我所用,我为测试所用

  • QTP:对象映射(自定义对象)应用(转)

    2009-09-14 14:17:25

    QTP版本:9.2英文版。

      一. 自动义对象应用

      当要操作的一些对象不识别时,且这些对象可以映射成标准Window控件时,则可以考虑自定义这些对象,并映射到相似的Window控件。这样就可以调用标准Window控件运行的方法来操作自定义对象了。

      要映射成相似的Window控件,则自定义的对象要有和标准Window控件相似的功能和操作。

      此法可以处理一些看起来像是标准Window控件的对象,但并不是所有这类对象都可行。如Delphi控件,大部分可以如此处理,但一些控件则不行哦。

      二. 自动义对象如何使用

      首先,需要对不识别的控件进行自定义,并做好与标准window控件的映射;

      其次,可以通过录制或描述性编辑调用这些自定义的对象;

      然后,就是像对待能识别的对象一样进行操作即可。

      注意:

      在移动脚本运行时(比如拷贝脚本至其他虚拟机运行),需要先运行自定义对象的定义脚本,然后再运行脚本。

      最好的方法是在要使用时,脚本中运行定义自定义对象的脚本,执行完成后则删除自定义的对象,恢复到原有配置。而由于QTP不提供删除单个自定义对象的功能,而提供了恢复默认配置的功能,因此只好使用恢复到默认对象配置的功能了。

      例:添加一个自定义对象的定义脚本如下:

    DimApp 'As Application
    ‘如果是在已经运行的QTP中运行,则可以用GetObject获取运行的QTP程序对象
    ‘如果是直接用VBS运行QTP,则可以用CreateObject建立QTP程序对象。
    SetApp =GetObject("","QuickTest.Application")
     
    ‘建立一个自定义对象“ttoolbar”,并映射到标准控件“WinToolbar”
    App.Options.ObjectIdentification("WinToolbar").CreateUserDefinedObject("ttoolbar")
    App.Options.ObjectIdentification("ttoolbar").OrdinalIdentifier = "location"
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.Add("nativeclass")
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.Add("text")
    App.Options.ObjectIdentification("ttoolbar").AssistiveProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").AssistiveProperties.Add("window id")
    App.Options.ObjectIdentification("ttoolbar").EnableSmartIdentification =False
    App.Options.ObjectIdentification("ttoolbar").BaseFilterProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").OptionalFilterProperties.RemoveAll()

      以上脚本也可以通过“Generate Script...”导出,然后删掉不是自定义的对象定义脚本,并稍微修改一下即可。

      恢复默认对象配置的方法如下:

      App.Options.ObjectIdentification.ResetAll

      三. 如何自定义对象

      1.      选择“Tools”>>“Object Identification”;

      2.      在“Environment”框中选择“Standard Windows”,则“User-Defined…”按钮将变为可用;

      3.      点击“User-Defined…”按钮,将显示“Object Mapping”对话框;

      4.      单击指向手,然后单击要将其类作为用户定义的类添加的对象。用户定义的对象的名称将显示在“Class Name”框中。(其实这个“Class Name”框也可以自己填,如果自己清楚该填什么的话)

      提示:按住Ctrl键,可以更改窗口焦点或执行右键单击或鼠标悬停(以显示上下文菜单)等操作。注意:按Ctrl键时,您不能从Windows任务栏中选择应用程序,因此,必须确保要访问的窗口没有最小化。

      5.      在“Map to”框中,选择要将用户定义的对象类映射到的标准对象类,然后单击“Add”。类名和映射将添加到对象映射列表中。

      6.      如果要将其他对象映射到标准类,请对每个对象重复步骤4-5。

      7.      单击“OK”。“Object Mapping”对话框关闭,您的对象作为用户定义的测试对象添加到标准Windows测试对象类列表中。注意:您的对象具有角上带有一个红色U的图标,标识它为用户定义的类。

      8.      为用户定义的对象类配置对象标识设置,方式与任何其他对象类一样。

      四. 例子

      以下举一个例子,就拿我们公司正在用的Delphi开发的“XX系统”为例吧:

      *操作如下:点击ToolBar中的打开按钮->在文本区域写入内容->点击ToolBar中的关闭按钮->关闭窗口

      *XX系统的界面就不给了,不好意思。

      [直接录制]如果不加载插件,则QTP对Delphi程序是不识别的,录制的代码如下:

    **************************************************************************************
    Window("XX系统").Activate
    Window("XX系统").WinObject("TToolBar").Click 266,39
    Window("XX系统").WinObject("TNoteEditor").Click 371,50
    Window("XX系统").WinObject("TNoteEditor").Type "fdsfasd"
    Window("XX系统").WinObject("TToolBar").Click 570,32
    Window("XX系统").WinObject("TToolBar").Click 327,36
    Window("XX系统").Close
     **************************************************************************************
    [定义自定义控件再录制]
    *定义自定义控件:
    *定义自定义控件后再录制的脚本如下:
    **************************************************************************************
    Window("XX系统").Activate
    Window("XX系统").WinToolbar("TToolBar").Press "打开"
    Window("XX系统").WinEditor("TNoteEditor").Type "fdsafsdafdas"
    Window("XX系统").WinToolbar("TToolBar").Press "保存"
    Window("XX系统").WinToolbar("TToolBar").Press "关闭"
    Window("XX系统").Close
    **************************************************************************************
     
    [改造后的脚本]
    *稍微改造一下,脚本如下,这样就可以自动调用程序进行笔录操作,然后关闭程序:
    **************************************************************************************
    SystemUtil.Run "C:\Program Files\XXXXsoft\ XX系统\P_XXXX.exe"
    ‘这里只是为了说明如何使用映射,不然以下这个循环会有一定的问题的哦,需要改造一下。
    Do while not  Dialog("提示").WinButton("确定").Exist(0)
       wait 1
    Loop
    Dialog("提示").WinButton("确定").Click
    Window("XX系统").Activate
    Window("XX系统").WinToolbar("TToolBar").Press "打开"
    Window("XX系统").WinEditor("TNoteEditor").Type "dfdghfdgfsgfds"
    Window("XX系统").WinEditor("TNoteEditor").Type micReturn
    Window("XX系统").WinEditor("TNoteEditor").Type "gfdsgfd"
    Window("XX系统").WinEditor("TNoteEditor").Type micReturn
    Window("XX系统").WinToolbar("TToolBar").Press "保存"
    Window("XX系统").WinToolbar("TToolBar").Press "关闭"
    window("XX系统").Close
    **************************************************************************************
     
    *如果是在其他机器上运行,则还需要先运行以下定义自定义控件的代码:
    **************************************************************************************
    Dim App 'As Application
    Set App = GetObject("","QuickTest.Application")
     
    'Configuration of user-defined objects
    'Object identification configuration for user-defined object "ttoolbar"
    App.Options.ObjectIdentification("WinToolbar").CreateUserDefinedObject("ttoolbar")
    App.Options.ObjectIdentification("ttoolbar").OrdinalIdentifier = "location"
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.Add("nativeclass")
    App.Options.ObjectIdentification("ttoolbar").MandatoryProperties.Add("text")
    App.Options.ObjectIdentification("ttoolbar").AssistiveProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").AssistiveProperties.Add("window id")
    App.Options.ObjectIdentification("ttoolbar").EnableSmartIdentification = False
    App.Options.ObjectIdentification("ttoolbar").BaseFilterProperties.RemoveAll()
    App.Options.ObjectIdentification("ttoolbar").OptionalFilterProperties.RemoveAll()
     
    'Object identification configuration for user-defined object "tnoteeditor"
    App.Options.ObjectIdentification("WinEditor").CreateUserDefinedObject("tnoteeditor")
    App.Options.ObjectIdentification("tnoteeditor").OrdinalIdentifier = "location"
    App.Options.ObjectIdentification("tnoteeditor").MandatoryProperties.RemoveAll()
    App.Options.ObjectIdentification("tnoteeditor").MandatoryProperties.Add("attached text")
    App.Options.ObjectIdentification("tnoteeditor").MandatoryProperties.Add("nativeclass")
    App.Options.ObjectIdentification("tnoteeditor").AssistiveProperties.RemoveAll()
    App.Options.ObjectIdentification("tnoteeditor").AssistiveProperties.Add("window id")
    App.Options.ObjectIdentification("tnoteeditor").EnableSmartIdentification = False
    App.Options.ObjectIdentification("tnoteeditor").BaseFilterProperties.RemoveAll()
    App.Options.ObjectIdentification("tnoteeditor").OptionalFilterProperties.RemoveAll()
    **************************************************************************************
     
    *在脚本运行结束时需要运行以下脚本,以清除自己的配置,防止影响别人脚本的运行:
    **************************************************************************************
    App.Options.ObjectIdentification.ResetAll
    Set App = Nothing
     **************************************************************************************

  • (转)使用QTP统计页面加载时间

    2009-09-14 14:10:23

    QTP是一款功能自动化测试工具,而页面加载时间或响应速度应该是性能测试的事情,其实QTP也可以实现对页面加载时间的统计功能。因为QTP使用的是VBS脚本,VBS脚本的强大之处在于它可以调用任何windows的COM组件和对象。那么问题解决的思路就很简单了,就是我们要利用VBS获取 IE网页,并统计网页加载的时间。

      分析很简单,但是在实现上却有几个技术问题:一、如何使用VBS分析网页。我们知道网页技术是基于DOM模型的(也不知道这么说是不是准确),那么只要我们能用VBS调用DOM下的document对象,那么我们就可以使用document的方法来实现我们的要求;二、如果能实现对DOM的调用,我们如何统计页面加载的各个阶段的时间,通过查阅资料可以知道,在document中有一个readystate方法,该方法共有五个返回值,分别对应网页初始化到网页加载完毕五个阶段,我们可以利用该方法实现我们的要求。

      实现的思路如下:

      1、利用createobject创建一个IE的实例,以访问document对象;

      2、利用document对象的readystate属性获取网页加载时各个阶段的时间,

      3、利用timer()实现对毫秒的统计。timer()函数的作用是统计从午夜时间到当前时间所过去的秒数,我们用两个timer值想减就可以得到两个时间点之间相隔的毫秒数。

      4、为了方便调用,将时间统计的代码封装成一个函数。

      最后代码如下:

    '在loadrunner脚本中,把要访问的url做参数化,变量名为SITEURL
    'timeCount方法返回一个字符串,字符串的内容是统计各个阶段发生的时间
    '可以使用各种方法查看result的内容
    SITEURL = "www.sina.com.cn"'设置要进行访问的URL
    result = timeCount(SITEURL)'返回运行结果
    MsgBox result '输出运行结果,在loadrunner中可以将该行注释掉

    '方法定义开始
    Public Function timeCount(url)
    Set dom = CreateObject("InternetExplorer.Application")  '创建一个IE的对象
    dom.Navigate(url)  '打开指定的URL
    time_start = Now()'获取统计开始时的时间
    timer_start = timer()'获取当前时间的毫秒数
    'a = dom.ReadyState'获取当前IE的状态值,将使用该状态值判断IE的当前状态
    dom.visible = True '设置IE可见
    While dom.busy or (dom.readyState<>4)'当IE处于BUSY状态或者加载未完成时(readystate不等于4)时,根据IE的状态统计时间,每毫秒统计一次
    wscrīpt.sleep 1 '时间间隔1毫秒,如果时间间隔比较长的话,很有可能会取不到状态值
    Select Case dom.readystate '判断dom.readystate的值

    Case 0 'IE未初始化,其实在该方法,readystate=0无意义,因为循环至少是从1开始的.
    time0 = Now()
    timer0 = timer()

    Case 1 '"正在发送请求"
    time1 = Now()
    timer1 = timer()

    Case 2 '"请求已经发送完成"
    time2 = Now()
    timer2 = timer()

    Case 3 '"可以接收到部分响应数据"
    time3 = Now()
    timer3 = timer()

    Case 4 '"页面加载完成"
    time4 = Now()
    timer4 = timer()

    End select
    wend
    time_end = Now() '统计结束时间
    'MsgBox "开始时间是:" & time1 & ";结束时间是"&time2

    timeCount = "统计开始时间:"&start_time&vbcrlf&"time0:"&time0&vbcrlf&"time1:"&time1&vbcrlf&"time2:
    "&time2&vbcrlf&"time3:"&time3&vbcrlf&"time4:"&time4&vbcrlf&"完成IE的初始化并发送请求:
    "&(timer1-timer_start)&"秒"&vbcrlf&"发送完成并接受服务端部分响应数据:
    "&(timer3-timer1)&"秒"&vbcrlf&"100%接收并完成HTML内容解析:
    "&(timer4-timer3)&"秒"&vbcrlf&"总共花费:"&(timer4-timer_start)&"秒"
    End Function

     代码中的SITEURL就是我们要进行测试的页面。

      这段代码虽然不长,但是却花了我整整4个小时的时间。一开始碰到的难题就是不知道VBS如何去调用document方法,在网上查了无数资料,大多是讲如何在HTML代码中进行调用,很少说到如何使用标准VBS去调用,其实到最后才明白,VBS调用访问document无非就是这样的一句代码:

      Set dom = CreateObject("InternetExplorer.Application")

      虽然简单,但是却花了我一个小时才明白。

      通过这样的一段代码时间,我现在清楚了两件事,第一:VBS作为脚本语言,它的强大之处在于它调用windows的COM能力,而VBS本身并没有什么复杂的技术和体系。第二:QTP永远只是一款工具,它能做什么取决于我们如何去使用。

  • 使用QTP完成回归脚本(转)

    2009-09-14 12:10:00

    最近组内在写项目的回归脚本,且组内新人较多,看到好多同学为写脚本而不知所措,现想把自己曾经学习QTP的笔记和经验跟大家分享下,希望有所帮助。

      QTP可以自动捕获、验证和重放用户的交互行为。它的自动化测试流程包括:

      ● 准备Test Case

      ● 录制脚本

      ● 修改增强脚本

      ● 调试脚本

      ● 回放脚本

      ● 脚本维护

      1. 准备Test Case

      在进行脚本编写之前,将要测试内容文档化,不建议直接录制脚本。

      测试内容文档化的好处

      – 在录制前将脚本设计好,可以保证脚本录制过程更流畅

      – 利于团队协作,设计测试案例和脚本开发可以不是同一个人

      – 便于后期的维护

      2. 录制脚本

      启动QTP的录制功能(面板上的Record),按照Test Case的操作步骤描述执行,QTP自动记录每一步操作,并自动生成VBscript脚本。

      3. 修改增强脚本

      录制好的脚本可能包含错误,也可能没达到预期的目标,这就需要在录制脚本的基础上,进行修改增强:

      – 删除录制过程中多余的操作,以最少的步骤完成必要的操作。

      – 如果后续操作的输入是前面操作的输出,则需要使用变量或者输入输出值进行替换。

      – 不是所有的操作都可以录制产生,需要手工编码实现这些功能,如对Excel文件的读写,数据库的操作等。

      – 录制产生的脚本为线性结构,可加入条件、循环控制语句,如if、while等语句,实现一些复杂的流程。

      – 脚本加入注释,便于阅读和维护。

      4. 调试脚本

      并非只有等到脚本回放失败时,才需对脚本进行调试,正确回放的脚本同样会包含错误。

      – Test Script由操作步骤和检查步骤组成;

      – 操作步骤只要能够执行成功结果均为Pass,如使用了非预期输入数据而也能执行成功;

      – 检查点步骤有预先设定的判断标准,但是如果标准是变量或者是参数,就需要仔细检查数据是否为预期数据

      – 在回放之前,可以通过插入断点,对脚本中的关键数据进行检查核对,确保脚本正式使用前Test Script本身正确性。

      5. 回放脚本

      通过前面一系列的工作,再点击面板上的Run按钮就可以回放Test Script里的操作了。

      6. 脚本维护

      随着工作的不断推进,脚本量会越来越多;被测程序的更新,也需要相应的更新测试脚本。脚本的维护变得愈发重要。

      – 采用版本管理工具保存脚本,如SVN,可以随时获取历史版本

      – 采用统一的脚本架构

      – 采用统一的命名规范

      – 添加充分的注释,避免时间久了连自己也无法马上读懂脚本。

      在今后的文章中,我将分别来描述以下QTP里的一些比较常用的几个功能点:

      ●对象识别及存储>>

      ●QTP 检查点(CheckPoint)>>

      ● 参数化

      ● 数据驱动

      ● 脚本复用

      ● 恢复场景

      ● 虚拟对象

      ● 脚本调试

      ● 正则表达式

  • 如何在LoadRunner中监控Oracle数据库(转)

    2009-09-14 11:58:59

     1、使用LR自带的监控引擎

      在LR的controller上安装oracle客户端:

      这一步就不用说了,安装直接Setup,安装就OK了。

      1)安装完后,先配置一下Net Configuration Assistant。记住配置的服务名。

      配置成功会显示:正在连接...测试成功。

      2)用sqlplus连接一下,看是否可以连接成功,打开sqlplus输入oracle用户名密码和主机字符串。

      查看是否登录成功。

      添加oracle计数器:

      3)登录成功后,打开LR的controller.,在可用图中选择oracle,点击add measurements,再点击Advanced,如下所示:

      这里我们用LR native monitors。

      4)在Monitored Server Machines区域,添加oracle服务器所在的IP。

      5)再在Resource Measurements on:IP区域点击添加,弹出对话框如下:

      6)输入相应的信息,这里的orcl就是前面在Net Configuration Assistant配置的服务名。

      7)点击OK,这里我们应该可以看到可以添加oracle的计数器了,如下所示:

     2、使用Sitescope引擎

      不需要配置Net Configuration Assistant。

      1)在第一个图choose monitor engine中选择sitescope,然后在在Monitored Server Machines区域点击Add如下所示:

      在这里可以选择本地或者其他机器的sitescope,如果sitescope启用了account的验证,也要写上相应的用户名密码。

      2)在Resource Measurements on:IP区域点击添加,弹出对话框如下:

      3)输入信息如图。点击OK,如下:

      至此就可以监控Oracle了。

  • QTP:vbs测试webservice脚本(转)

    2009-09-14 11:49:33

    脚本是写着玩的,有什么建议或者意见,欢迎各位行家指出。

      脚本部分:

    作者:  aslandhu
    '公司:  中科大讯飞科技股份有限公司
    '部门:  技术质量部
    '脚本功能:     webservice自动化测试,自动读取测试用例,用例配置文件,最终将测试结果写入用例中。
    '开发开始时间: 2009-4-20
    '******************************************************************webservice 测试开始*************************************************************
    '请在使用前调试脚本确保脚本能正常工作
    '请严格使用提供的模板编写用例,否则脚本无法正常工作
    '***************************************************************** 收集相关信息************************************************************************
    Dim SoapText,XmlHead,XmlLast,SoapQuest,MethodInput,XmlMethodString1,XmlMethodString2,WebserviceAddress,testResult,ResultPath
    MethodInput=InputBox("方法名称为:")
    Dim n,m,i,j,a,b,k,c 'n为参数个数,也即用例需要取值的列数量,m为用例数量即Excel行数,K为方法数量(保留)
    n=CInt(InputBox("参数个数为:"))
    k=CInt(inputbox("需要比较的返回值个数"))
    m=CInt(InputBox("Excel行数,即用例数:"))
    WebserviceAddress=Inputbox("接口URL为:")
    TestPath=Inputbox("完整用例路径:")
    Dim ArrayInfo()
    ReDim ArrayInfo(m,n)
    '**************************************************************** 拼装SOAP头尾消息*****************************************************************
    XmlHead="<?xml version=""1.0"" encoding=""utf-16""?>"&"<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">"&"<soap:Body>"
    XmlLast="</soap:Body>"&"</soap:Envelope>"
    XmlMethodString1="<"&MethodInput&" "&"xmlns=""http://tempuri.org/"">"'&"<model>"
    'XmlMethodString2="</model>"&"</"&MethodInput&">"
    XmlMethodString2="</"&MethodInput&">"
    '***************************************************************** 创建Excel对象,准备读取用例************************************************
    Set Excel = CreateObject("Excel.Application")
    oExcel.DisplayAlerts=FALSE
    oExcel.Visible = false
    oExcel.WorkBooks.Open(TestPath)
    oExcel.WorkSheets(MethodInput).Activate
    '***************************************************************** 将用例存入数组********************************************************************
    For i=1 To m  '行数3,b
      For j=1 To n  '列数2,a
      ArrayInfo(i,j)= oExcel.Cells(i,j).Value
     Next
    Next
    '**************************************************************** 开始组装SOAP主体*****************************************************************
    SoapText=""
    For b=2 To m
    For a=1 To n
    SoapText=SoapText&"<"&ArrayInfo(1,a)&">"&ArrayInfo(b,a)&"</"&ArrayInfo(1,a)&">"
    Next
    SoapQuest=XmlHead&XmlMethodString1&SoapText&XmlMethodString2&XmlLast
    'MsgBox(SoapQuest)
    WriteToFile  "c:\test.txt",SoapQuest
    '**************************************************************** 开始循环发送消息*********************************************************************
    '定义一XML的文档对象
    '初始化http对象
    Set h = createobject( "Microsoft.XMLHTTP")
    h.open "POST", WebserviceAddress, False
    h.setRequestHeader "Content-Type", "text/xml; charset=utf-8"
    h.setRequestHeader "SOAPAction", "http://tempuri.org/"&MethodInput
    h.send (SoapQuest)
    While h.readyState <> 4
    Wend
    '***************************************************************循环处理返回结果并将结果写入用例***********************************************
    For c=n+1 to n+k
    testResult=oExcel.Cells(1,c).Value
    If  oExcel.Cells(b,c).Value <>NodeData(h.responseText,testResult) then
       oExcel.Cells(b,c+k).Value ="false"
              oExcel.Cells(b,c+k).Font.Color = RGB(255, 0, 225)
       oExcel.Cells(b,c+k).Interior.Color = RGB(0, 255, 0) 'Background color
                     oExcel.Cells(b,c+k).Font.Bold = True
     else
       oExcel.Cells(b,c+k).Value ="true"
       oExcel.Cells(b,c+k).Font.Color = RGB(0, 0, 0)
       oExcel.Cells(b,c+k).Interior.Color = RGB(255, 255, 255) '
    end if
    Next
    SoapText=""
    Next

    '****************************************************************释放Excel对象,并将结果写到指定路径***************************************
    CheckFolder "C:\TestResult"
    ResultPath="C:\TestResult\"&MethodInput&".xls"
    oExcel.WorkSheets(MethodInput).SaveAs ResultPath
    oExcel.WorkBooks.Close
    oExcel.Quit
    Set Excel=nothing

    '*************************************************************** 以下是被调用的函数****************************************************************
    '获取结点值并输出到txt文本
    function NodeData(XmlString,Node)
    Dim ResultArray,NodeString,NodeDateLen,No,i
    ResultArray=Split(XmlString,Node,-1,1)
    No=UBound(ResultArray) '获取数组上界
    '循环查找符合要求的字节
    For i=1 To No Step 2
    NodeString=ResultArray(i)
    NodeDateLen=Len(NodeString)-3
    NodeData=Mid(NodeString,2,NodeDateLen)
    Next
    End function


    ''将string写入文本
    Sub WriteToFile (filepath,text)
      Dim fso, MyFile,txtFile
    if  IsFileExist(filepath)=true then
      Set fso = CreateObject("Scripting.FileSystemObject")
      Set txtFile = fso.GetFile(filepath)
      Set MyFile = txtFile.OpenAsTextStream(8, 0)
      MyFile.Write text&vbcrlf
      MyFile.Close
      else
      CreatedFile(filepath)
       Set fso = CreateObject("Scripting.FileSystemObject")
      Set txtFile = fso.GetFile(filepath)
      Set MyFile = txtFile.OpenAsTextStream(8, 0)
      MyFile.Write text&vbcrlf
      MyFile.Close
      end if
    End Sub

    '创建文本文件
    Sub CreatedFile(filepath)
     Set fso = CreateObject("Scripting.FileSystemObject")
        Set MyFile = fso.CreateTextFile(filepath, true)
        MyFile.WriteLine("<!-- Result -->")
        MyFile.Close
    End Sub

    '判断txt文件是否存在
    Function IsFileExist(filepath)
      Dim fso
      Set fso = CreateObject("Scripting.FileSystemObject")
      IsFileExist = fso.FileExists(filepath)
    End Function

    Sub CheckFolder(folderpath)
    Dim fso,CreateFolderSuccess,f
    Set fso=CreateObject("Scripting.FileSystemObject")
    If  fso.FolderExists(folderpath)=false Then
     Set f = fso.CreateFolder(folderpath)
      CreateFolderSuccess = f.Path
      Else
      Set fso=nothing
    End If
    End Sub

      脚本使用步骤:

      1、运行脚本,提示输入方法名称。

      2、提示输入参数个数:(参数个数为方法需要传入的参数个数,即用例中的输入)

      3、提示输入需要比较的返回值的个数:(指的是输出的结果的个数,用例中写了几列就输入几列(不带单位))

      4、提示输入Excel行数,即用例个数(包括第一列非用例,即总行数):

      5、提示输入接口URL(即接口链接地址):

      6、提示输入完整用例路径(即用例存放地址):

      7、等待执行一段时间

      8、查看C:\TestResult,可以获取测试结果如下:(出现与预期结果不一致的用例会使用绿色将结果标明)

      9、测试完成。

      注意事项:

      (1)目前仅实现一个方法一个脚本,且一个Excel只能存放一个方法的测试用例(后期改进)

      (2)未实现结果的统计(后期实现)

      (3)前面要求输入的内容必须准确可靠,否则脚本会执行出错(后期改进容错能力,会考虑加入脚本配置文件)

      (4)脚本必须配合指定的用例模板

      (5)建议脚本不要使用QTP执行,直接双击操作。在QTP上运行的话,脚本执行速度会非常慢。

  • LR监控linux之详解rstatd的安装(转)

    2009-09-14 11:36:40

    1.前期准备:
     
     
    1,把rstatd文件解压到要监控的机器上。
    2,打开终端,定位到rstatd文件夹下:查看文件夹中的内容如下:
      
    [root@localhost rpc.rstatd]# ls
    aclocal.m4    COPYING     Makefile.am    README        rstat_proc.c rup.1
    config.h.in   CVS         Makefile.in    rpc.rstatd.8 rstat.x       rup.c
    configure     INSTALL     missing        rstatd.8      rsysinfo.1    stamp-h.in
    configure.in install-sh mkinstalldirs rstat_main.c rsysinfo.c
    2.执行如下步骤:
     
     
    2.1.执行:./configure 命令
     
     
    [root@localhost rpc.rstatd]# ./configure
    creating cache ./config.cache
    checking for a BSD compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking whether make sets ${MAKE}... yes
    checking for working aclocal... found
    checking for working autoconf... found
    checking for working automake... found
    checking for working autoheader... found
    checking for working makeinfo... found
    checking for gawk... gawk
    checking for gcc... gcc
    checking whether the C compiler (gcc ) works... yes
    checking whether the C compiler (gcc ) is a cross-compiler... no
    checking whether we are using GNU C... yes
    checking whether gcc accepts -g... yes
    checking for a BSD compatible install... /usr/bin/install -c
    checking whether ln -s works... yes
    checking whether make sets ${MAKE}... (cached) yes
    checking how to run the C preprocessor... gcc -E
    checking for sys/ioctl.h... yes
    checking for syslog.h... yes
    checking whether time.h and sys/time.h may both be included... yes
    checking whether gcc needs -traditional... no
    checking for ANSI C header files... yes
    checking return type of signal handlers... void
    updating cache ./config.cache
    creating ./config.status
    kcreating Makefile
    creating config.h
     
    2.2.执行:make 命令。
    [root@localhost rpc.rstatd]# make
    rm -f rstat.h
    rpcgen -h -o rstat.h rstat.x
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rup.c
    rup.c: In function 'ointopoint_v5':
    rup.c:256: warning: passing argument 6 of 'client->cl_ops->cl_call'?from incompatible pointer type
    rup.c: In function 'ointopoint_v3'?
    rup.c:292: warning: passing argument 6 of 'client->cl_ops->cl_call'?from incompatible pointer type
    rup.c: In function 'main'?
    rup.c:317: warning: return type of 'main'?is not 'int'?rm -f rstat_xdr.c
    rpcgen -c -o rstat_xdr.c rstat.x
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rstat_xdr.c
    rm -f rstat_clnt.c
    rpcgen -l -o rstat_clnt.c rstat.x
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rstat_clnt.c
    gcc -g -O2 -o rup rup.o rstat_xdr.o rstat_clnt.o 
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rsysinfo.c
    rsysinfo.c: In function 'ointopoint_v3'?
    rsysinfo.c:136: warning: passing argument 6 of 'client->cl_ops->cl_call'?from incompatible pointer type
    rsysinfo.c: In function 'main'?
    rsysinfo.c:160: warning: return type of 'main'?is not 'int'?gcc -g -O2 -o rsysinfo rsysinfo.o rstat_xdr.o rstat_clnt.o 
    rm -f rstat_svc.c
    rpcgen -m -o rstat_svc.c rstat.x
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rstat_svc.c
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rstat_proc.c
    gcc -DHAVE_CONFIG_H -I. -I. -I.     -g -O2 -c rstat_main.c
    rstat_main.c: In function 'main'?
    rstat_main.c:82: warning: return type of 'main'?is not 'int'?gcc -g -O2 -o rpc.rstatd rstat_svc.o rstat_xdr.o rstat_proc.o rstat_main.o 
      这之后可以执行:make check检查一下。

    2.3.执行:make install 命令。

       

    [root@localhost rpc.rstatd]# make install
    make[1]: Entering directory `/opt/rpc.rstatd'
    /bin/sh ./mkinstalldirs /usr/local/bin
     /usr/bin/install -c rup /usr/local/bin/rup
     /usr/bin/install -c rsysinfo /usr/local/bin/rsysinfo
    /bin/sh ./mkinstalldirs /usr/local/sbin
     /usr/bin/install -c rpc.rstatd /usr/local/sbin/rpc.rstatd
    make[1]: Nothing to be done for `install-data-am'.
    make[1]: Leaving directory `/opt/rpc.rstatd'

    2.4.执行:./rpc.rstatd 命令。启动rpc服务。
     
     
    注:无回显为成功。

        

    [root@localhost rpc.rstatd]# ./rpc.rstatd

    2.5.执行:rpcinfo –p 命令。检查rpc服务的状态.
       
    [root@localhost rpc.rstatd]# rpcinfo -p
       program vers proto   port
        100000    2   tcp    111 portmapper
        100000    2   udp    111 portmapper
        100024    1   udp    797 status
        100024    1   tcp    800 status
        100001    5   udp    900 rstatd
        100001    3   udp    900 rstatd
        100001    2   udp    900 rstatd
        100001    1   udp    900 rstatd
    [root@localhost rpc.rstatd]#
    3.    可能会出现的错误:
     
    1,若RPC服务没有成功启动。
    2,若目标主机上开启了防火墙,阻挡了RPC服务。
    在LR中添加时可能会出现如下错误:
      

    Monitor name :UNIX Resources. Cannot initialize the monitoring on 10.1.200.65. Error while creating the RPC client. Ensure that the machine can be connected and that it runs the rstat daemon (use rpcinfo utility for this verification). Detailed error: RPC: Failed to create RPC client.
    RPC-TCP: Failed to establish RPC server address.
    RPC-TCP: RPC Server <100001, 3, 17> is not registered on host '10.1.200.65'. (entry point: CFactory::Initialize).   [MsgId: MMSG-47190]

     

    Monitor name :UNIX Resources. Internal rpc error (error code:2). Machine: 10.1.200.65. Hint: Check that RPC on this machine is up and running. Check that rstat daemon on this machine is up and running (use rpcinfo utility for this verification). Details: RPC: RPC call failed.
    RPC-TCP: recv()/recvfrom() failed.
    RPC-TCP: Timeout reached. (entry point: Factory::CollectData). [MsgId: MMSG-47197]

     
    至此完毕。
  • Error -26612

    2009-09-14 10:12:21

    1、设置代理服务器可能引起这个MERR-26612,取消代理服务器的设置解决
    2、取消选中run time settings-browser emulation-download non-html resources.解决
    3、没有设置关联,在录制完成之后F8,自动关联看看
    4、服务器程序本身问题
  • (转)QTP脚本中使用正则表达式,匹配字符串方法

    2009-09-10 23:01:20

    第一、首先正则表达式使用如下对象。

      1、RegExp 这是使用正则表达式匹配模式的主要对象了

      属性:

      Pattern:一个字符串,用来定义正则表达式<匹配规则>。

      IgnoreCase:如果True,则忽略英文字母大小的匹配,False对大小写进行匹配。

      Global:设置True则必须匹配整个<匹配规则>,设置False只匹配第一个<匹配规则>。

      MultiLine:设置True则在多行中搜索。设置False则在换行时停止。

      方法:

      Execute:返回一个MatchCollection对象,该对象包含每个成功匹配的Match对象。

      Replace:返回一个将符合<匹配规则>的字符串替换为指定字符串。

      Test:返回一个布尔值,该值指示正则表达式是否与字符串成功匹配。

      2、MatchCollection 是集合对象,该对象包含每个成功匹配的Match对象。

      属性:

      Count:匹配对象的总数。

      Item:匹配对象的索引。

      3、Match 是成功匹配的对象。

      属性:

      FirstIndex:匹配对象所匹配字符串的起始位置。

      Length:匹配对象所匹配字符串的字符长度。

      SubMatches:匹配对象所匹配结果的子项。也就是<匹配规则>中下一个匹配项“一般一个()代表一个匹配项”

      Value:匹配对象所匹配的值。

    第二、RegExp对象的Test方法:测试字符串是否符合匹配规则。

    FunctionRTest(s, p)
        Setre =NewRegExp
         re.IgnoreCase =False '设置是否忽略大小写
         re.Pattern = p
         RTest= re.Test(s)
    End Function

      一般我们在QTP中使用正则表达式来匹配字符串的话,会编写如上面那样的一个函数。使用方法如下:

      s = “我的邮箱: test@163.com 。欢迎致电!"'用来匹配的字符串,也就是实际上我们要测试的内容

      '检查测试字符串中是否包含数字

      p = “\d+” ’测试是否包含数字的匹配规则

      MsgBoxRTest(s, p)

      '检查测试字符串是否全是由数字组成:

      p = “^\d+$”

      MsgBoxRTest(s, p)

      '检查测试字符串是否有大写字母:

      p = “[A-Z]+”

      MsgBoxRTest(s, p)

      第三、RegExp的Replace方法:把测试字符串中符合匹配规则的字符串替换为指定内容

    FunctionStrReplace(s, p, r)
        Setre =NewRegExp
         re.IgnoreCase =True'设置忽略大小写
         re.Global =True '设置必须匹配整个规则
         re.Pattern = p
         StrReplace = re.Replace(s, r)
    End Function

      上面的就是一般情况下使用这个方法所需要编写的一个函数,下面的就是如何使用

      ‘以下是如何使用这个方法替换邮箱地址

         s = "我的E-mail: Test@163.com 。欢迎致电!"
         p = "\w+@\w+\.(com|cn|net)"
         r = "E_Mail@sohu.net"
         s = StrReplace(s, p, r)
        MsgBox s
        '结果:我的E-mail: E_Mail@sohu.net 。欢迎致电!

      第四、Match的SubMatches属性:下一个匹配项的匹配内容

      仔细看下面这段代码的含义...

        inpStr = "我的E-mail: lucky@163.com 。欢迎致电!"
        Setre =NewRegExp
        re.Pattern = "(\w+)@(\w+).(\w+)" '注意!这个匹配规则有3个(),一个()代表一个匹配项

        Setmhs = re.Execute(inpStr)
        Setmh = mhs(0)            '根据上面的匹配规则可以计算出只有一个匹配结果
       
        MsgBox "电子邮件地址是:"&mh.Value      '这里是匹配的内容
        MsgBox "用户名是:"&mh.SubMatches(0)  '第一个括号<匹配项>中的内容
        MsgBox "邮箱是:"&mh.SubMatches(1)  '第二个括号<匹配项>中的内容
        MsgBox "域名是:"&mh.SubMatches(2)  '第三个括号<匹配项>中的内容


  • LoadRunner压力测试结果分析探讨(转)

    2009-09-10 22:36:53

      分析原则:

      1. 具体问题具体分析(这是由于不同的应用系统,不同的测试目的,不同的性能关注点)

      2. 查找瓶颈时按以下顺序,由易到难。

      服务器硬件瓶颈  网络瓶颈(对局域网,可以不考虑)  服务器操作系统瓶颈(参数配置)  中间件瓶颈(参数配置,数据库web服务器等)  应用瓶颈(SQL语句、数据库设计、业务逻辑、算法等)

      分析的信息来源:

      1. 根据场景运行过程中的错误提示信息

      2. 根据测试结果收集到的监控指标数据

      一.错误提示分析

      分析实例:

      1.Error: Failed to connect to server “172.17.7.230″: [10060] Connection

      Error: timed out Error: Server “172.17.7.230″ has shut down the connection prematurely

      分析:

      A、应用服务死掉。

      (小用户时:程序上的问题。程序上处理数据库的问题,实际测试中多半是服务器链接的配置问题)

      B、应用服务没有死

      (应用服务参数设置问题)

      对应的Apache和tomcat的最大链接数需要修改,如果连接时收到connection refused消息,说明应提高相应的服务器最大连接的设置,增加幅度要根据实际情况和服务器硬件的情况来定,建议每次增加25%!

      C、数据库的连接

      (数据库启动的最大连接数(跟硬件的内存有关))

      D、我们的应用程序spring控制的最大链接数太低

      2. Error: Page download timeout (120 seconds) has expired

      分析:

      A、应用服务参数设置太大导致服务器的瓶颈

      B、页面中图片太多

      C、在程序处理表的时候检查字段太大多

      D、实际测试时有些资源需要请求外网,而我们的测试环境是局域网环境

      3. Error “http://172.17.7.230/Home.do....”

      分析:

      A、脚本设计错误,造成页面异常。服务器有响应!

      B、并发数过大,造成服务器响应延迟。

      4. Error page “text=xxxxx”

      分析:

      A、脚本设计问题,例如,前一脚本修改了某些内容,造成后面的脚本访问异常。

      B、不确定因素,有时候回放正常的脚本,一放到场景中就出现这样的错误。只能反复修改脚本!

      二.监控指标数据分析

      1.Vusers数

      Loadrunner 系统设置的虚拟用户数目。Vuser去实际调用事先制作的脚本文件中的应用。

      每个Vuser产生响应的操作,所有的操作对服务器形成并发。

      颜色 比例 度量 图最小值 图平均值 图最大值 图中间值 图SD

      1 Run 0.0 21.25 44 41 21.276

      在实际测试中,Vusers可以根据实际情况的需要,在测试过程中增加或者减少。

      2.最大并发用户数:

      颜色 比例 度量 最小值 平均值 最大值 SD

      100 Apache CPU 使用情况(Apache):172.17.7.210 0.777 0.852 0.93 0.043

      0.01 已发送 KB/秒(Apache):172.17.7.210 6 1430.371 2689.333 327.924

      0.1 点击次数/秒(Apache):172.17.7.210 0.333 114.352 533.667 40.201

      应用系统在当前环境下能承受的最大并发用户数。

      在方案运行中,如果出现了大批用户的业务操作失败,或出现了服务器shutdown的情况,则说明在当前环境下,系统承受不了当前并发用户的负载压力,那么最大并发用户数就是前一个没有出现这种现象的并发用户数。

      从上图可以看出:在测试运行到4个小时左右的时候,apache的点击数/秒开始迅速增加!

    3.业务操作响应时间:

      使用“事务性能摘要”图,可以确定在方案执行期间响应时间过长的事务。

      颜色 比例 度量

      1 最小值

      1 平均值

      1 最大值

      分析事务的响应情况,要每次详细分析,目前还只能观察到响应时间过长的事务!

      4.每秒点击数

      负载测试期间每秒内 Vuser 在 Web 服务器上点击的次数。可根据点击次数来估算 Vuser 生成的负载数。

      颜色 比例 度量 图最小值 平均值 图最大值 图中间值 图SD

      1 点击次数 69.908 105.736 130.244 103.666 12.186

      从图中不难看出,在4小时的时候,点技数明显增高。和apache的每秒点击数增大的时间相吻合!

      5.吞吐量

      负载测试期间 Web 服务器上的吞吐量(字节)。吞吐量表示在任何指定秒内 Vuser 从服务器接收到的数据量。此图可估计 Vuser 生成的负载量(服务器吞吐量)。

      颜色 比例 度量 图最小值 平均值 图最大值 图中间值 图SD

      1 Throughput 1257502.795 1375591.372 1525865.047 1372743.691 49130.473

      同样,从图中可以看出,在4个小时的时候,web服务器的吞吐量开始增高。在图中还可以看到吞吐量的走势图,从开始到进行到4个小时反弹之前呈降低的趋势,这是因为系统在初期调用的资源都是直接来之服务器,运行一段时间后系统的部分资源来自缓存。

      6.下载组件大小

      每个页面的组件大小,且包括组件的标头的大小!

      页面组件大小的分析表格比较复杂,实际分析中可以通过loadrunner的报告分析工具来分析。页面组件大小分析主要是找到页面中比较庞大的组件,如果其影响到了页面的下载速度,则要想办法将其改小!

      7.Apache资源

      显示APACHE web服务器上的资源摘要。前面已经提到过以并发点击数为主。

      颜色 比例 度量 最小值 平均值 最大值 SD

      100 Apache CPU 使用情况(Apache):172.17.7.210 0.777 0.852 0.93 0.043

      0.01 已发送 KB/秒(Apache):172.17.7.210 6 1430.371 2689.333 327.924

      0.1 点击次数/秒(Apache):172.17.7.210 0.333 114.352 533.667 40.201

      三.服务器资源监控指标:

      (目前通过top监察)

      内存:

      Linux资源监控中指标内存页交换速率(Paging rate),如果该值偶尔走高,表明当时有线程竞争内存。如果持续很高,则内存可能是瓶颈。也可能是内存访问命中率低。

      实际测试中,当并发点击数出现突然剧增前后,内存的PR 值则居高25不下。说明目前测试的系统中内存存在瓶颈!

      内存资源成为系统性能的瓶颈的征兆:

      很高的换页率(high pageout rate);

      进程进入不活动状态;

      交换区所有磁盘的活动次数可高;

      可高的全局系统CPU利用率;

      内存不够出错(out of memory errors)

      处理器:

      Linux资源监控中指标CPU占用率持续超过80%(对该值的要求,根据具体应用和机器配置而要求不同,有资料表明95%),表明瓶颈是CPU。

      实际测试中,当并发点技数出现突然增加前后,cpu的占用率持续保持在86%以上!

      说明,目前系统用应用的cpu也是测试的瓶颈!

      CPU资源成为系统性能的瓶颈的征兆:

      很慢的响应时间(slow response time)

      CPU空闲时间为零(zero percent idle CPU)

      过高的用户占用CPU时间(high percent user CPU)

      过高的系统占用CPU时间(high percent system CPU)

      长时间的有很长的运行进程队列(large run queue size sustained over time)

      四.数据库服务器:

      数据库服务器目前测试观察,当web服务器点击率增大时,观察mysql数据库的最大连接数,仍未超过系统设置的最大连接数。所以,暂时未发现数据库的瓶颈!

      五.结论

      以上报告分析中的数据、图标均来自同一次测试。是在平时测试中挑出的一次现象比较明显,比较利于观察的作为分析案例。

      根据以上综合分析,当前测试环境下,当应用系统产生最大533.667的并发压力。平均负载压力114.352。根据分析,用户在4个小时的时候,并发数迅速增加前后的值在400左右!分析结果跟实际测试的硬件环境以及测试脚本有一定关系。同时,测试服务器的硬件配置和实际服务器的配置还有一定的差距!

  • LoadRunner常见测试结果分析(转)

    2009-09-10 22:30:38

    测试过程中,可能会出现以下常见的几种测试情况:

      一、当事务响应时间的曲线开始由缓慢上升,然后处于平衡,最后慢慢下降这种情形表明:

      * 从事务响应时间曲线图持续上升表明系统的处理能力在下降,事务的响应时间变长;

      * 持续平衡表明并发用户数达到一定数量,在多也可能接受不了,再有请求数,就等待;

      * 当事务的响应时间在下降,表明并发用户的数量在慢慢减少,事务的请求数也在减少。

      如果系统没有这种下降机制,响应时间越来越长,直到系统瘫痪。

      从以上的结果分析可发现是由以下的原因引起:

      1. 程序中用户数连接未做限制,导致请求数不断上升,响应时间不断变长;

      2. 内存泄露;

      二、CPU的使用率不断上升,内存的使用率也是不断上升,其他一切都很正常;

      表明系统中可能产生资源争用情况;

      引起原因:

      开发人员注意资源调配问题。

      三、 所有的事务响应时间、cpu等都很正常,业务出现失败情况;

      引起原因:

      数据库可能被锁,就是说,你在操作一张表或一条记录,别人就不能使用,即数据存在互斥性;

      当数据量大时,就会出现数据错乱情况。

  • (转)LoadRunner分析结果图功能说明

    2009-09-06 17:06:12

    Transactions(用户事务分析)
    用户事务分析是站在用户角度进行的基础性能分析。

    1、Transation Sunmmary(事务综述)
    对事务进行综合分析是性能分析的第一步,通过分析
    测试时间内用户事务的成功与失败情况,可以直接判断出系统是否运行正常。

    2、Average Transaciton Response Time(事务平均响应时间)
    “事务平均响应时间”显示的是测试场景运行期间的每一秒内事务执行所用的平均时间,通过它可以分析测试场景运行期间应用系统的性能走向。
    例:随着测试时间的变化,系统处理事务的速度开始逐渐变慢,这说明应用系统随着投产时间的变化,整体性能将会有下降的趋势

    3、Transactions per Second(每秒通过事务数/TPS)
    “每秒通过事务数/TPS”显示在场景运行的每一秒钟,每个事务通过、失败以及停止的数量,使考查系统性能的一个重要参数。通过它可以确定系统在任何给定时刻的时间事务负载。分析TPS主要是看曲线的性能走向。
    将它与平均事务响应时间进行对比,可以分析事务数目对执行时间的影响。
    例:当压力加大时,点击率/TPS曲线如果变化缓慢或者有平坦的趋势,很有可能是服务器开始出现瓶颈。

    4、Total Transactions per Second(每秒通过事务总数)
    “每秒通过事务总数”显示在场景运行时,在每一秒内通过的事务总数、失败的事务总署以及停止的事务总数。

    5、Transaction Performance Sunmmary(事务性能摘要)
    “事务性能摘要”显示方案中所有事务的最小、最大和平均执行时间,可以直接判断响应时间是否符合用户的要求。
    重点关注事务的平均和最大执行时间,如果其范围不在用户可以接受的时间范围内,需要进行原因分析。

    6、Transaction Response Time Under Load(事务响应时间与负载)
    “事务响应时间与负载”是“正在运行的虚拟用户”图和“平均响应事务时间”图的组合,通过它可以看出在任一时间点事务响应时间与用户数目的关系,从而掌握系统在用户并发方面的性能数据,为扩展用户系统提供参考。此图可以查看虚拟用户负载对执行时间的总体影响,对分析具有渐变负载的测试场景比较有用。

    7、Transaction Response Time(Percentile)(事务响应时间(百分比))
    “事务响应时间(百分比)”是根据测试结果进行分析而得到的综合分析图,也就是工具通过一些统计分析方法间接得到的图表。通过它可以分析在给定事务响应时间范围内能执行的事务百分比。

    8、Transaction Response Time(Distribution)(事务响应时间(分布))
    “事务响应时间(分布)”显示在场景运行过程中,事务执行所用时间的分布,通过它可以了解测试过程中不同响应时间的事务数量。如果系统预先定义了相关事务可以接受的最小和最大事务响应时间,则可以使用此图确定服务器性能是否在可以接受的范围内。

     

    Web Resources(Web资源分析)
    Web资源分析是从服务器入手对Web服务器的性能分析。

    1、Hits per Second(每秒点击次数)
    “每秒点击次数”,即使运行场景过程中虚拟用户每秒向Web服务器提交的HTTP请求数。
    通过它可以评估虚拟用户产生的负载量,如将其和“平均事务响应时间”图比较,可以查看点击次数对事务性能产生的影响。通过对查看“每秒点击次数”,可以判断系统是否稳定。系统点击率下降通常表明服务器的响应速度在变慢,需进一步分析,发现系统瓶颈所在。

    2、Throughput(吞吐率)
    “吞吐率”显示的是场景运行过程中服务器的每秒的吞吐量。其度量单位是字节,表示虚拟用在任何给定的每一秒从服务器获得的数据量。
    可以依据服务器的吞吐量来评估虚拟用户产生的负载量,以及看出服务器在流量方面的处理能力以及是否存在瓶颈
    “吞吐率”图和“点击率”图的区别:
    “吞吐率”图,是每秒服务器处理的HTTP申请数。
    “点击率”图,是客户端每秒从服务器获得的总数据量。

    3、HTTP Status Code Summary(HTTP状态代码概要)
    “HTTP状态代码概要”显示场景或会话步骤过程中从Web服务器返回的HTTP状态代码数,该图按照代码分组。HTTP状态代码表示HTTP请求的状态。

    4、HTTP Responses per Second(每秒HTTP响应数)
    “每秒HTTP响应数”是显示运行场景过程中每秒从Web服务器返回的不同HTTP状态代码的数量,还能返回
    其它各类状态码的信息,通过分析状态码,可以判断服务器在压力下的运行情况,也可以通过对图中显示的结果进行分组,进而定位生成错误的代码脚本。

    5、Pages Downloader per Second(每秒下载页面数)
    “每秒下载页面数”显示场景或会话步骤运行的每一秒内从服务器下载的网页数。使用此图可依据下载的页数来计算Vuser生成的负载量。
    和吞吐量图一样,每秒下载页面数图标是Vuser在给定的任一秒内从服务器接收到的数据量。但是吞吐量考虑的各个资源极其大小(例,每个GIF文件的大小、每个网页的大小)。而每秒下载页面数只考虑页面数。
    注:要查看每秒下载页数图,必须在R-T-S那里设置“每秒页面数(仅HTML模式)”。

    6、Retries per Second(每秒重试次数)
    “每秒重试次数”显示场景或会话步骤运行的每一秒内服务器尝试的连接次数。
    在下列情况将重试服务器连接:
    A、初始连接未经授权
    B、要求代理服务器身份验证
    C、服务器关闭了初始连接
    D、初始连接无法连接到服务器
    E、服务器最初无法解析负载生成器的IP地址

    7、Retries Summary(重试次数概要)
    “重试次数概要”显示场景或会话步骤运行过程中服务器尝试的连接次数,它按照重试原因分组。将此图与每秒重试次数图一起使用可以确定场景或会话步骤运行过程中服务器在哪个时间点进行了重试。

    8、Connections(连接数)
    “连接数”显示场景或会话步骤运行过程中每个时间点打开的TCP/IP连接数。
    借助此图,可以知道何时需要添加
    其他连接。
    例:当连接数到达稳定状态而事务响应时间迅速增大时,添加连接可以使性能得到极大提高(事务响应时间将降低)。

    9、Connections Per Second(每秒连接数)
    “每秒连接数”显示方案在运行过程中每秒建立的TCP/IP连接数。
    理想情况下,很多HTTP请求都应该使用同一连接,而不是每个请求都新打开一个连接。通过每秒连接数图可以看出服务器的处理情况,就表明服务器的性能在逐渐下降。

    10、SSLs Per Second(每秒SSL连接数)
    “每秒SSL连接数”显示场景或会话步骤运行的每一秒内打开的新的以及重新使用的SSL连接数。当对安全服务器打开TCP/IP连接后,浏览器将打开SSL连接。


    Web Page Breakdown(网页元素细分)
    “网页元素细分”主要用来评估页面内容是否影响事务的响应时间,通过它可以深入地分析网站上那些下载很慢的图形或中断的连接等有问题的
    元素。

    1、Web Page Breakdown(页面分解总图)
    “页面分解”显示某一具体事务在测试过程的响应情况,进而分析相关的事务运行是否正常。
    “页面分解”图可以按下面四种方式进行进一步细分:
    1)、Download Time Breaddown(下载时间细分)
    “下载时间细分”图显示网页中不同元素的下载时间,同时还可按照下载过程把时间进行分解,用不同的颜色来显示DNS解析时间、建立连接时间、第一次缓冲时间等各自所占比例。
    2)、Component Breakdown(Over Time)(组件细分(随时间变化))
    “组件细分”图显示选定网页的页面组件随时间变化的细分图。通过该图可以很容易的看出哪些元素在测试过程中下载时间不稳定。该图特别适用于需要在客户端下载控件较多的页面,通过分析控件的响应时间,很容易就能发现那些控件不稳定或者比较耗时。
    3)、Download Time Breakdown(Over Time)(下载时间细分(随时间变化))
    “下载时间细分(随时间变化)” 图显示选定网页的页面元素下载时间细分(随时间变化)情况,它非常清晰地显示了页面各个元素在
    压力测试过程中的下载情况。
    “下载时间细分”图显示的是整个测试过程页面元素响应的时间统计分析结果,“下载时间细分(随时间变化)”显示的事场景运行过程中每一秒内页面元素响应时间的统计结果,两者分别从宏观和微观角度来分析页面元素的下载时间。
    4)、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一次缓冲之前的这段时间,场景或会话步骤运行的每一秒中每个网页组件的服务器时间和网络时间(以秒为单位)。
    可以使用该图确定场景或会话步骤运行期间服务器或网络出现问题的时间。
    First Buffer Time:是指客户端与服务器端建立连接后,从服务器发送第一个数据包开始计时,数据经过网络传送到客户端,到浏览器接收到第一个缓冲所用的时间。

    2、Page Component Breakdown(页面组件细分)
    “页面组件细分”图显示每个网页及其组件的平均下载时间(以秒为单位)。可以根据下载组件所用的平均秒数对图列进行排序,通过它有助于隔离有问题的组件。

    3、Page Component Breakdown(Over Time)(页面组件分解(随时间变化))
    “页面组件分解(随时间变化)”图显示在方案运行期间的每一秒内每个网页及其组件的平均响应时间 (以秒为单位)。

    4、Page Download Time Breakdown(页面下载时间细分)
    “页面下载时间细分”图显示每个页面组件下载时间的细分,可以根据它确定在网页下载期间事务响应时间缓慢是由网络错误引起还是由服务器错误引起。
    “页面下载时间细分”图根据DNS解析时间、连接时间、第一次缓冲时间、SSL握手时间、接收时间、FTP验证时间、客户端时间和错误时间来对每个组件的下载过程进行细分。

    5、Page Download Time Breakdown(Over Time)(页面下载时间细分(随时间变化))
    “页面下载时间细分(随时间变化)”图显示方案运行期间,每一秒内每个页面组件下载时间的细分。使用此图可以确定网络或服务器在方案执行期间哪一时间点发生了问题。
    “页面组件细分(随时间变化)”图和“页面下载时间细分(随时间变化)”图通常结合起来进行分析:首先确定有问题的组件,然后分析它们的下载过程,进而定位原因在哪里。

    6、Time to First Buffer Breakdown(第一次缓冲时间细分)
    “第一次缓冲时间细分”图显示成功收到从Web服务器返回的第一次缓冲之前的这一段时间内的每个页面组件的相关服务器/网路时间。如果组件的下载时间很长,则可以使用此图确定产生的问题与服务器有关还是与网络有关。
    网络时间:定义为第一个HTTP请求那一刻开始,直到确认为止所经过的平均时间。
    服务器时间:定义为从收到初始HTTP请求确认开始,直到成功收到来自Web服务器的一次缓冲为止所经过的平均时间。

    7、Time to First Buffer Breakdown(Over Time)(第一次缓冲时间细分(随时间变化))
    “第一次缓冲时间细分(随时间变化)”图显示成功收到从Web服务器返回的第一个缓冲之前的这段时间内,场景运行的每一秒中每个网页组件的服务器时间和网络时间。可以使用此图确定场景运行期间服务器或网络出现问题的时间点。

    8、Downloader Component Size(KB)(已下载组件大小)
    “已下载组件大小”图显示每个已经下载的网页组建的大小。通过它可以直接看出哪些组件比较大并需要进一步进行优化以提高性能

  • 一位前辈工程师的忠告!(转)

    2009-09-06 15:49:39

    [1]好好规划自己的路,不要跟着感觉走!根据个人的理想决策安排,绝大部分人并不指望成为什么院士或教授,而是希望活得滋润一些,爽一些。那么,就需要慎重安排自己的轨迹。从哪个行业入手,逐渐对该行业深入了解,不要频繁跳槽,特别是不要为了一点工资而转移阵地,从长远看,这点钱根本不算什么,当你对一个行业有那么几年的体会,以后钱根本不是问题。频繁地动荡不是上策,最后你对哪个行业都没有摸透,永远是新手!

    [2]可以做技术,切不可沉湎于技术。千万不可一门心思钻研技术!给自己很大压力,如果你的心思全部放在这上面,那么注定你将成为孔乙己一类的人物!适可而止为之,因为技术只不过是你今后前途的支柱之一,而且还不是最大的支柱,除非你只愿意到老还是个工程师!

    [3]不要去做技术高手,只去做综合素质高手!在企业里混,我们时常瞧不起某人,说他“什么都不懂,凭啥拿那么多钱,凭啥升官!”这是普遍的典型的工程师的迂腐之言。

    很牛吗?人家能上去必然有他的本事,而且是你没有的本事。你想想,老板搞经营那么多年,难道见识不如你这个新兵?人家或许善于管理,善于领会老板意图,善于部门协调等等。因此务必培养自己多方面的能力,包括管理,亲和力,察言观色能力,攻关能力等,要成为综合素质的高手,则前途无量,否则只能躲在角落看示波器!技术以外的技能才是更重要的本事!!从古到今,美国日本,一律如此!

    [4]多交社会三教九流的朋友!不要只和工程师交往,认为有共同语言,其实更重要的是和其他类人物交往,如果你希望有朝一日当老板或高层管理,那么你整日面对的就是这些人。了解他们的经历,思维习惯,爱好,学习他们处理问题的模式,了解社会各个角落的现象和问题,这是以后发展的巨大的本钱,没有这些以后就会笨手笨脚,跌跌撞撞,遇到重重困难,交不少学费,成功的概率大大降低!

    [5]知识涉猎不一定专,但一定要广!多看看其他方面的书,金融,财会,进出口,税务, 法律等等,为以后做一些积累,以后的用处会更大!会少交许多学费!!

    [6]抓住时机向技术管理或市场销售方面的转变!要想有前途就不能一直搞开发,适当时候要转变为管理或销售,前途会更大,以前搞技术也没有白搞,以后还用得着。搞管理可以培养自己的领导能力,搞销售可以培养自己的市场概念和思维,同时为自己以后发展积累庞大的人脉!应该说这才是前途的真正支柱!!!
    [7]逐渐克服自己的心里弱点和性格缺陷!多疑,敏感,天真(贬义,并不可爱),犹豫不决,胆怯,多虑,脸皮太薄,心不够黑,教条式思维。。。这些工程师普遍存在的性格弱点必须改变!很难吗?只在床上想一想当然不可能,去帮朋友守一个月地摊,包准有效果,去实践,而不要只想!不克服这些缺点,一切不可能,甚至连项目经理都当不好--尽管你可能技术不错!
    [8]工作的同时要为以后做准备!建立自己的工作环境!及早为自己配置一个工作环境,装备电脑,示波器(可以买个二手的),仿真器,编程器等,业余可以接点活,一方面接触市场,培养市场感觉,同时也积累资金,更重要的是准备自己的产品,咱搞技术的没有钱,只有技术,技术的代表不是学历和证书,而是产品,拿出象样的产品,就可技术转让或与人合作搞企业!先把东西准备好,等待机会,否则,有了机会也抓不住!

    [9]要学会善于推销自己!不仅要能干,还要能说,能写,善于利用一切机会推销自己,树立自己的品牌形象,很必要!要创造条件让别人了解自己,不然老板怎么知道你能干?外面的投资人怎么相信你?提早把自己推销出去,机会自然会来找你!搞个个人主页是个好注意!!特别是培养自己在行业的名气,有了名气,高薪机会自不在话下,更重要的是有合作的机会...

    [10]该出手时便出手!永远不可能有100%把握!!!条件差不多就要大胆去干,去闯出自己的事业,不要犹豫,不要彷徨,干了不一定成功,但至少为下一次冲击积累了经验,不干永远没出息,而且要干成必然要经历失败。不经历风雨,怎么见彩虹,没有人能随随便便成功。

  • 如何设计编写和设计软件测试用例(转)

    2009-09-06 12:28:46

    一、测试用例软件测试的核心

      软件测试的重要性是毋庸置疑的。但如何以最少的人力、资源投入,在最短的时间内完成测试,发现软件系统的缺陷,保证软件的优良品质,则是软件公司探索和追求的目标。每个软件产品或软件开发项目都需要有一套优秀的测试方案和测试方法。

      影响软件测试的因素很多,例如软件本身的复杂程度、开发人员(包括分析、设计、编程和测试的人员)的素质、测试方法和技术的运用等等。因为有些因素是客观存在的,无法避免。有些因素则是波动的、不稳定的,例如开发队伍是流动的,有经验的走了,新人不断补充进来;一个具体的人工作也受情绪等影响,等等。如何保障软件测试质量的稳定?有了测试用例,无论是谁来测试,参照测试用例实施,都能保障测试的质量。可以把人为因素的影响减少到最小。即便最初的测试用例考虑不周全,随着测试的进行和软件版本更新,也将日趋完善。

      因此测试用例的设计和编制是软件测试活动中最重要的。测试用例是测试工作的指导,是软件测试的必须遵守的准则,更是软件测试质量稳定的根本保障。

      二、什么叫测试用例

      测试用例(Test Case)目前没有经典的定义。比较通常的说法是:指对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略,内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等,并形成文档。

      不同类别的软件,测试用例是不同的。不同于诸如系统、工具、控制、游戏软件,管理软件的用户需求更加不统一,变化更大、更快。笔者主要从事企业管理软件的测试。因此我们的做法是把测试数据和测试脚本从测试用例中划分出来。测试用例更趋于是针对软件产品的功能、业务规则和业务处理所设计的测试方案。对软件的 每个特定功能或运行操作路径的测试构成了一个个测试用例。

      三、编写测试用例

      着重介绍一些编写测试用例的具体做法。

      1、测试用例文档

      编写测试用例文档应有文档模板,须符合内部的规范要求。测试用例文档将受制于测试用例管理软件的约束。

      软件产品或软件开发项目的测试用例一般以该产品的软件模块或子系统为单位,形成一个测试用例文档,但并不是绝对的。

      测试用例文档由简介和测试用例两部分组成。简介部分编制了测试目的、测试范围、定义术语、参考文档、概述等。测试用例部分逐一列示各测试用例。每个具体测试用例都将包括下列详细信息:用例编号、用例名称、测试等级、入口准则、验证步骤、期望结果(含判断标准)、出口准则、注释等。以上内容涵盖了测试用例的 基本元素:测试索引,测试环境,测试输入,测试操作,预期结果,评价标准。

      2、测试用例的设置

      我们早期的测试用例是按功能设置用例。后来引进了路径分析法,按路径设置用例。目前演变为按功能、路径混合模式设置用例。

      3、按功能测试是最简捷的,按用例规约遍历测试每一功能。

      对于复杂操作的程序模块,其各功能的实施是相互影响、紧密相关、环环相扣的,可以演变出数量繁多的变化。没有严密的逻辑分析,产生遗漏是在所难免。路径分析是一个很好的方法,其最大的优点是在于可以避免漏测试。

      为提高测试效率,软件测试已大力发展自动测试。自动测试的中心任务是编写测试脚本。如果说软件工程中软件编程必须有设计规格说明书,那么测试脚本的设计规格说明书就是测试用例。

      4、评估测试结果的度量基准

      完成测试实施后需要对测试结果进行评估,并且编制测试报告。判断软件测试是否完成、衡量测试质量需要一些量化的结果。例:测试覆盖率是多少、测试合格率是多少、重要测试合格率是多少,等等。以前统计基准是软件模块或功能点,显得过于粗糙。采用测试用例作度量基准更加准确、有效。

      5、分析缺陷的标准

      通过收集缺陷,对比测试用例和缺陷数据库,分析确证是漏测还是缺陷复现。漏测反映了测试用例的不完善,应立即补充相应测试用例,最终达到逐步完善软件质量。而已有相应测试用例,则反映实施测试或变更处理存在问题。

      四、相关问题

      1、测试用例的评审

      测试用例是软件测试的准则,但它并不是一经编制完成就成为准则。测试用例在设计编制过程中要组织同级互查。完成编制后应组织专家评审,需获得通过才可以使用。评审委员会可由项目负责人、测试、编程、分析设计等有关人员组成,也可邀请客户代表参加。

      2、测试用例的修改更新

      测试用例在形成文档后也还需要不断完善。主要来自三方面的缘故:第一、在测试过程中发现设计测试用例时考虑不周,需要完善;第二、在软件交付使用后反馈的软件缺陷,而缺陷又是因测试用例存在漏洞造成;第三、软件自身的新增功能以及软件版本的更新,测试用例也必须配套修改更新。

      一般小的修改完善可在原测试用例文档上修改,但文档要有更改记录。软件的版本升级更新,测试用例一般也应随之编制升级更新版本。

      3、测试用例的管理软件

      运用测试用例还需配备测试用例管理软件。它的主要功能有三个:第一、能将测试用例文档的关键内容,如编号、名称等等自动导入管理数据库,形成与测试用例文档完全对应的记录;第二、可供测试实施时及时输入测试情况;第三、最终实现自动生成测试结果文档,包含各测试度量值,测试覆盖表和测试通过或不通过的测试 用例清单列表。

      有了管理软件,测试人员无论是编写每日的测试工作日志、还是出软件测试报告,都会变得轻而易举。
  • 第一次缓冲时间

    2009-08-26 10:32:36

    Time to First Buffer Breakdown(Over Time)――第一次缓冲时间细分(随时间变化)。
    此分析图显示成功收到从Web服务器返回的第一次缓冲之前这段时间内,场景或会话步骤运行的每一秒中每个网页组件的服务器时间和网络时间。
    通过此图可确定场景或会话步骤运行期间服务器或网络出现问题的时间。
    NetWork Time――场景或会话步骤运行的每一秒中每个网页组件的网络时间。
    Server Time ――场景或会话步骤运行的每一秒中每个网页组件的服务器时间。
    =========================================================================

    First buffer是指从发出第一个http请求到收到第一个字节返回的时间。
    它是根据收到ACK的时间来划分成两部份:网络时间+服务器时间。
    网络时间是从发出第一个http请求到收到ACK的时间。(也就是在网络上传送和收回所花的时间)
    服务器时间是从收到ACK到第一个字节返回的时间。(也就是服务器对请求处理的时间)

    first buffer= 服务器处理+网络下载时间
    如果有很多non-html资源,需要检查windows 或者linux 的网卡流量以及中间的路由器、交换间的带宽

    注:ACK是TCP首部中的确认标志,对已接受到的TCP报文进行确认。
    英文缩写: ACK (ACKnowledge Character)
    中文译名: 确认字符
    分  类: 传输与接入
    解  释: 在数据通信传输中,接收站发给发送站的一种传输控制字符。它表示确认发来的数据已经接受无误
  • DOM

    2009-08-18 19:35:32

    HTML 文档中的每个成分都是一个节点。
    DOM 是这样规定的:
       1. 整个文档是一个文档节点
       2. 每个 HTML 标签是一个元素节点
       3. 包含在 HTML 元素中的文本是文本节点
       4. 每一个 HTML 属性是一个属性节点
       5. 注释属于注释节
    举例:<head> 和 <body> 的父节点是 <html> 节点,文本节点 "Hello world!" 的父节点是 <p> 节点。
    <html>
      <head>
        <title>DOM Tutorial</title>
      </head>
      <body>
        <h1>DOM Lesson one</h1>
        <p>Hello world!</p>
      </body>
    </html>

    访问节点:1. 通过使用 getElementById() 和 getElementsByTagName() 方法
             2. 通过使用一个元素节点的 parentNode、firstChild 以及 lastChild 属性
    注释:getElementById() 无法工作在 XML 中


    字节信息
    每个节点都拥有包含着关于节点某些信息的属性。这些属性是:
         
    nodeName(节点名称) 、nodeValue(节点值) 、nodeType(节点类型)
    nodename
    nodeName 属性含有某个节点的名称。
        1. 元素节点的 nodeName 是标签名称
        2. 属性节点的 nodeName 是属性名称
        3. 文本节点的 nodeName 永远是 #text
        4. 文档节点的 nodeName 永远是 #document
    注释:nodeName 所包含的 XML 元素的标签名称永远是大写的
    nodevalue
        对于文本节点,nodeValue 属性包含文本。
        对于属性节点,nodeValue 属性包含属性值。
        nodeValue 属性对于文档节点和元素节点是不可用的。
    nodetype
    nodeType 属性可返回节点的类型。

    最重要的节点类型是:

    元素类型 节点类型
    元素 1
    属性 2
    文本 3
    注释 8
    文档 9

  • 描述性语言

    2009-08-16 17:08:38

    1. 使用Description
       Set bj = Description.Create()
       Obj("name") = "username"
       Browser().Page().WebEdit(Obj).Set ""

    2. 使用正则
       Browser("name:=" & BrowserName & ".*").Page("title:=" & PageName & ".*").WebEdit(Obj).Set "" 

    3. 使用环境变量
       导入xml,注意编码,否则汉字显示乱码
       可以直接在Test Setting 中导入xml文件,也可以通过loadfromfile函数导入
       Environment.LoadFromFile(filepath)
       Browser("name:=" & BrowserName & ".*").Page("title:=" & PageName & ".*").WebEdit(Obj).Set Environment.value("username")

     

  • QTP操作xml文件的方法(转)

    2009-08-12 11:00:05

    目前,企业中对XML的应用越来越广泛,作为自动化测试的测试工程师,也应该掌握XML的读写操作。
      以下我使用XML DOM技术演示一个例子,用以读取XML指定节点的节点内容值。
      读取函数原型 GetXml strXmlPath,nodeName
      这个函数的第一个参数表示xml文件所在路径,第二个参数表示希望获取到的xml节点名,请结合下列例子看
      首先,新建一个vbs文件(取个名字叫readXml.vbs),输入代码:
    Dim strXML

      GetXml "c:search.xml","TestResult"  '这个函数的第一个参数表示xml文件所在路径,第二个参数表示希望获取到的xml节点名,请结合下列例子看
    MsgBox strXML

    Function GetXml (ByVal strXmlFilePath,ByVal xmlNodeName)
            Dim xmlDoc,xmlRoot
           
            Set xmlDoc = CreateObject("Microsoft.XMLDOM") '创建XML DOM对象
            xmlDoc.async = False  '控制加载模式为同步模式(xml树加载完毕后再执行后续代码)
            xmlDoc.load strXmlFilePath        '载入xml文件
            If xmlDoc.parseError.errorCode <> 0 Then
                    MsgBox "XML文件格式不对,原因是:" & Chr(13) &  xmlDoc.parseError.reason
                    Exit Function               
            End If
            Set xmlRoot = xmlDoc.documentElement       
            xmlRecursion xmlRoot,xmlNodeName        '调用xml递归函数传入指定的根和节点名       
            GetXml = True 'xmlRecursion (xmlRoot)
           
    End Function

    Function xmlRecursion(byval xmlNode,byval strNodeName)
            If xmlNode.nodeName = strNodeName And xmlNode.hasChildNodes Then
                    If  xmlNode.childNodes.item(0).nodeName = "#text" Then
                            strXML = strXML & xmlNode.nodeName & ":" & xmlNode.childNodes.item(0).nodeValue & Chr(13)                                               
                    End If               
            End If                       
            If xmlNode.hasChildNodes Then
                    For Each childNodeItem In xmlNode.ChildNodes
                            If childNodeItem.hasChildNodes Then
                                    xmlRecursion childNodeItem,strNodeName                               
                            End If                       
                    Next
            End If       
    End Function
     
    问题:
      haschildnodes()这个方法好奇怪,明明已经没有子节点了,却仍然返回true,
      比如<TestResult>1</TestResult>这个节点,它的childNodes.item(0).nodeName竟然是“#text”,但是根据例子来看TestResult已经没有子节点了阿
    回答:
      因为在xml有一个特殊的“子节点”——文本节点。比如 <TestResult>100</TestResult>
      这个节点TestResult下并不是没有子节点,而是有一个文本节点,这个节点的nodeName就是“#text”,而nodeValue是100.如果是 <TestResult/> 这种节点的话,那么用hasChildNodes则返回False
     
    遍历xml的代码:
    Option Explicit
    Dim xmlDoc,myErr,strXML
    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    xmlDoc.async = False  
    xmlDoc.load "c:calc1.xml"
    If xmlDoc.parseError.errorCode <> 0 Then  
       Set myErr = xmlDoc.parseError
       MsgBox("XML Loads Failed. " & myErr.reason)
    Else
            Set rootNode = xmlDoc.documentElement
            Call rTravel(rootNode)
            MsgBox strXML
    End If

    Sub rTravel (rNode)
            Dim blnTwo,intTestCase,
            blnTwo = False
            iLen = rNode.childNodes.length
            If iLen > 0 Then
                    For i = 0 To rNode.childNodes.length -1
                            Set child = rNode.childNodes.item(i)
                            Call rTravel(child)                       
                            childtext = child.nodeValue                       
                            strXML = strXML & childtext & chr(13)
                    Next
            Else
                    Exit Sub               
            End If
    End Sub


    方法二:
    Option Explicit
    Dim xmlDoc,myErr,strXML

    Set xmlDoc = CreateObject("Microsoft.XMLDOM")
    xmlDoc.async = False  
    xmlDoc.load "c:calc1.xml"
    If xmlDoc.parseError.errorCode <> 0 Then  
       Set myErr = xmlDoc.parseError
       MsgBox("XML Loads Failed. " & myErr.reason)
    Else
            Set rootNode = xmlDoc.documentElement
            Call rTravel(rootNode)
            MsgBox strXML
    End If
    Sub rTravel (rNode)
            Dim blnTwo,intTestCase,
            blnTwo = False
            iLen = rNode.childNodes.length
            If iLen > 0 Then
                    For i = 0 To rNode.childNodes.length -1
                            Set child = rNode.childNodes.item(i)
                            Call rTravel(child)                       
                            childtext = child.nodeValue                       
                            strXML = strXML & childtext & chr(13)
                    Next
            Else
                    Exit Sub               
            End If
    End Sub

  • 自动化测试中如何利用WMI(转)

    2009-08-10 20:56:29

    WMI即Windows 管理规范,是用户管理本地和远程计算机的一种模型。通过它可以访问、配置、管理和监视几乎所有的 Windows 资源。WMI的语法十分简单,基本上常见的命名空间、对象等用几乎一模一样。它对应的是Windows里的WMI服务(winmgmt)

    WMI实际是由两部分组成:CIM库和WMI脚本对象库。在具体使用过程中,我们是通过WMI脚本对象库去访问CIM库,管理托管的资源。也就是说,在我们编写脚本的过程大致可以分为这么几步:

    1)创建WMI对象脚本库的指针实例;

    2)调用其实例的方法,连接到CIM库,并指明需要访问的资源的逻辑位置;

    )获得托管资源也就是类的实例的集合;

    4)枚举实例,完成工作

    WMI的命名空间共有16个,不过我们常用的只有两个:

    1)root\cimv2  在这个命名空间里包括了绝大多数与计算机、操作系统相关联的类。

    2)root\default  管理注册表的类

    给出两个实例参考:

    日志报告中记录测试机器的地址:

    Public Function GetIP()
     '获取测试机器的IP
      ComputerName="."
      Dim objWMIService,colItems,objItem,objAddress
      Set ōbjWMIService = GetObject("winmgmts:\\" & ComputerName & "\root\cimv2")
      Set colItems = objWMIService.ExecQuery("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
      For Each objItem in colItems
         For Each objAddress in objItem.IPAddress
             If objAddress <> "" Then
               GetIP = objAddress
               Exit Function
             End If
         Next
      Next
    End Function

    如何在判断进程是否存在

    Function ProcessExist(processName)
      For each Process in GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_process")
       If Process.Name = processName Then
         ProcessExist = True
         Exit Function 
       End If
     Next
     ProcessExist = False
    End Function

Open Toolbar