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