jmeter接口测试 day11

一、复习:
设置JMeter默认打开语言风格:
修改jmeter.properties文件  属性文件、配置文件 名值对
    供JMeter在启动时,作为初始化配置使用
#language=en 默认英文版en  改为简体中文zh_CN
language=zh_CN
重启jmeter

1、接口测试的前提:
1)需求文档(功能需求、性能需求) 客户、需求分析师
    是后续设计、开发、测试、实施的依据
2)接口文档(API文档、开发文档)
 由开发方的系统设计人员编写的,作为后续开发的重要依据,也作为测试的依据;
 如果没有接口文档? 分析协议 HTTP   简单的、无状态的
    如果有UI界面,可以使用Fiddler就行抓包,获取核心功能、动作的数据报文(请求包、应答包),从请求的头部header获得URL、请求方式get/post、URL后携带的参数(Query String 查询字符串  ?参数名=参数值&...)、支持的编码类型 Accept-Encoding: gzip, deflate、内容类型Content-Type、是否携带Cookie信息(客户端保存用户状态信息的技术);  从请求的主体body获取post方式携带的参数(参数名=参数值&... 或者是JSON文本提交给服务器);
    从响应中获取服务器接口的返回信息:从响应头部header获取HTTP响应码(2xx 3xx 4xx 5xx)、响应内容类型Content-Type、是否让客户端保存Cookie(Set-Cookie: 名=值;xxx=xxx); 从响应的主体body获取响应文本内容,比如JSON、XML、HTML、JS、CSS、JPG、mp4等;接口测试时,可以将返回的JSON结果进行改写,作为新业务的检查依据(数据格式一样,数据内容不同);
    作为接口测试,主要是对某些核心功能发送请求,一般结果以JSON或XML格式为主,表示返回重要结果数据,作为前端、下一步显示、判断的重要依据;
    如果既没有接口文档、界面也未实现,如何测试接口?需要和开发方获取重要的协议信息,尤其是接口文档;

二、JMeter核心技术  
1、什么是JMeter?
 JMeter是由Apache基金会组织提供的开源、免费的、轻量化的、Java技术开发的一款接口测试工具、性能测试工具;
 作为客户端通过大量网络协议向服务器发请求,可以测试目前业内主流的接口;由于能够模拟大量虚拟用户VU(Java多线程Thread技术实现),可以发起压力测试,可用测试系统的性能;
 Java程序需要JVM Java虚拟机执行,JVM是一个进程 Process
 如果后续要启动多任务,一定是Java的多线程技术  Thread  节省系统资源(轻量化)
 计算机资源分配技巧:一般在一个进程中开启多个线程,而不是通过启动多个进程来模拟多任务。

快速提高技能的思路:多分析、思考测试工具、框架为何如此设计?

2、安装和使用JMeter
1)安装JDK:目前JDK1.6或1.8     Java开发工具包
                              (高版本JMeter 比如5.3要求1.8以上)
   含有JVM Java虚拟机 程序,执行Java程序
设置系统环境变量:
JAVA_HOME  JDK的安装目录
          建议从实际JDK路径名拷贝,
          比如:C:\Program Files (x86)\Java\jdk1.6.0
Path            命令的搜索路径
          %JAVA_HOME%\bin;原有配置内容...
检查:cmd
set java_home
set path
java -version

2)安装JMeter:解压即可 apache-jmeter-2.12.zip
目录结构:
<1> bin目录:常用命令
 jmeter.bat  给Windows使用 批处理
 jmeter.sh   给Linux使用 shell脚本   Java跨平台
<2> lib目录:第三方类库   jar包
 比如需要数据库驱动程序,将jar包放入lib中;
 mysql.jar

启动:运行jmeter.bat  出现界面,关键:测试计划
原理:可以将一次测试计划配置到界面中(更直观);
   保存后,是jmx文件,就是xml风格(便于存储复杂信息)
XML文件的第一行声明:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan ...>   根标记:JMeter的测试计划
   嵌套添加其他节点,配置计划中的内容
</jmeterTestPlan>

面试题:系统、产品中常见的配置文件有哪些格式?  触类旁通
  jmeter.properties   属性文件  特点:大量的名值对  注释#开头
                       #配置端口号
                       #name=Tom
                       port=8000
                       name=测试计划
  xxx.json    JSON文件    {"名称": 值, ...}
  server.xml   XML文件   大量标签、属性存储信息
                      比如:修改过Tomcat的默认端口号为8880
         .jmx   也是XML风格

3、面试题:JMeter的一个测试计划中有哪些要素?  先整体,后局部
1)根节点:测试计划   是其他节点的“容器”
配置内容:
 用户定义的变量:配置计划中全局变量
    名称和值        后续使用:${变量名}  区别{LR变量名}
    name  Tom         ${name}  获取值Tom
  独立运行每个线程组:一般不选
    如果选中,多线程组会串行执行,测试性能时不够真实;
    一般测性能时,多请求分别发送执行(并发)
    如果需要顺序执行,则选中;
  Add directory or jar to classpath: 类路径中添加jar包
    比如访问数据库,需要数据库驱动程序 mysql.jar
    添加第三方类库;(工具lib目录下也可)

2)测试计划下,添加1个或多个线程组:Thread Group 
线程组可以配置1个或多个线程,模拟1个或多个用户;
测试功能时:1个VU   调试时,先使用1VU运行,分析执行轨迹,再转多VU
测试性能时:多个VU  发起更大的压力

在取样器错误后要执行动作:
  一般选继续、有时可停止线程
线程数:1   模拟1个虚拟用户VU
Ramp-UP Period(in seconds): 1  用户准备时间
           1个VU在1秒内做好准备(运行前初始化)
循环次数:默认1
调度器:一般不选择,正常执行完
若选中,出现调度器配置: 类似LR中的Duration持续时间
 A.启动时间:2020/07/11 17:00:00
 B.结束时间:2020/07/11 17:01:00     前两个为基础
 C.持续时间(秒):180秒   优先3分钟  后两个调整   00~03
 D.启动延迟(秒):120秒   延迟2分钟启动           02~05

3)线程组下,添加取样器Sampler: 常用协议的请求
目前:Http请求  按照接口文档、测试用例要求设置细节
名称:通用酒店数据-HTTP-GET-001
注释:基于HTTP协议,以GET方法,使用有效关键词kw发送请求,查看是否返回正确的JSON结果
服务器名称或IP:api01.idataapi.cn
端口号:8000
协议:HTTP
方法:GET
路径:/hotel/idataapi
   第1个/代表Web应用程序的根目录
   从端口号后算起
接口文档的URL参考:
http://api01.idataapi.cn:8000/hotel/idataapi
协议    域名              端口  应用资源路径

同请求一起发送的参数:添加
  kw:  广州
  apikey:  xxxxxx

4)测试计划下或线程组下,添加“监听器” Listener (观察者模式)
  不同位置添加作用域不同,在测试计划下添加,是对整个计划下内容进行监控;线程组下添加,只对当前组内监控;
