性能测试-Loadrunner、Jmeter 性能测试概念详解+性能方案+代码录制(待完善)

Loadrunner和Jmeter:

  1. Loadrunner,社区版本,一台机器最多能开50个并发。四台机器就是200个,四台机器分别手动设置LR运行参数,执行完后分别统计运行结果再汇总到一起。收费版本收费非常贵,按照不同协议,并发数来收费。
  2. Jmeter,开源,支持编程,但是不然Loadrunner支持的彻底。是轻量的,百八十兆,在mac下装java环境就可以做性能测试。

性能测试:

  1. 性能测试:在不同负载情况下,查看被测试系统的表现。
  2. 前端性能:app性能(GT、Emmagee)。
  3. 后端性能:接口和服务。

性能指标:

  1. TPS 和平局响应时间:并发多少?多快?正确?这三种情况下占用了多少资源。

性能测试的全流程:

  1. 1

性能测试的最大原则:

  1. 模拟最可能发生的最极端并发访问的情况。

Loadrunner工具三个部分:

  1. virtualuser generator:虚拟用户生成器:录制脚本、调试脚本、单线运行。
  2. controller:设定性能测试场景,来运行多线程(多进程)并发,执行并发测试。
  3. analysys:分析性能测试执行后的结果,可以出图表报告。
  4. 补充:ipspoofer:ip欺骗,把所有内网IP做遍历,一般内网是有几百个IP,LR跑的话一般一分钟左右就跑完了,没啥意义,所以为了测试大量IP,需要开发把限制IP关掉再做测试性能。但是这种情况就和真实情况不相符了,要综合考虑。

概念详解:

  1. 开始-HP Software-Start HP Web tours Server,相当于启动服务,然后打开http://127.0.0.1:1080/WebTours/index.htm 工具自带的网站,打开网页点击administration,在做关联的时候需要选择第三个Set LOGIN form's action tag to an error page.
  2. 关联:把动态的数据放到变量中,会在后续的测试中使用。比如登录了之后,系统返回一个token(串),访问所有后续的页面会带有这个token。录制的脚本拿到token,但是都是之前历史值,在性能测试时并不能复用,所以需要做关联。
  3. 参数化:避免大量的请求被缓存命中。

