使用Loadrunner分别测量服务器响应时间及页面加载时间

上一篇 / 下一篇  2013-08-06 10:10:16 / 个人分类:Loadrunner

  最近想对一网站进行性能测试,我们的初衷是把Server reponse时间和页面渲染时间区分看,这样我们就能判断是server这端的问题,还是网页前端HTML、CSS、JS等解析问题。
  因为性能测试还需要同时测试最大并发用户数及服务器资源使用情况,所以测试工具选择了Loadrunner,但此工具只是能统计服务器响应时间,无法测试页面渲染及加载时间。
  在网上搜索了一些,有一篇帖子是讲如何使用QTP写VBS脚本,然后使用QTP中Tools--Options--Run的"Alow other Mercury products to run tests and components"功能来执行性能测试。这种方法不好的地方在于我们得在机器上同时装QTP 和 Loadrunner, 那么有没有一种办法可以直接使用Loadrunner来写VBS脚本然后直接用Loadrunner跑VBS的脚本呢?
  查看了Loadrunner支持的协议,其中有一项是关于"VB Script. Vuser",使用该协议可以实现相应语言的脚本的编写,那不正好可以满足我的要求么?于是参考帖子“使用QTP统计页面加载时间”开始在Loadrunner中编写VBS脚本。
  以下在原帖子中的代码在Loadrunner中的应用:
在Action模块中编写如下脚本:

Public Function timeCount(url)

  Set dom = CreateObject("InternetExplorer.Application") 'Create an IE object

  Set lr = CreateObject("LoadRunner.LrApi") 'Create LoadRunner object

  dom.Navigate(url) 'Open the specific URL

  time_start = Now() 'To obtain statistics at the beginneing of time

  timer_start = timer() 'Get the current time in milliseconds

  dom.visible = True ' Set IE can be seen

  While dom.busy or (dom.readyState<>4) 'dom.readyState -- Got the IE status; when IE busy or is loading the readyState<>4, got the time duration

   wscript.sleep 1 'Time interval 1 ms, if the relatively long time interval, then is likely to take less than a state value

   Select Case dom.readyState 'To determine the value of dom.readyState

    Case 0  'IE is not initialized

      time0 = Now()

      timer0 = timer()

    Case 1 'Is sending Request

      time1 = Now()

      timer1 = timer()

    Case 2 'Request has been sent to complete

      time2 = Now()

      timer2 = timer()

    Case 3 'Can receive the part of response data

      time_3 = Now() 

      timer_3 = timer()

    Case 4 'Page is loaded

      time4 = Now()

      timer4 = timer()

    End select

   wend

   timeCount = "Statistics Start Time:"&start_time&vbcrlf&"time0:"&time0&vbcrlf&"time1:"&time1&vbcrlf&"time2:"&time2&vbcrlf&"time3():"&time3&vbcrlf&"time4:"&time4&vbcrlf&"To complete the initializtion of IE and send request:"&(timer1-timer_start)&"seconds"&vbcrlf&"To send the completion and acceptance of server-side part of the response data:"&(timer2-timer1)&"seconds"&vbcrlf&"100% to receive and complete the HTML content parsing:"&(timer4-timer2)&"seconds"&vbcrlf& "Total spent:"&(timer4-timer_start)&"seconds"

End Function


Public Function Action()

  SITEURL = "http://www.yourwebsite.com"

  result = timeCount(SITEURL) 'Returns running result

  MsgBox result 'Output to run As a result, the line can be commented out loadrunner ' For debugging, you can comment it out

End Function 


通过执行上述脚本发现如下几个问题:
1. wscript.sleep 1 运行时提示缺少wscript对象,在网上查了一下,原因如下:
wscript对象是windows宿主脚本对象,而且是windows系统默认提供的脚本操作对象,即无须重新创建就可以使用。所以你在vbs,js中可以直接使用wscript(或者wsh)的方法和属性,但这只是说你可以直接使用wscript,不代表wscript属于vbs。
尽管QTP引入了vbs,但由于wscript不属于vbs,所以QTP未引入wscript,使用时自然报错。