<1> 察看结果树:和功能查看有关  请求包、响应包的关系         
 类似于LR的Tree树视图(HTML View网页效果,HTTP View协议数据包)、Fiddler的监控面板--审查  Raw选项卡
 查看视图:Text   普通文本
             HTML  网页页面效果  更直观
             JSON  JSON格式化后效果
<2> 图形结果:查看性能变化趋势
<3> 用表格察看结果:查看性能结果明细
<4> 聚合报告:查看性能结果统计

和Postman对比:
   Postman的一个用例集,类似于JMeter中的一个测试计划,计划下可以创建1个或多个线程组,组中管理1个或多个请求;一条用例可以由1条请求或按照顺序执行的请求(顺序流)形成;

练习:对天气预报接口进行测试,使用GET方式
          访问接口地址 语法 异常  非法  字符 
java.net.URISyntaxException: Illegal character in authority at index 7: http://apis.juhe.cn :8000/simpleWeather/query?

                            Http主机连接  异常
org.apache.http.conn.HttpHostConnectException: Connection to http://apis.juhe.cn:8000 refused  被拒绝

练习:对中文分词接口进行一次测试,使用POST方式
api01.idataapi.cn
8000
HTTP
POST
/nlp/segment/bitspaceman
http://api01.idataapi.cn:8000/nlp/segment/bitspaceman
参数:
 text
 apikey   此处不妥!属于Post方式 请求主体中携带

{"message":"No API key found in headers or querystring"}
问题1:请求头部、查询字符串中未找到apikey
解决:在路径名后添加QueryString
/nlp/segment/bitspaceman?apikey=xxx

设计思路:开发者设计程序时,经常为程序出现的错误设计一些类,表示程序的异常XxxException、错误XxxError,在程序运行程序出现问题时抛出(throw),提示给开发者、测试者,及时发现问题;同时建议打开调试日志,便于查看结果。

问题2:java.util.zip.ZipException: Not in GZIP format
                    Zip异常   不是GZIP格式
原因:请求的头部信息不够完整,没有说明使用什么格式提交;--分析协议的数据包
解决:在线程组下添加“配置元件” -> HTTP信息头管理器
 添加:名称                    值
      Accept-Encoding        gzip,defalte
     是浏览器发给服务器,声明浏览器支持的编码类型

其他问题:
 URISyntaxException: Illegal character in query at index 84...
 请求路径 语法 异常    非法    字符     在            下标位置

4、如何添加检查点?  也称为“断言” Accert  给出预期结果,对比实际结果
目的:自动化执行过程中,对结果进行检查,确保业务准确
LR:
1)找到相应请求:请求后的响应结果需要检查
   先发送该请求,会返回响应结果,结果中文本需要检查
             因                  果
技巧:使用Tree视图 HTML View(页面视图)
     找到响应快照 和 请求的对应关系
2)在相应请求之前写检查点函数:(通过关键右键生成)
     reg注册性函数  要求写在相应请求之前
web_reg_find("Text=响应包需要检查的文本", LAST);

JMeter:
1)找到相应请求:导致其响应结果需要检查的那个请求
目前:就是自己编写的某请求,结果返回json等需要检查
其他:如果发请求,返回HTML网页,
   结合监听器--察看结果树  HTML视图查看
         网页效果和请求的关系  类似:LR的Tree视图(HTML视图 网页效果)
2)在相应请求下,添加“断言” -> 响应断言
1.要测试的响应字段:响应文本
2.模式匹配规则:包括
3.要测试的模式:北京
 就是要检查的文本,注意:必须写响应包的源代码文本(协议数据包文本)
3)在测试计划或线程组下,添加“监听器”->断言结果
响应断言 : Test failed: text expected to contain /呵呵/
         代表结果无法查到文本

添加1:检查响应码为200
名称:响应断言-HTTP响应码
注释:对HTTP响应码进行检查
测试字段:响应头   HTTP响应码在响应的头部信息中
模式匹配规则:包括
测试模式:200
  就是需要检查的文本,点击添加

添加2:检查响应文本中含有:城市名称  比如北京
名称:响应断言-响应文本
注释:检查响应文本中含有:城市名称
测试字段:响应文本    就是响应主体文本内容
模式匹配规则:包括
测试模式:北京


练习:针对天气预报接口发送一条无效数据请求,并添加检查点(响应码、响应文本);
在线程组下新建:
请求名称:根据城市查询天气-HTTP-GET-002
描述:基于HTTP协议,以GET方法,使用无效的城市名查询天气,查看是否返回含有提示信息的JSON文本;
HTTP
apis.juhe.cn
GET
/simpleWeather/query
参数:
  city   火星
  key   ${key}

http://apis.juhe.cn/simpleWeather/query?city=火星&key=xxxx

{"reason":"暂不支持该城市","result":null,"error_code":207301}

技巧:可以将HTTP响应码断言 拖拽到“线程组”下,能够对线程组下所有的请求负责,都要检查响应码为200;(共享方式)
    在002请求下,再添加响应断言,对响应文本检查,要求含有:207301

名称:响应断言-响应文本
注释:检查响应文本含有:207301
测试字段:响应文本
模式匹配规则:包括
测试模式:207301


{"message":"API rate limit exceeded 并发已达上限","retcode":"100703"}
HTTP响应码:429   太多的请求 Too many requests!

技巧:让请求之间适当保留一些间隔时间!
  比如Postman的批量执行,设置Delay 请求的延迟时间

越是大家都有的,越重要!

练习:使用JMeter对手机号码归属地接口进行测试。
1、设计、编写用例
前提:需求、接口文档   来源:juhe
功能介绍 / Introduction
根据手机号码或手机号码的前7位,查询手机号码归属地信息,如省份 、城市、运营商等。

手机号格式:一共11位  344结构
               前7位就能够确定 哪个运营商、哪个地区
       138-1181-0099
    运营商-归属地-不同用户区分
  三大:
   中国移动 北京
   中国电信
   中国联通    

搜索:常见运营商和号段
中国电信号段:

133、149、153、173、177、180、181、189、199


中国联通号段:

130、131、132、145、155、156、166、171、175、176、185、186、166


中国移动号段:

134(0-8)、135、136、137、138、139、147、150、151、152、157、158、159、172、178、182、183、184、187、188、198 

接口地址:http://apis.juhe.cn/mobile/get
返回格式:json/xml
请求方式:get
请求示例:http://apis.juhe.cn/mobile/get?phone=13429667914&key=您申请的KEY

请求参数说明:
名称    必填    类型    说明
phone    是    int    需要查询的手机号码或手机号码前7位
key    是    string    在个人中心->我的数据,接口名称上方查看
dtype    否    string    返回数据的格式,xml或json,默认json

返回JSON结果:
{
"resultcode":"200",
"reason":"Return Successd!",
"result":{
    "province":"浙江",
    "city":"杭州",
    "areacode":"0571",
    "zip":"310000",
    "company":"中国移动",
    "card":""
}
}