创建录制脚本:

  1. 启动virtualuser generator,File-new Script and solution-WebHttpHtml,创建在了C:\Users\太阳\Documents\VuGen\Scripts路径下的录制脚本文件。
  2. 脚本的结构:
    1. vuser_init:函数,
      在一个线程中最多执行1次
      一个用于数据准备等操作,在action前执行
    2. action:函数,在一个线程中可以执行1-多次
    3. vuser_end:函数在一个线程中最多执行1次
      一个用于数据清理等操作
      在action后执行。
  3. 点击录制图标录制,选择浏览器、录制模式、录制网址
  4. 在网页中执行注册的操作,同时LR就开始自动录制了,注册结束后点击结束按钮,LR生成录制的脚本,打开action后就可以看到:对应其他收集用户信息的脚本可以删掉。以下是重点脚本解析,
    1.     web_url("index.htm",  //请求的名字
              "URL=http://127.0.0.1:1080/WebTours/index.htm", //请求的网址
              "Resource=0", //是否是资源,0不是资源是网页,1是资源:文件、图片、js、css
              "RecContentType=text/html", //contentType,请求类型是网页类型
              "Referer=", //请求这个网页的时候是从哪个网址访问来的信息
              "Snapshot=t2.inf", //截图文件名字
              "Mode=HTML", //录制模式HTML,还有种模式是URL,如果有ajax、flash等必须使用url。url会把所有的http请求都录下来
              EXTRARES, //下面全是资源文件,"Url=http://www.duba.com/hotwords.json", "Referer=", ENDITEM,这些都是静态的资源文件,如果只想测试动态的数据,则可以把下面这行删除,如果动态和静态都想测试则不需要清空
              "Url=http://www.duba.com/hotwords.json", "Referer=", ENDITEM, 
              LAST);
    2.     web_submit_data("login.pl_2", 
              "Action=http://127.0.0.1:1080/cgi-bin/login.pl", //数据提交后的处理网址
              "Method=POST", //HTTP协议的类型
              "RecContentType=text/html", //提交的资源类型,contenttype
              "Referer=http://127.0.0.1:1080/cgi-bin/login.pl?username=&password=&getInfo=true", //从哪个网址跳转过来的
              "Snapshot=t12.inf", 
              "Mode=HTML", 
              ITEMDATA, //这个下面的这些也可以手动写入,通过抓包获得相关信息
              "Name=username", "Value=changjinling", ENDITEM, 
              "Name=password", "Value={PasswordParameter}", ENDITEM, 
              "Name=passwordConfirm", "Value=123456", ENDITEM, 
              "Name=firstName", "Value=chang", ENDITEM, 
              "Name=lastName", "Value=jinling", ENDITEM, 
              "Name=address1", "Value=beijing", ENDITEM, 
              "Name=address2", "Value=tongzhou", ENDITEM, 
              "Name=register.x", "Value=60", ENDITEM, //UI页面上没看到的字段,是隐含字段,基于安全考虑,比如多长时间之内提交是有效的。
              "Name=register.y", "Value=9", ENDITEM, //是隐含字段
              LAST);
    3. 注册全部脚本:Action()
      {

          web_add_auto_header("DNT", 
              "1");

          web_url("index.htm",    //请求的名字
              "URL=http://127.0.0.1:1080/WebTours/index.htm",  //请求的网址
              "Resource=0",     //是否是资源?0,不是资源,是个网页,1:是资源:文件:图片、js、css..
              "RecContentType=text/html",   //contentType:请求类型:网页类型
              "Referer=",                  //从哪个网址访问来的信息
              "Snapshot=t1.inf",           //截图文件的名字
              "Mode=HTML",                 //录制的模式:html,   url。如果有ajax\flash\:必须使用url:会把所有的http请求录制下来。
              EXTRARES,                   //资源文件
              "Url=../favicon.ico", "Referer=", ENDITEM, 
              "Url=http://s.pc.qq.com/navigate/adc/adc_loader.js?v=20160326171611", ENDITEM, 
              "Url=http://s.pc.qq.com/navigate/adc/v4/engine_loader_v3.js", ENDITEM, 
              "Url=http://s.pc.qq.com/navigate/adc/jquery.min.js?ver=3", ENDITEM, 
              "Url=http://s.pc.qq.com/navigate/adc/velocity.js", ENDITEM, 
              LAST);

          web_set_sockets_option("SSL_VERSION", "2&3");



          web_url("login.pl", 
              "URL=http://127.0.0.1:1080/WebTours/login.pl?username=&password=&getInfo=true", 
              "Resource=0", 
              "RecContentType=text/html", 
              "Referer=http://127.0.0.1:1080/WebTours/home.html", 
              "Snapshot=t3.inf", 
              "Mode=HTML", 
              LAST);

          web_add_cookie("SRCHD=AF=NOFORM; DOMAIN=iecvlist.microsoft.com");

          web_add_cookie("SRCHUID=V=2&GUID=213C7604B2E646778D68C0E2C5F9563A&dmnchg=1; DOMAIN=iecvlist.microsoft.com");

          web_add_cookie("SRCHUSR=DOB=20190119; DOMAIN=iecvlist.microsoft.com");

          web_add_cookie("MC1=GUID=1cc40e7eeb084d58a1a4aab5a0176a31&HASH=1cc4&LV=201903&V=4&LU=1553846123710; DOMAIN=iecvlist.microsoft.com");

          web_add_cookie("MUID=30550888172C666B26C505A6132C607F; DOMAIN=iecvlist.microsoft.com");

          web_add_auto_header("UA-CPU", 
              "AMD64");

          

          web_revert_auto_header("UA-CPU");

          web_submit_data("login.pl_2", 
              "Action=http://127.0.0.1:1080/WebTours/login.pl",    //数据提交后的处理网址
              "Method=POST",      //http协议的类型
              "RecContentType=text/html",   //资源类型,contenttype
              "Referer=http://127.0.0.1:1080/WebTours/login.pl?username=&password=&getInfo=true", 
              "Snapshot=t6.inf", 
              "Mode=HTML", 
              ITEMDATA, 
              "Name=username", "Value=tianchuan", ENDITEM, 
              "Name=password", "Value=tianchuan", ENDITEM, 
              "Name=passwordConfirm", "Value=tianchuan", ENDITEM, 
              "Name=firstName", "Value=tianchuan", ENDITEM, 
              "Name=lastName", "Value=tianchuan", ENDITEM, 
              "Name=address1", "Value=tianchuan", ENDITEM, 
              "Name=address2", "Value=tianchuan", ENDITEM, 
              "Name=register.x", "Value=57", ENDITEM, 
              "Name=register.y", "Value=13", ENDITEM, 
              LAST);

          return 0;
      }
    4. 通过脚本回放的话,一个用户名密码重复注册是不会成功的,虽然http返回了200,但是实际上注册是没有成功的,即业务上是没有成功的。在web_submit_data("login.pl_2", 前要加一行断言代码,如果注册成功了则不保存,否则报错    //断言放到请求的前面,如果成功了则页面会有Thank you这样的字样
          web_reg_find("text=Thank you,",LAST)。如果注册成功则在执行log中可以看到提示:Action.c(220): Registered web_reg_find successful for "Text=Thank you," (count=1)      [MsgId: MMSG-26364]。如果注册失败则在执行log中可以看到提示:Action.c(220): Error -26366: "Text=Thank you," not found for web_reg_find      [MsgId: MERR-26366]。
    5. 参数化,用户名可以用随机数做,也可以用文件,将数字部分做随机数,右击2,参考如图
      1. 想看到脚本执行的参数是多少,可以设置以下,再执行,就可以在log中看到参数的实际的值了。  Action.c(220): Notify: Parameter Substitution: parameter "randomnumber" =  "76064"
        Action.c(220): Notify: Parameter Substitution: parameter "PasswordParameter" =  "123456"
      2. 想看到执行时网页的操作页面,通过设置Tools-options-Scripting-replay-show run-time viewer during replay。
      3. 通过文件做参数化如图设置,这里要注意以下Select next row的内容的选择,如果选择了Unique,小截图中的参数才能可用可选,具体含义如下:
      4. 设置action一共跑几次可用通过
      5. 如果想要分析问题,想得到更多的log,可以在log中选中,然后回放的时候就可以在日志中看到更多的服务返回的信息。
    6. 录登录的脚本。
    7. 自动关联,必须有两个页面有相同的内容才能关联,在Design-Design Studio中选中后点击Correlation。这样在脚本中就会自动添加如下代码:                                                                                                               /*Correlation comment - Do not change!  Original value='126029.393681652zticzDzpQDHfDiiQfpicVzcf' Name ='userSession' Type ='ResponseBased'*/
          web_reg_save_param_regexp(
              "ParamName=userSession",
              "RegExp=name=\"userSession\"\\ value=\"(.*?)\"/>\\\n<table\\ border",
              SEARCH_FILTERS,
              "Scope=Body",
              "IgnoreRedirections=No",
              "RequestUrl=*/nav.pl*",
              LAST);    这样的话,原脚本就会被自动的将userSession的值变为关联后                       web_submit_data("login.pl",
              "Action=http://127.0.0.1:1080/cgi-bin/login.pl",
              "Method=POST",
              "RecContentType=text/html",
              "Referer=http://127.0.0.1:1080/cgi-bin/nav.pl?in=home",
              "Snapshot=t33.inf",
              "Mode=HTML",
              ITEMDATA,
              "Name=userSession", "Value={userSession}", ENDITEM,
              "Name=username", "Value=changjinling", ENDITEM,
              "Name=password", "Value={PasswordParameter}", ENDITEM,
              "Name=JSFormSubmit", "Value=off", ENDITEM,
              "Name=login.x", "Value=32", ENDITEM,
              "Name=login.y", "Value=9", ENDITEM,
              LAST);
    8. 手动关联,假如只有一个页面想要做关联,首先需要在源码中找到需要关联的内容的左右边界,
    9. Runtime Settings菜单介绍。
    10. 接口测试的写法                                                                                                                                                    Action()
      {

          lr_rendezvous("hi");
          

          web_reg_find("Text={\"code\": \"00\", \"userid\": ",
              LAST);

          
          web_rest("POST: http://39.106.41.11:8080/register/",
              "URL=http://39.106.41.11:8080/register/",
              "Method=POST",
              //"EncType=raw",
              //"Snapshot=t854649.inf",
              "Body={\"username\":\"wxh22{usenum}\",\"password\":\"12345678abc\",\"email\":\"[email protected]\"}",
              LAST);
          
          

          return 0;
      },目前这个接口只要code返回00就是业务上注册成功了。
      1. 延伸:注册后需要登录,登录后返回值有token,需要将token取出来存到变量里,在后面的接口请求都可以用这个token作为请求参数去发送请求。
  5. Controller
    1. 启动Controller,有手动模式和目标模式两种方式,
    2. TPS拐点
    3. 如果想分析结果,最好可以通过对服务器端日志中得到更加具体的数据请求的时间等。
    4. 接口的响应时间,一百毫秒以上就是比较慢的了,一百毫秒以下就是不错的。
  6. Analysis
    1. 图示分析,在Average Transaction Response Time图标中右击选择Show Transaction Breakdown Tree,如图示:
  7. 网络流程:通过dns-找到ip-建立连接-发送请求-等待服务器处理-接收服务器返回数据-断开连接,first buffer time:等待服务器处理+返回数据的第一个字节在网上的传输时间。

猜你喜欢

转载自blog.csdn.net/chang_jinling/article/details/89428668