很多人提供了解决办法,有的说是没有创建对象的缘故,按要求加了Set WshShell = CreateObject("WScript.Shell")也是不可以的,后来网上有人重新写了WScript供Loadrunner调用:
在 Action 函数前放置 Sleep 过程 Sub Sleep(MSecs) ' loadrunner can't use wscript.sleep directly, the following code is trying to create Wscript. object Set fso = CreateObject("Scripting.FileSystemObject") If Fso.FileExists("sleeper.vbs")=False Then Set bjOutputFile = fso.CreateTextFile("sleeper.vbs", True) objOutputFile.Write "wscript.sleep WScript.Arguments(0)" objOutputFile.Close End If CreateObject("WScript.Shell").Run "sleeper.vbs " & MSecs,1 , True End Sub
将Loadrunner中的 wscript.sleep 1 改为调用 Sleep(1)

2.不支持其它的浏览器,因为页面渲染时间跟浏览器是息息相关的,用vbscript写的脚本目前只支持IE,因为创建只能创建IE对象。

3.上述脚本中只能把时间以Message box的形式显示出来,如果使用Loadrunner测试的话,为了分析结果,我们需要把时间存成事务,更新后的脚本如下:

Sub Sleep(MSecs) ' loadrunner can't use wscript.sleep directly, the following code is trying to create Wscript. object

    Set fso = CreateObject("Scripting.FileSystemObject")

    If Fso.FileExists("sleeper.vbs")=False Then

       Set bjOutputFile = fso.CreateTextFile("sleeper.vbs", True)

       objOutputFile.Write "wscript.sleep WScript.Arguments(0)"

       objOutputFile.Close

    End If

    CreateObject("WScript.Shell").Run "sleeper.vbs " & MSecs,1 , True

End Sub

Public Function timeCount(url)

  Set dom = CreateObject("InternetExplorer.Application") 'Create an IE object

  Set lr = CreateObject("LoadRunner.LrApi") 'Create LoadRunner object

  dom.Navigate(url) 'Open the specific URL

  time_start = Now() 'To obtain statistics at the beginneing of time

  timer_start = timer() 'Get the current time in milliseconds

  dom.visible = True ' Set IE can be seen

  While dom.busy or (dom.readyState<>4) 'dom.readyState -- Got the IE status; when IE busy or is loading the readyState<>4, got the time duration

   Sleep(1) 'Time interval 1 ms, if the relatively long time interval, then is likely to take less than a state value

   Select Case dom.readyState 'To determine the value of dom.readyState

    Case 0  'IE is not initialized

      time0 = Now()

      timer0 = timer()

    Case 1 'Is sending Request

      time1 = Now()

      timer1 = timer()

    Case 2 'Request has been sent to complete

      time2 = Now()

      timer2 = timer()

    Case 3 'Can receive the part of response data

      time_3 = Now() 

      timer_3 = timer()

    Case 4 'Page is loaded

      time4 = Now()

      timer4 = timer()

    End select

   wend

   server_response_transaction_timer = timer2 - timer1 ' Get the server

   page_render_transaction_timer = timer4-timer_2

   total_timer = timer4 - timer_start

   lr.log_message "The server response time is " + lr.eval_string(server_response_transaction_timer)

   lr.log_message "The page render time is " + lr.eval_string(page_render_transaction_timer)

   lr.log_message "Total page load time is " + lr.eval_string(total_timer)

   lr.set_transaction "server_response_time", server_response_transaction_timer, lr.PASS

   lr.set_transaction "page_render_time", page_render_transaction_timer, lr.PASS

   lr.set_transaction "total_page_load_time", total_timer, lr.PASS

 

Public Function Action()

  SITEURL = "http://www.yourwebsite.com"

  result = timeCount(SITEURL) 'Returns running result

  'MsgBox result 'Output to run As a result, the line can be commented out loadrunner 

End Function


4.测试更新后脚本发现dom.readystate=2总是捕获不到,导致不能计算出事务时间,经过Debug发现,dom.readystate=2确实没有捕获到,但dom.readystate=3到是有很多次的时间捕获,后来想到当dom.readystate状态从2变化到3时,也可以认为服务器已经返回了响应,直接把readystate变成3的第一个时间值当做服务器返回响应的最后时间就可以,再次更新代码
Sub Sleep(MSecs) ' loadrunner can't use wscript.sleep directly, the following code is trying to create Wscript. object

    Set fso = CreateObject("Scripting.FileSystemObject")

    If Fso.FileExists("sleeper.vbs")=False Then

       Set bjOutputFile = fso.CreateTextFile("sleeper.vbs", True)

       objOutputFile.Write "wscript.sleep WScript.Arguments(0)"

       objOutputFile.Close

    End If

    CreateObject("WScript.Shell").Run "sleeper.vbs " & MSecs,1 , True