2、编写用例
1)手机归属地查询-HTTP-GET-001
描述:基于HTTP协议,以GET方法,使用11位有效的手机号查询归属地,返回JSON格式的结果;

2)手机归属地查询-HTTP-GET-002
描述:基于HTTP协议,以GET方法,使用7位有效的手机号查询归属地,返回XML格式的结果;

3)手机归属地查询-HTTP-GET-003
描述:基于HTTP协议,以GET方法,使用无效的手机号(为空)查询归属地,返回JSON格式的结果;
比如:不填(长度为0的字符串) 
预期结果:响应码200
            响应文本含有:201101  手机号码不能为空
实际结果:
{
    "result": null,
    "reason": "The phone number can not be empty!",
    "error_code": 201101,
    "resultcode": "201"
}

4)手机归属地查询-HTTP-GET-004
描述:基于HTTP协议,以GET方法,使用无效的手机号(位数不够)查询归属地,返回JSON格式的结果;
比如:138118     6位,不够7位
预期结果:响应码200
            响应文本含有:201102   错误的手机号码
实际结果:
{
    "result": null,
    "reason": "Wrong phone number!",
    "error_code": 201102,
    "resultcode": "202"
}

5)手机归属地查询-HTTP-GET-005
描述:基于HTTP协议,以GET方法,使用无效的手机号(错误的)查询归属地,返回JSON格式的结果;
比如:8110081     7位,但无效
预期结果:响应码200
            响应文本含有:201103   查询无结果
实际结果:
{
    "result": null,
    "reason": "Empty",
    "error_code": 201103,
    "resultcode": "203"
}

3、使用JMeter执行用例
1)新建“测试计划”:手机号码归属地接口测试计划
   (作为根节点!是其他子节点的最顶层容器)
描述:根据手机号码或手机号码的前7位,查询手机号码归属地信息,如省份 、城市、运营商等。
         Test Plan
建议:在“测试计划”中设置全局变量,比如key
 变量名     变量值
 key         xxxxxx

2)在“测试计划”节点下,新建“线程组” Thread Group
目前先测试功能,使用1个线程即可

                          Sampler
3)在“线程组”下,添加“取样器”:“HTTP请求”
比如:
名称:手机归属地查询-HTTP-GET-001
描述:基于HTTP协议,以GET方法,使用11位有效的手机号查询归属地,返回JSON格式的结果;
协议:HTTP
服务器名称:apis.juhe.cn
端口号:
方法:GET
路径:/mobile/get
默认采用:跟随重定向
同请求一起发生参数:
 名称:   值:
phone     13811810099
key        ${key}
dtype      json

                            Listener
4)在“测试计划”下,添加“监听器”:察看结果树
发送请求,观察结果:Text或JSON视图
{
    "result": {
        "zip": "100000",
        "province": "北京",
        "city": "北京",
        "company": "移动",
        "areacode": "010",
        "card": ""
    },
    "reason": "Return Successd!",
    "error_code": 0,
    "resultcode": "200"
}

4、针对HTTP响应码200,添加检查点:
1)找到相应请求   都是
  在线程组下添加,能够为组下的所有请求的结果进行检查
2)在“线程组”下,添加“断言”:“响应断言”
名称:响应断言-HTTP响应码
注释:检查HTTP响应码为200
测试字段:响应头     因为HTTP响应码在响应的头部
模式匹配规则:包括
测试模式:200
自定义失败消息:HTTP响应码不是200!
3)在“测试计划”下,添加“监听器”:“断言结果”
观察执行效果:
  如果只显示请求名称,表示检查通过;
  如果显示请求名称和错误提示,表示检查失败!

5、针对响应文本进行检查
1)找到相应请求  比如001
    在哪个请求下添加,就为哪个请求负责
2)在001请求下,添加“断言”:“响应断言”
名称:响应断言-响应文本
注释:检查响应文本中含有城市名称、运营商名称
测试字段:响应文本
描述匹配规则:包括
测试模式:添加两行 等待检查的文本
   北京
   移动
自定义失败消息:未查到预期城市名、运营商名!

改进:将以上断言分解为两个断言,分别检查,分别给出错误提示!

3)添加“监听器”:断言结果  就绪

6、针对005请求添加文本检查点,检查含有:201103
名称:响应断言-响应文本-错误编码
描述:检查响应文本含有错误编码:201103

补充:设置系统环境变量
1)新建JMETER_HOME  
含义:JMeter的安装目录,供后续借用
比如:
变量名:JMETER_HOME
值:E:\apache-jmeter-5.3

2)修改Path
含义:命令的搜索路径
变量名:Path
值:原有的值;E:\apache-jmeter-5.3\bin
或:原有的值;%JMETER_HOME%\bin
目的:在cmd命令行中任何位置都能通过执行jmeter命令启动JMeter执行。

5、在自动化测试中如何添加步骤的等待时间?(面试题)
目的:让步骤有秩序的执行,符合业务的需要;
       模拟平时用户的操作步骤间隔,更真实;
       测试性能时可以通过调节间隔时间调节施压大小:时间越长,对服务器的压力会越小;
 工具环境   代码或命令             语法
1)LR:lr_think_time(秒数);       类C           性能自动化
2)QTP:wait(秒数)                VBScript     UI功能自动化 基于页面控件
3)Selenium:  sleep(秒数)          Python       UI功能自动化
4)Appium:    sleep(秒数)         Python        手机自动化
5)Java:  Thread.sleep(毫秒数);   Java
6)Linux:  sleep 秒数              Linux shell命令   shell脚本
7)monkey:  adb shell monkey ...--throttle 毫秒数  选项
8)monkeyrunner:  MonkeyRunner.sleep(秒数)   Python(Jython)
                    使用了类 API                使用Java语言实现的一套Python

随机算法:达到随机效果的规则、依据;

9)JMeter: 定时器Timer
效果:在某个请求下添加定时器,会在该请求发送之前等待一段时间;在线程组下添加定时器,组下所有请求都受影响,在请求之前都会等待;多处添加形成累加效果;
<1> 固定定时器:固定等待一段时间(时间更准确)
<2> 高斯随机定时器:按照高斯定理(正态分布)进行随机等待;(显得更真实)
正态分布:多个数据按照正态分布曲线进行概率分布
            --随大流  满足大概率事件
   偏差(毫秒):1000
   固定延迟偏移(毫秒):3000
效果:以3秒为中心,前后偏移1秒为范围,满足正态分布
       越靠近3秒的概率越高,越远离3秒的概率越低;

墨菲定律:越不太可能发生的事情有时容易发生。
(幂律分布)

面试题:接口的单点测试和流程测试?
    单点测试:针对某接口进行一次访问   对应一条URL和参数
    流程测试:将业务流通过多次请求依次访问,依次发送多条URL和参数
    额外问题:上一次请求的结果数据,作为下一次请求的参数,需要采用“关联”技术解决!
用途:进行流程测试时,可以在请求之前适当间隔,一般采用随机间隔(高斯随机定时器),如果要求时间固定时,可以采用固定定时器。
    比如执行某请求后,需要适当等待,后续请求才发送,保证业务完整性。

    
       生活中    计算机中
透明: 看得见     看不见
       透过看见    看不见其存在
同步: 同时做     先后做

<3> 同步定时器:Synchronizing Timer     用于并发测试,作为集合点!
          JMeter或LR模拟  多线程模拟多用户(虚拟用户)
并发测试:模拟多用户在几乎同一时刻一起向服务器发送请求,模拟瞬时压力,观察系统各项性能指标是否符合性能需求。(平均响应时间 < 2秒)
    (TPS 每秒事务数 达到一定标准)
日活:30万  一天时间完成30万笔交易、事务
   300000 / 24*60*60 = 3.47笔/秒
结合二八原则:80/20原则
   80%的交易发生在一天20%的时段内:
   300000 * 0.8 / 24*60*60 * 0.2 = 13.8笔/秒

同步:等待A任务完成后,B任务才能开始  随同
       和多线程、多用户有关
       并发测试?等待所有VU到达集合点时一起释放;
       在多线程开发中,同步技术能够解决线程安全问题;
       --开发中的难点
         Java中的关键字:synchronized  同步关键字
      synchronized { 
         //同步代码块  同时只能允许一个线程执行
         原理:哪个线程进入执行,获取锁标记(钥匙) 同步锁机制
                 其它线程无法进入执行;
                 只有归还了锁标记,才能让其它线程执行;
      }
异步:A任务正在执行,B任务也可开始  异步请求

6、如何进行一次并发测试?(重要面试题)
含义:多用户在几乎同一时刻对某功能点进行瞬时访问,形成严格的并发操作;关键:集合点
LR:
1)Action脚本中添加事务; 目的:事务指标、并发的起点
2)事务开始之前添加集合点:  目的:形成严格的并发
   lr_rendezvous("集合点名");   可以同时管理多个集合点进行分别并发
   lr函数比较通用,不同协议的脚本都可使用
3)控制台场景中设置并发策略:  目的:设定并发的规模
   比如:让所有VU的100%到达集合点时一起释放;
           或正在运行用户的100%
           或直接指定用户数
   并设置超时时间,超过该时间,就不等待,先并发执行;

需求:对天气预报接口进行n用户的并发测试
                             3
       测性能建议使用内网测试,没有网络安全的限制
JMeter:  技巧:同步定时器  Synchronizing Timer     
  同步,具有“等待”之意 蓄势待发

1)找到开始并发的请求;  目的:并发的起点
2)在请求节点下,添加子节点:“同步定时器”  目的:集合点
    多用户(线程)到达该请求时会等待(同步机制)
    等待到齐后一起并发执行
    定时器 -> Synchronizing Timer
1.名称:同步定时器
2.注释:作为并发测试的集合点
3.模拟用户组的数量:默认0  并发用户数参考线程数
                            表示所有线程都参与并发
     期待并发的用户数:3  表示期望要求3个用户并发
     要求线程组的线程数与之对应
4.超时时间(毫秒):10000
  先到达集合点的VU开始计时,如果超过10秒,就不再等待,先并发执行已到达的VU;
3)线程组中设置合理的线程数:3   模拟VU,要足够
4)在线程组下添加和性能有关的监听器
 图形结果:性能变化的趋势
 用表格察看结果:每次请求性能明细
 聚合报告:多次请求汇总统计

补充:对TPS的监听  目前JMeter5.3 添加了插件
   可以添加新的监听器:Transaction Per Second
     jp@gc - Transactions per Second
   简称为TPS  每秒事务数
前提:对某请求设计为一个事务 Transaction
   在“线程组”下,添加“逻辑控制器”:“事务控制器”
   并将某请求移到“事务控制器”下,作为一个事务看待

练习:对用户登录操作进行100VU的并发测试,查看登录请求的平均响应时间,要求<3s(性能需求,提供一些指标,比如平均请求响应时间)
新建测试计划:testLogin.jmx
1)启动被测系统环境:Tomcat服务器  startup.bat
使用浏览器访问:
http://localhost:8880/web01/login.html
目前登录的请求是用访问页面模拟,未直接调用登录接口:
http://localhost:8880/web01/p1.html    返回页面模拟
协议   主机名   端口号 应用路径 资源名
方法:POST
参数:username  Tom
       password  123

2)使用JMeter配置测试计划,添加线程组、取样器
HTTP请求:
  服务器名:localhost         端口号:8880
  协议:HTTP          方法:POST
  路径:/web01/p1.html        说明:真实的接口地址是一个虚拟路径  有后台代码实现
  请求参数:username     Tom
              password      123
3)在请求节点下添加:同步定时器  Synchronizing Timer
  配置期望并发用户数:0   表示希望全部线程并发    
  超时时间:10000  毫秒
4)线程组中设置合理的VU数:100
5)测试计划下添加监听器:
  察看结果树、图形结果、用表格察看结果、聚合报告
  如果需要TPS可以继续添加

测试结果对比:        
请求响应时间=客户端时间+网络时间+服务器时间(Web DB ...)
   并发用户数(个)    平均响应时间(秒)
      100                  0.188
      200                  0.443
      300                  0.818
      ...
      1000                 1.688
重要性能测试策略:递增测试
                       
积累项目经验的技巧:__项目的__模块中,遇到__问题,经过分析,是__原因引起,凭借经验,是__解决的;类似的问题还有__;找其他项目,触类旁通
               
   涉及业务:多分析业务需求
   涉及技术:结合3W1H  What? Why? Where? How?
                            概念    优势   应用场合  使用步骤、注意事项
         123
字面量:1  100   56  "ABC"
变量:变量名不变,变量值可以改变
       使用变量名 指代 变量的值
         代词
系统变量:
   变量名           变量值
  JAVA_HOME    xxxxx1.8
  Path              %JAVA_HOME%\bin;xxx;xxxx

add(a, b):
  return a+b

  以不变应万变!
    变量名  变量的值

         参数就是变量,加入的数据    avg(salary)  
7、如何进行参数化?(变量化)  
含义:将自动化脚本中的某些业务数据 变量化;
        使用变量名 获取 不同业务数据;
目的:将脚本中的业务数据改变,满足更真实的用户体验;
       某些需求中要求业务数据必须改变,比如:用户注册
         用户名、手机号、邮箱号、文档重命名等不能重复
         脚本必须要参数化,改变数据,才可使用
关键:类型 + 数据 + 策略
1)LR: 主要测试性能、也能测试接口,主要测试接口的性能
<1> 类型:File   使用文本文件存储数据    .dat文本文件
           Date/Time 系统日期时间    指定不同格式  偏移
           Random Number 随机值     指定范围
           Unique Number  唯一值     确保多VU各自获取唯一数据