End Sub

 

Public Function timeCount(url)

  Dim i

  i = 0

  Dim time_3(100)

  Dim timer_3(100)

  Set dom = CreateObject("InternetExplorer.Application") 'Create an IE object

  Set lr = CreateObject("LoadRunner.LrApi") 'Create LoadRunner object

  dom.Navigate(url) 'Open the specific URL

  time_start = Now() 'To obtain statistics at the beginneing of time

  timer_start = timer() 'Get the current time in milliseconds

  dom.visible = True ' Set IE can be seen

  While dom.busy or (dom.readyState<>4) 'dom.readyState -- Got the IE status; when IE busy or is loading the readyState<>4, got the time duration

   Sleep(1) 'Time interval 1 ms, if the relatively long time interval, then is likely to take less than a state value

   lr.log_message "The readyState is " + lr.eval_string(dom.readyState) ' For debugging, you can comment it out before running

   Select Case dom.readyState 'To determine the value of dom.readyState

    Case 0  'IE is not initialized

      time0 = Now()

      timer0 = timer()

    Case 1 'Is sending Request

      time1 = Now()

      timer1 = timer()

    Case 2 'Request has been sent to complete

      time2 = Now()

      timer2 = timer()

   Case 3 'Can receive the part of response data

      time_3(i) = Now() ' When dom.readystate is changed from 2 to 3, it means server has returned the response data, so the first value of Now() and Timer() stands for the server response time.

      timer_3(i) = timer()

      lr.log_message "when dom.readystate = 3 "& cstr(i) + " " + lr.eval_string(time_3(i)) ' For debugging, you can comment it out before running

      i = i+1 ' Because dom.reaystate = 3 may keep in a while

    Case 4 'Page is loaded

      time4 = Now()

      timer4 = timer()

      lr.log_message "4 start at " + lr.eval_string(time4) ' For debugging, you can comment it out before running

    End select

   server_response_transaction_timer = timer_3(0) - timer1 ' Get the server

   page_render_transaction_timer = timer4-timer_3(0)

   total_timer = timer4 - timer_start

   lr.log_message "The server response time is " + lr.eval_string(server_response_transaction_timer)

   lr.log_message "The page render time is " + lr.eval_string(page_render_transaction_timer)

   lr.log_message "Total page load time is " + lr.eval_string(total_timer)

   lr.set_transaction "server_response_time", server_response_transaction_timer, lr.PASS

   lr.set_transaction "page_render_time", page_render_transaction_timer, lr.PASS

   lr.set_transaction "total_page_load_time", total_timer, lr.PASS

End Function


Public Function Action()

  SITEURL = "http://www.yourwebsite.com"

  result = timeCount(SITEURL) 'Returns running result

  'MsgBox result 'Output to run As a result, the line can be commented out loadrunner 

End Function


5.还有一个问题就是当脚本执行完毕后,发现IE无法关闭,虽然表面上看似已经关闭了,其实进程还在运行,当批量进行执行脚本时,导致机子运行缓慢,解决方法是在vusr_end中将IE进程关闭
Public Function Terminate() 

   Set ws=CreateObject("wscript.shell")

   ws.run "cmd /c taskkill /f /im iexplore.exe",0 

End Function


6.刚才测试的时候发现一个问题,如果在vusr_end中结束IE进程,在controller中跑的时候,有可能会导致正在运行中的其它并发用户正在使用的浏览器关闭,所以我们还不能使用上述的方法,暂时想到的办法是使用dom.quit 放置在timeCount函数最后。
  然后写一个批处理程序来运行controller,等所有的脚本运行完成后关闭ie进程,目前只是一个想法,后续实践后再分享。
哈哈,至此使用Loadrunner测试页面加载时间的目的已经达到

TAG:

 

评分:0

我来说两句

Open Toolbar