<2> 数据:性能测试要求数据真实、有效、合理
            促成功能实现的基础上,考察性能问题
     要么自己填写,要么关键设置规则自动产生
<3> 策略:取值方式    +   更新时机        超过值的策略
              How?             When?         Out of Values?
  SE组合:Sequential  +  Each Iteration
              顺序             每次迭代
  RE组合:Random   +    Each Iteration
              随机             每次迭代
  UEA组合:Unique   +   Each Iteration  + Abort Vuser
              唯一的           每次迭代       放弃虚拟用户
             保证多VU各自取值互不相同
     版本1:File类型              自己填写业务数据
     版本2:Unique Number类型  感觉规则产生大量唯一数据
      比如:注册大量手机号、上传大量文件 重命名不能重复
http://tool.chinaz.com/tools/urlencode.aspx

2)JMeter:  参考 类型+数据+策略
了解:常用类型
  <1> 在测试计划中设置全局变量  比如key
         优点:全局可用,整个计划共享
         缺点:值一次只有一个,过于单一
  <2> 使用“配置元件”:CSV Data Set Config 
                          CSV数据设置配置
         优点:数据自己准备、可定制,大批量使用
         缺点:工作量较大
  <3> 使用“函数助手”:生成不同功能函数,获取数据
         优点:获取方便,功能丰富

需求:对请求的参数数据进行改变,比如查询中文文本、城市信息...
<1> 找到需要参数化的位置,比如提交的请求参数值
<2> 选择类型:文本文件,并提供文件数据   data
对比:LR: user.dat文件     普通的文本文件,扩展名改为dat
username,password    第一行是列名
jojo,bean               第二行开始才是数据
qq,123
|                <-- 光标应该在最后一行数据的下一行开头
                       ctrl+a 全选文本 检查格式

JMeter:  user.txt文件   不需要列名
jojo,bean               第一行开始就是数据
qq,123
|                <-- 光标应该在最后一行数据的下一行开头

           新建文本文件
比如:E:\text.txt    数据文件存储的路径名不要有中文、空白 否则影响读取
今天天气不错,今天
继续接口测试,接口
|         <-- ctrl+a 光标应该在最后一行数据的下一行开头

说明:第1列表示需要提交的 分词文本
       第2列表示分词后含有的文本 需要检查


E:\city.txt
北京
上海
深圳

说明:仅1列,表示城市名称
       没一行供每次迭代、每个VU使用

<3> 在线程组下添加“配置元件” -> CSV Data Set Config   数据设置配置
说明:在谁之下添加,作用域就在谁之下
        线程组下添加,组内的请求都可共享使用
1.Filename: E:\text.txt
文件路径名  绝对路径、相对路径(相对于当前计划文件 和jmx并列)

查看JMeter运行日志,查找问题原因
引起问题原因:            非法 参数 异常
Caused by: java.lang.IllegalArgumentException: File city.txt must exist and be readable  文件city.txt  必须存在 和 可读的

将city.txe文件 放在和jmx文件同样的目录下,就可使用相对路径,直接写city.txt

2.File encoding: 默认不写  或 UTF-8 
           根据实际需要也可以:UTF-8、GBK、GB2312
指定 文件字符编码    根据实际项目进行设置
3.Variable Names: text,check
              后续请求通过${text}   ${check}取值     LR没有$
变量名,就是后续请求中的变量名、参数名
多列使用逗号分隔,列的顺序和文件中列的顺序一致
比如登录:username,password  
       后续取值方式 ${username} ${password}
4.Delimiter: ,
  分隔符,默认逗号
  循环   在    End Of File 文件结束
5.Recycle on EOF?: True   可以循环重复使用数据
 循环使用数据 文件结束时 
6.Stop thread on EOF?: False
 当文件结束时是否结束线程(VU) 工具通过线程模拟用户
 用途:当多用户要求获取不同数据时,需要适可而止
         唯一策略,如同放弃VU
7.Sharing mode: All threads
 共享策略模式  多线程,依次向下交替使用数据
    VU1:  a1
    VU2:  a2
    VU3:  a1
    VU4:  a2

<4> 将请求中的固定数据改为参数: ${参数名}      类似JSP中EL表达式
比如:中文分词技术  -> ${text}

响应断言 : Test failed: text expected to contain /中文/

<5> 检查点中有相关的参数也需要更改;
比如:将 中文 ->  ${check}

常见问题解决方法:
  文件路径名、变量名是否一致、数据内容是否一致、策略细节是否合适、字符集UTF-8

java.net.UnknownHostException: api01.idataapi.cn
            未知的主机  异常
          路径名 语法 异常    
java.net.URISyntaxException: Illegal character in authority at index 7: http://api01.idataapi.cn :8000/nlp/segment/bitspaceman?apikey=

响应断言 : Test failed: text expected to contain /${check}/

错误      从运行日志Log中查看:                文件 找不到  异常
ERROR - jmeter.config.CSVDataSet: java.io.FileNotFoundException: C:\Users\tren\Desktop\day07\city.txt (系统找不到指定的文件。) 

练习:针对邮编查询地名请求进行参数化
思路:需要的参数?
邮编     页码  每页条数 结果类型  检查的城市名  
postcode,page,pagesize,dtype,city

数据文件:E:\postcode.txt
      或在jmx共同的目录下,新建postcode.txt
      后续使用相对路径
postcode,page,pagesize,dtype,city
100080,1,5,json,北京市
201101,2,3,json,上海市
215001,1,3,xml,苏州市

邮编查询地名-HTTP-POST-001
基于HTTP协议,以POST方法,使用有效的一组数据,包括邮编、页码、每页记录条数、返回格式类型查询地名,查看是否返回正确的结果
URL:
http://v.juhe.cn/postcode/query
HTTP
v.juhe.cn
POST
/postcode/query
设置参数:
postcode    215001    
key    ${key}    
page    1    
pagesize    5    
dtype    json

思路:先将一个基础例子配置好后,再批量使用
后续添加检查点
    HTTP响应码 200
    响应文本:对应的城市名
    
对业务数据进行参数化  
   类型:配置元件 CSV Data Set Config
文件名:postcode.txt    相对路径
文件编码:默认不写
变量名称:postcode,page,pagesize,dtype,city
忽略首行:True
后续默认

修改请求中参数:
${postcode}
${page}
${pagesize}
${dtype}
修改文本检查点中内容:
${city}

面试题:Postman如何进行参数化?
思路:参数化也叫变量化,是将自动化脚本中的业务数据使用参数、变量替代,结合数据和策略控制取值方式,为了让业务更真实、并且符合某些特殊业务的需要,比如注册的用户名是不能重复;当前Postman通过一个请求,批量发送不同数据,减少用例的数量;
实现方式:
1)全局变量:
Postman右上角“环境管理”按钮 Manage Environments 
  全局Globals -> 输入变量名 和 变量值 -> 保存Save
后续使用数据时:{{变量名}}

对比:LR: {变量名}
       JMeter:  ${变量名}
       Postman: {{变量名}}
目的:将以往多条用例合并,不同的数据通过一条用例逐个使用

也可以:通过代码设置全局变量
 在Pre-request Script选项卡中设置: 请求之前的操作
postman.setGlobalVariable("key", "xxxxx");
          设置 全局 变量   变量名  变量值
或
pm.globals.set("sj_key", "xxxxxx");

属于JS语法

2)使用文档进行参数化:支持txt、json、csv文件格式
以JSON文本格式为例:
<1> 新建phone.json,编辑:要求以数组方式存储数据,并且注意保存文本采用合适的字符编码集,推荐:UTF-8
[
  {"phone": "13811810088", "city": "北京", "company": "移动"},
  {"phone": "1330088", "city": "上海", "company": "电信"},
  {"phone": "13000661199", "city": "广州", "company": "联通"}
]
<2> 将请求中业务数据使用参数代替:{{phone}}
<3> 针对用例集 -> 菜单Run窗口 
  Select File 选择文件:指定phone.json
  自动识别 文件格式类型:application/json  
  由于数组中有三条数据,工具会自动修改为迭代3次 Iterations
  建议设置请求间隔:1000ms  就是1秒
  技巧:可以通过Preview 预览数据效果
  Run运行该用例集
注意:检查中的业务数据也需要跟着改变
       json文本保存编码格式也需要统一,比如另存为UTF-8
技巧:检查点中如何获取参数? tests选项卡的代码 JS语法
JS局部变量      根据参数名获取参数值   从phone.json文件中 
city = pm.variables.get("city");
company = pm.variables.get("company");
tests["响应主体含有:北京"] = responseBody.has("北京");
改为:
tests["响应主体含有:" + city] = responseBody.has(city);

tests["响应主体含有:" + company] = responseBody.has(company);

思路:如何准备数据?
 结合手工测试在界面中填写的业务数据,考虑有效、无效、必填、选填、数据边界值、各种条件的组合等,设计参数化数据,供工具自动执行,并且对结果进行有针对性的检查。

练习:针对邮编查询接口,基于HTTP协议,以POST方法,采用有效数据根据邮编查询城市信息,采用参数化技术。

邮编查询地名-HTTP-POST-001
基于HTTP协议,以POST方法,采用有效数据根据邮编查询城市信息,采用参数化技术。

参数化数据文件:postcode.json   另存为,指定UTF-8
[
  {"postcode": "100080", "page": "1", "pagesize": "3", "city": "北京市"},
  {"postcode": "215001", "page": "2", "pagesize": "3", "city": "苏州市"},
  {"postcode": "201500", "page": "1", "pagesize": "5", "city": "上海市"}
]

技巧:通过在线JSON校验工具检查语法格式
https://www.json.cn/

安装好Mysql5       Mysql早期被Sun公司(Java)收购,后来Sun被Oracle收购!
mysql-5.0.18-win32.zip  解压后:Setup.exe
选择Skip跳过注册
默认端口号3306  如果冲突可以更改比如3308
指定数据库字符集:第3项 选为utf8  和UTF-8等同
可以将mysql的命令路径bin目录添加到PATH中
指定数据库密码,比如:123456
Execute 执行后全部显示对勾,表示成功!

如何查看数据库端口号?
cmd中:netstat -ano|more     
                    回车:跳行   空格:翻页    q:退出
   找到 3306  对应 pid进程号
     根据任务管理器根据pid找到对应进程 mysqld.exe


如果安装失败,需要:
<1> 先卸载mysql    控制面板->添加与删除程序  卸载MySQL Server 5.0
<2> 到C:\Program Files (x86)下,删除MySQL目录
<3> 最好重启系统
<4> 重新安装

查看哪些数据库:
show databases;
创建一个数据库:testing
create database testing;
选择使用某数据库:
use testing;
查看数据库中有哪些表:
show tables;

8、如何使用JMeter压测数据库? JDBC
1)原理
 JMeter是Java开发,Java访问数据库技术规范:JDBC
 Java DataBase Connectivity
  Java  数据库    连接
本质:一套API、一套类和接口、编程规范
                     class interface
了解三方:演绎设计者、实现者、使用者 分工的效果
<1> 规范的制定者:Oracle SUN  Java语言作者
前提:Java语言本身不具备访问数据库的可能
但是:通过设计(数据库驱动)接口interface,只有设计没有实现,是制定规范的好办法;由各大数据库产商实现;
<2> 规范的实现者:数据库产商     .class 类 字节码文件
 公司        产品                  数据库驱动类的实现 driver
Oralce      Oracle10g 11g 12c  将类打包 ojdbc14.jar包
IBM         DB2                    db2.jar
Microsoft   SqlServer              
Mysql        Mysql                  mysql.jar
...
<3> 规范的使用者:广大程序猿,包括JMeter作者、JMeter使用者
                     (Java程序)
效果:JMeter通过Java编程可以让工具连接和访问数据库
前提:既需要JDBC API:   JDK中默认含有  java.sql包 接口和工具类    已经就绪
       还需要数据库驱动类的实现:各种jar包
            想连接哪种数据库,就需要对应的jar包
                 Mysql5          mysql-connector-java-5.1.7-bin.jar

  Java程序、JMeter实现的程序
2)程序访问数据库需要哪些参数? (工具配置的重点)(面试题)
<1> 主机名(IP地址):localhost
  目前数据库安装在本地主机,项目中其它机器需要IP地址
  如果Mysql安装在其他主机中,就写IP地址,确保网络可达
<2> 数据库端口号:3306
  使用netstat -ano|more 查看端口号对应关系
<3> 数据库名:testing
<4> 数据库用户名:root
<5> 数据库密码:123456
以上信息可以汇总为:
<1> URL:访问数据库资源的地址
jdbc:mysql://localhost:3306/testing
协议名        主机名  端口号 数据库名
<2> 数据库用户名:root
<3> 数据库密码:123456
<4> 数据库驱动类名:由数据库产商实现的程序  Java类名
com.mysql.jdbc.Driver   目的:让工具注册数据库驱动程序!
        包名     类名

存在于数据库驱动:Mysql版    jar包中
   mysql-connector-java-5.1.7-bin.jar
安放到:E:\driver下

目前在testing库建立表和数据:测试数据
drop table emp;
create table emp (
   empno   int(11)    primary key,
   ename   varchar(10)   not null,
   job      varchar(9)
);
insert into emp values(9001, 'Tom', 'CTO');
insert into emp values(9002, 'Mary', 'CFO');
insert into emp values(9003, 'Andi', 'COO');
insert into emp values(9004, 'Rose', 'CHO');
insert into emp values(9005, 'James', 'CSO');
commit;
select * from emp;
select empno, ename, job from emp;

-----Oracle 版本--------
drop table emp;
create table emp (
   empno   number(11)    primary key,
   ename   varchar2(10)   not null,
   job      varchar2(9)
);
insert into emp values(9001, 'Tom', 'CTO');
insert into emp values(9002, 'Mary', 'CFO');
insert into emp values(9003, 'Andi', 'COO');
insert into emp values(9004, 'Rose', 'CHO');
insert into emp values(9005, 'James', 'CSO');
commit;
select * from emp;
select empno, ename, job from emp;

Oracle的连接配置参数:
默认数据库名orcl
jdbc:oracle:thin:@localhost:1521:orcl
jdbc:oracle:thin:@localhost:1521:XE
oracle.jdbc.driver.OracleDriver
system
123456

查看Oracle数据库名:   Oracle数据字典 查看内部信息
SQL> select name from v$database;
SQL> show parameter db_name;
结果:XE


观点:目前许多问题是从数据库层面发现的;
       编写sql对数据库进行查看,看结果是否满足预期;
       例子:下订单 对数据库哪些表有影响?
           订单表、条目表、用户表、商品表、收货人表...
           order    item    user     product    receiver

需求:对某条查询sql进行100~2000VU的并发测试,观察sql的平均响应时间,要求<1.5秒;结合递增策略
思路:JMeter具有访问数据库的能力(JDBC技术),能够发起并发压力
      只要通过合理的配置,就能够达成一个测试计划

9、实现具体步骤:
1)新建测试计划 testJDBC.jmx
2)测试计划下新建“线程组”:       建议:先测试功能,再给压力测试性能
  默认1个线程,先模拟1VU测试功能
3)在线程组下,新建“配置元件” -> JDBC连接配置
  JDBC Connection Configuration
 1.针对Mysql5数据库的连接配置
 2.Variable Name: mysql5
 变量名,就是对当前配置的代号,供后续请求选择使用
 3.数据库URL:jdbc:mysql://localhost:3306/testing
 4.JDBC数据库驱动类名:com.mysql.jdbc.Driver
 5.数据库用户名:root
 6.数据库密码:123456

4)在线程组下,添加“取样器Sampler” -> JDBC请求   JDBC Request
1.注释:针对一条查询sql的请求
2.Variable Name: mysql5
  变量名,选择之前JDBC连接配置的 代号
3.SQL Query
  Query Type: SQL的类型
<1> Select Statement:特指select语句  查询 (选择) 读操作   Disk Input 输入
 结果就是查询的行、列内容
<2> Update Statement:泛指所有的更新  增、改、删   写操作   Disk Output 输出
 insert、update、delete
 结果是影响的记录条数    比如删除5条记录,返回5

   可 调用
<3> Callable Statement:可调用的存储过程
对比:使用存储过程前后
 不用:日常访问
   WebServer -网络->  DBServer
  接口程序
   SQL 网络传输->翻译SQL->C程序->编译->连接->执行
       <------       查询结果

存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,它存储在数据库中,一次编译后永久有效,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。在数据量特别庞大的情况下利用存储过程能达到倍速的效率提升;

 使用:大大优化查询的性能
   WebServer -网络->  DBServer
   调用存储过程名        存储过程 提前编译好 等待调用
        g1 ------------->
            <------------  查询结果
 缺点:存储过程固化在数据库端,如果业务规则改变了,需要重新修改和布置存储过程,难以维护。适合于功能比较稳定、数据量较大、对性能有高要求的业务。

<4> Query: 写有效的sql语句,sql本身结尾没有分号
select * from emp

5)在测试计划下添加“监听器”:-> 察看结果树:
问题1:未添加数据库驱动程序
响应      消息                SQL异常       没有 合适的  驱动   找到
Response message: java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/testing

问题2:请求指定的连接配置名称不对
数据库变量名找不到
No pool found named: 'mysql6', ensure Variable Name matches Variable Name of JDBC Connection Configuration

问题3:SQL语句语法不对   比如from 和 form
                                     来自     表单
                             SQL语法 错误
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'form emp' at line 1
                              表单

问题4:数据库或表名不对
 testing数据库中没有emp1表    表也是数据库中的对象
Table 'testing.emp1' doesn't exist

未知的数据库  testing1
Unknown database 'testing1'

问题5:连接配置设置失误,比如URL地址、用户名和密码
Response message:                通讯异常     通讯连接失败com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

SQL异常,访问被拒绝  用户账户相关  有密码
                               数据库有关的异常
Response message: java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)

6)在环境中添加数据库驱动:xxx.jar
方法1:在当前测试计划中添加   仅当前计划可用
 在 “测试计划”中 -> 添加jar包到类路径下
 通过“浏览” 选择合适的jar包:
   E:\driver\mysql-connector-java-5.1.7-bin.jar

方法2:在JMeter工具中添加   以后所有计划都可用   一劳永逸
 在JMeter的lib目录下,添加合适的第三方jar包
 好处:所有测试计划共享这些资源;
 注意:添加后,需要重启JMeter才生效;  

7)在JDBC请求下,添加“定时器”:同步定时器
  Synchronizing Timer
指定期望并发用户数:100、200、300、500、1000、2000
                      写成0  表示所有线程参与并发
超时时间(毫秒):10000    表示10秒
                      如果写0  表示无限期等待

8)线程组需要对应线程数: 结合递增测试策略进行  压力从小到大 逐步加压
  100、200、300、500、1000、2000

9)添加和性能测试有关的监听器:
 图形结果、用表格察看结果、聚合报告

平均响应时间:(毫秒ms)
  75   87            101   124    767

结果大约0.1秒左右,随着压力增大,变化不明显,由于数据库中的数据量不大,并且查询语句逻辑简单,耗时较少;另外,明数据库很可能存在查询结果的缓存Cache(思想:拿空间换时间),能够尽快将结果呈现给用户;

思考:后续需要测试什么SQL?
  后台接口程序,在需要从数据库中获取信息时,会通过程序向数据库发送执行SQL语句,随着业务复杂度提高,SQL语句也越来越复杂,比如涉及多表连接查询、子查询(查询嵌套)、海量数据中查询少量结果;此时对数据库的测试更有必要,有时需要测试人员自己编写SQL语句,和开发方查询结果进行对比。
  既可以测试SQL的功能,又可以测试SQL的性能(大部分性能问题和数据库有关)。

练习:使用JMeter工具向emp表中添加5条员工信息
1)新建测试计划:testAdd.jmx
2)测试计划下添加线程组,默认1个线程
3)线程组下添加配置元件:JDBC连接配置
<1> 变量名(连接配置代号):mysql5
<2> 数据库URL:jdbc:mysql://localhost:3306/testing
<3> JDBC数据库驱动类名:com.mysql.jdbc.Driver
<4> 数据库用户名:root
<5> 数据库密码:123456
4)线程组下添加Sampler 取样器:JDBC请求
<1> 变量名(连接配置代号):mysql5
<2> SQL类型:Update Statement   更新语句
     insert、update、delete都属于更新操作!都会改变数据库数据
<3> insert into emp(empno, ename, job) values(9006, 'Lucy', 'PM')

insert into emp(empno, ename, job) values(9006, '', '')

5)在测试计划下添加监听器:
察看结果树

第一次执行成功了;
第二次执行失败了:
Duplicate entry '9006' for key 1
Response message: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '9006' for key 1
MySQL完整性约束违反异常:密钥1重复条目'9006'
原因:违反了主键约束(实体完整性约束,就是唯一性)
     主键PK  primary key  唯一 且 非空

6)需要对数据进行参数化:
在线程组下添加配置元件:CSV Data Set Config   数据配置
<1> 数据文件路径:E:\emp.txt
<2> 字符集:不填 或 UTF-8    根据实际环境匹配
<3> 变量名:empno,ename,job
     忽略首行:True  
<4> 分隔符:默认逗号分隔
<5> Recyle on EOF: False  文件结束时不允许重复使用数据
<6> 文件结束时是否结束线程:True 
<7> Sharing Mode共享模式: 默认All Threads
     不同线程各自获取不同数据
在E:\下准备emp.txt,内容如下:
empno,ename,job
9007,Emp007,PM
9008,Emp008,SD
9009,Emp009,SD
9010,Emp010,SD
9011,Emp011,TSD
|
7)将JDBC请求中的SQL的数据改为参数:${变量名}
insert into emp(empno, ename, job) values(${empno}, '${ename}', '${job}')

列举常用的函数助手:
<1> char    根据字符编码 生成 对应的字符
${__char(65)}     A
${__char(66)}     C
...
${__char(97)}     a

<2> Random   根据数据范围生成一个随机整数
            会将该随机数存于变量num中,供后续继续使用
${__Random(1,100,num)}  表示生成1~100内的随机整数
后续使用:
${num}

select ${__Random(1,100,num)}, ${num}
由于随机数可能会重复,不适合作为id值

<3> UUID  通用唯一识别码(Universally Unique Identifier)的缩写
 能够生成大量唯一的长编号
${__UUID}

ebf12ea8-7a81-40ec-b1f9-1deaed7b9023
9f96f1ed-6816-4778-916f-ace42f706813

<4> counter  计数器   从1开始递增
${__counter(TRUE,num)}    每个VU从1开始取值
${__counter(FALSE,num)}   多VU共享使用递增数据

select ${__counter(TRUE,num)}, ${num}, ${num}
效果:
select 1, 1, 1
select 2, 2, 2
...

补充技巧:JMeter中具有“函数助手对话框” 生成一些函数
比如:__Random  生成随机数 比如1~100 变量名num
${__Random(1,100,num)}   后续${num}
比如:__counter  生成 自增序列    常用于数据库表中id的生成
          TRUE: 不同VU局部拥有  VU1: 1 2 3    VU2: 1 2 3
          FALSE: 不同VU全局共同拥有 VU1: 1   VU2: 2   VU3: 3 ...
${__counter(FALSE,num)}
${__counter(TRUE,num)}

insert into emp(empno, ename, job) values(${__counter(TRUE,num)}, '${ename}', '${job}')

insert into emp(empno, ename, job) values(${__counter(FALSE,num)}, concat('Emp', ${num}), '${job}')

Mysql中字符串拼接:concat函数
concat('Emp', 'hehe')   结果:'Emphehe'
concat('Emp', 123)      结果:'Emp123'

问题:Duplicate entry '2' for key 1
        重复的

技巧:通过SQL改变后台数据,让数据不重复;
delete from emp where empno between 1 and 10;

面试题:如何向数据库中快速添加大量数据?
思路:自动化   工具、代码、SQL、参数化、循环...
比如:JMeter 通过配置执行  testadd.jmx

核心:JDBC规范、JDBC连接配置、JDBC请求
      SQL分为:select和update
      数据可以参数化:全局--测试计划
                          CSV数据配置
                          函数助手

10、如何进行在线综合场景测试?(混合交易测试)
  模拟很多用户,不同用户执行不同任务,持续执行一段时间
对比:基准测试   1个线程,循环执行若干次
       并发测试   n个线程,各自并发执行1次或n次
       在线综合场景  n个线程,执行不同业务若干次、一段时间   混合交易
                       多用户、多任务、时间长
技巧:先调试好某任务,之后再重组
       不同测试计划中的节点可以复制、粘贴,可以剪辑
重要细节:
<1> 测试计划设置为:不能选择“独立运行每个线程组”,除非不同组之间确实要先后执行
<2> 不同线程组设置相应的线程数,模拟不同VU
<3> 线程组中可以有1条或多条请求
<4> 线程组中设置“调度器”,可以设置场景运行的持续时间

录制   和   回放
Badboy     JMeter
      -> .jmx

11、使用Badboy工具为JMeter录制脚本
前提:有界面  使用浏览器访问Web服务器
1)Badboy是澳洲提供的一个录制脚本工具,尤其为JMeter提供了定制化的录制方案,简而易用、轻量、免费;
2)安装:BadboyInstaller-2.1.2.exe
运行默认下一步
3)录制:
先填写首页URL
http://localhost:8880/web01/login.html
执行正常业务操作,等待录制好(录制状态为蓝色)再下一步
录制结束点击Off,保存为.bb文件
导出为.jmx(File -> Export to JMeter)
4)使用JMeter打开jmx文件进行调试,发请求,查看结果;

后续可以对测试计划进行增强,比如检查点、定时器、集合点、配置元件... 

练习:对百度的一次关键词搜索录制脚本,搜索:JMeter
https://www.baidu.com

面试题:两个接口之间如何协作?
 业务需要依次访问不同接口,比如第1个接口返回的结果,需要作为第2个接口请求的参数,如何实现?

关键思路:脚本关联技术
  之前请求返回的数据,作为后续请求的参数
  (与有关的数据产生联系)
比如:JMeter使用 “后置处理器”:“正则表达式提取器”

<meta name="description" content="全球最大的中文搜索引擎

<meta name="description" content="全球(.*)的中文搜索引擎


结果:
{"q":"最大","p":false,"g":[{"type":"sug","sa":"s_1","q":"最大公因数和最小公倍数"},{"type":"sug","sa":"s_2","q":"最大霸王龙化石拍出天价"},{"type":"sug","sa":"s_3","q":"最大的自然数是多少"},{"type":"sug","sa":"s_4","q":"最大摄氧量"},{"type":"sug","sa":"s_5","q":"最大公约数"},{"type":"sug","sa":"s_6","q":"最大的猫头鹰"},{"type":"sug","sa":"s_7","q":"最大的两位数和最小的两位数差是多少"},{"type":"sug","sa":"s_8","q":"最大泡压法测定溶液表面张力实验报告"},{"type":"sug","sa":"s_9","q":"最大金矿老板"},{"type":"sug","sa":"s_10","q":"最大的负整数是多少?"}

安装好VMware
Linux安装文件:
shrike-i386-disc1.iso   638MB
shrike-i386-disc2.iso   646MB
shrike-i386-disc3.iso   485MB

 

posted @ 2020-12-18 17:28  藤上小冬瓜  阅读(286)  评论(0编辑  收藏  举报