接口测试工具使用
一、接口测试分类
接口测试:就是测试项目和项目之间,模块和模块之间,组件和组件之间的数据交互和权限鉴定(鉴 权)。
分类:
测试外部接口:是被测系统和外部系统之间的接口。(一般只要正常调用即可)
测试内部接口:是被测系统内部各个模块之间的接口。
1.内部接口提供给内部系统使用(一般只要正常调用即可)
2.内部接口提供给外部系统使用(测试必须非常全面,正例,反例,鉴权,兼容)
接口测试重点测试什么?
接口参数传递的正确性,接口功能的正确性,以及各种异常情况系统的容错能力,接口的权限控制,接口的兼容性。
前后端分离:前后端联调。mock模拟,测试左移。 基于安全考虑
市面接口类型
1.基于soap接口架构的接口:基于webservice协议,基于XML传输数据的。
分辨:接口地址:https://….?wsdl
基于工具:soapui
2.基于RPC接口架构的接口:阿里的dubbo,RMI,thift 分辨:接口地址:dubbo://
springcloud微服务
基于工具:jmeter(插件)
3.最核心的主流:基于restful接口架构:http协议
基于工具:jmeter,postman
二、接口流程,用例设计方案
1.拿到api接口文档(可以从开发拿,也可以抓包自己创建),熟悉接口文档业务,接口地址,接口鉴权(鉴定是否有访问接口的权限)方式,接口入参,出参,是否有完善的错误码机制。
2.编写接口测试用例以及评审
思路:
正例: 输入正常的入参,接口能够正常返回。(get/post)反例:
鉴权反例: 必填,错误的鉴权码,鉴权码已过期…….
参数反例: 必填,参数类型异常,参数的长度异常…..
错误码反例:
其他场景:黑名单,接口调用次数限制,分页场景。
接口的兼容性:一个接口是否能兼容多个版本的前端
3.使用接口测试工具Postman/jmeter/apifox执行接口测试,提供BUG,以及BUG验
Postman+Newman+Jenkins+git实现持续集成并目生成报告
jmeter+ant+git+jenkins持续集成
三、postman执行接口测试
请求:请求方式,请求路径,请求头,请求参数
Params: get请求传参
Authorization: 鉴权
Headers: 请求头
- accept:客户端接收的数据类型
- content-type:客户端发送给服务器的数据类型
- user-agent:客户端的类型
- xmlhttprequest:异步请求
Body: post请求传参
- none:没有参数
- form-data: 文件上传 (包含键值对和文件上传)
- x-www-form-urlencoded: 表单请求 (键值对)
- raw: 使用原始数据格式请求 (JSON,XML,HTML,Text,Javascript)
- binary: 二进制文件上传。
Pre-request Script: 请求之前的脚本
Tests: 请求之后的脚本。
Settings: 设置
Cookies: 是Postman用于自动管理Cookie的功能
响应:
Body:返回的值
- Pretty:以不同的格式查看返回结果
- Raw:以文本格式查看返回结果
- Preview:以网页格式查看返回结果
Cookies:响应的Cookie
Headers:响应头
TestResults:断言的结果
调试
Console控制台
面试题:get请求和post请求的区别是什么?
1.get请求一般用于获取数据,post一般用于提交数据。
2.传参的方式不一样: get请求在接口地址里面以?的方式传参,多个参数直接用&分隔。 post是在body当中传参。
3.post比get请求安全。
4.get请求只发一个数据报文,post请求发送两个数据报文。
接口关联
第一种方式:
1.取值并设置全局变量(JSON提取器)只能用于json数据
//打印用于调试
console.log(responseBody);
//把返回的字符串转换成JSON对象。
var baili = JSON.parse(responseBody);
//取值
console.log(baili.access_token);
2.在需要的接口里面通过<!–swig0–>
json;是一种数据格式。
它有两种数据:
1.对象(字典)(键值对,key:value) {key:value}
2.数组 (列表) [a,b,c,d]
键值对:key:value
第二种方式:
正则表达式提取器:用于所有数据
//判断只有返回成功才需要提取
if(responseBody.search("access_token")!=-1{
//正则表达式提取器
console.log(responseBody);
//通过正则匹配值,match匹配,
var datas = responseBody.match(new RegExp('"access_token":"(.+?)")');
console.log(datas[1]);
//设置成全局变量
pm.globals.set("tokens",datas[1]);
}
2.在需要的接口里面通过<!–swig1–> Python自动换行
环境变量和全局变量
全局变量:在所有的接口里面都可以访问的变量
环境变量:在当前环境里面都可以访问的变量
1.设置环境变量
2.把所有的请求中的ip地址改成获取环境变量的方式
3.在postman的右上角选择不同的环境即可。
四、postman动态参数和断言
第一种:系统自带的动态参数
//动态时间戳 //动态0-1000的整形 //动态的guid字符串第二种:自定义的动态参数
//自定义动态参数生产随机数
var times = Date.now();
pm.globals.set("times", times);//定时五秒
const sleep = (milliseconds) => {
const start = Date.now();
while (Date.now() <= start + milliseconds) {}
};
sleep(5000);
Status code: Code is 200 检查返回的状态码是否为200 (常用)
Response body: Contains string 检查返回的数据中包括有指定的字符串 (常用)
Response body: JSON value check 检查json中的其中一个字段的值 (常用)
Response body: ls equal to a string 检查返回的值等于一个指定的字符串 (常用)
Response headers: Content-Type header check 检查是否包含有content-type响应头
Response time is less than 200ms 检查请求的时间少于200MS
Status code: Successful POST request 检查返回的状态码是否在数组中
Status code: Code name has string 检查状态信息是指定的字符串
//------------断言-----------
pm.test("检查返回状态码为200",function(){
pm.response.to.have.status(200);
});
pm.test("检查返回的结果中包括指定字符串",function(){ pm.expect(pm.response.text()).to.include("access token");
});
pm.test("检查json中其中一个字段的值",function () {
var jsonData = pm.response.json();
pm.expect(jsonData.expires_in).to.eql(7200);
});
//第四种在编辑接口
pm.test("Body is correct",function () {
pm.response.to.have.body( '{"errcode" :0, "errmsg" :"ok"}');
});
pm.test("Content-Type is present",function () {
pm.response.to.have.header("Content-Type" );
});
pm.test("Response time is less than 200ms", function(){
pm.expect(pm.response.responseTime).to.be.below(300);
});
pm.test("Successful POST request", function () {
pm.expect(pm.response.code).to.be.oneOf([200,202]);
});
pm.test("status code name has string", function () {
pm.response.to.have.status ("OK");
});
pm.test("Body matches string",function () { //断言形如:张三534214的数据
pm.expect(pm.response.text()).to.include("张三"+pm.globals.get("times"));
一旦需要断言随机数,那么就必须使用自定义动态参数并且要注意如下事项:
1.在断言的代码中不能够使用的方式取全局变量。
2.一般通过:pm.globals.get(“times”) 取全局变量的值
五、Postman批量运行测试用例和参数化
特别要注意:文件上传的接口在做批量运行的时候会报错
解决方案:在settings中的Location为postman默认文件上传目录,需要将文件上传的文件拷贝到这个目录
Allow reading files outside working下开启选项
第一组数据:
{"access token":"54_9ztT4UEWEtv5LBGm4gUogsam9xjbSu35VjsV8DU01Di9EUGORN5R3ywKqHZIXP(45cMsuymFkP7GazAnBrH7LrYi8mJ8apGSh-q4bayPdXtbSzfETP7IEORLT2vwOPknfYPOE8e-OA I2urOZUfAIAENI",
"expires_in": 7200}
第二组数据:
{
"errcode": 40002,
"errmsg": "invalid grant_type rid: 620cfc5e-51b0dfc4-118b36a1"
}
上传csv文件批量处理
在Tests中,编写后置处理
//设置成全局变量
pm.globals.set("tokens",datas[1]);
//街言包含有access_token
pm.test("Body matches string", function (){
pm.expect(pm.response.text()).to.include(data.getassert_str);
特别注意: 在断言中取数据文件的值,不能使用:pm.globals.get(“times”) ,而是要使用:data.assert_str
六、Postman接口测试之Cookie鉴权和Mock测试
1.什么是Cookie? cookie是一小段文本,格式是key-valuie键值对
分类:持久化,回话级。
2.查看Cookie? F12,抓包工具。
3.Cookie是如何实现鉴权的,如果判断接口和接口之间存在Cookie鉴权。
cookie可以传输session,也可以传输token。
cookie鉴权的原理:分为两步
1.当客户端第一次访问服务器的时候,那么服务器就会生成cookie,并且通过响应里面的set-cookie 传输给客户端。客户端会自动保存。
2.当客户端第2-N次访问服务器的时候,那么客户端就会自动的读取本地的cookie,然后根据主机IP或 域名添加对应的cookie从而实现鉴权。
Mock测试
mock:模拟
应用场景:
1.前后端分离的架构下,前后端的开发是不同步,前端的展示数据依赖于后端的接口。后端的接口还没 完成。
2.当被测系统调用第三方接口,这个时候我们想要测试这个接口的错误场景。
3.去甲方展示demo,静态网页
Shift+F5 :缓存刷新
postman的mock测试每天只能访问1000次。
七、Postman处理需要加密和解密的接口以及持续集成
目前市面上的加密技术:
1.对称式加密:DES,AES,Base64
//Base64位加密
//把需要加密的值转换成utf-8的编码格式
var us = CryptoJS.enc.Utf8.parse("admin");
var pw = CryptoJS.enc.Utf8.parse("123");
//对转换后的值做Base64加密
var bs64_us = CryptoJS.enc.Base64.stringify(us);
var bs64_pw = CryptoJS.enc.Base64.stringify(pw);
//设置为全局变量
pm.globals.set("bs64_us",bs64_us.toString().toUpperCase());
pm.globals.set("bs64_pw",bs64_pw.toString().toUpperCase());
2.非对称式加密(双钥):RSA加密
3.只加密不解密:SHA加密,MD5
4.混合加密(自定义加密方式)
5.接口签名Sign
Postman持续集成
newman (新男人): 专为postman而生的命令行工具。
安装:
1.安装Nodejs
2.安装newman
命令如下: npm install -g newman
3.导出postman的脚本并执行。 导出:用例,环境,全局变量。
命令:
newman run "e:\newmans\yongli.json" -e "e:\newmans\huanjing.json" -g "e:\newmans\quanju.json" -r cli,html,json,junit --reporter-html-export "e:\newmans\report.html"
有Postman,Jmeter,为什么现在很多企业用requests做接口自动化呢?
1.没有非常完善的报告体系、
2.怎么实现团队协作?版本控制。
3.CSV参数化。
4.只支持http和https协议,支持webservice,dubbo不支持。
5.找错,定位问题。
6.连接数据库,日志监控。
所以:复杂的大量的接口测试,使用python+requests接口自动化。
八、Jmeter的界面和组件详解
jmeter依赖于java环境(jdk1.8以上)
1.安装jdk以及配置jdk的环境变量。
2.jmeter不需要安装,解压即可使用
backups 备份jmx脚本。
bin目录: ApacheJMeter.jar Jmeter的主要jar文件
jmeter.bat 启动文件
jmeter.properties 全局配置文件
docs 离线帮助文档,用于二次开发
exras 第三方插件集成
组件:
1.测试计划:容器。起点
2.线程组:一定用户。(测试片段)
3.配置元件: 配置信息
4.前置处理器:请求之前的操作
5.逻相控制器:单次请求,循环请求,判断请求
6.定时器:固定定时器,高斯,随机。
7.取样器: 请求。http,ftp,tcp,jdbc
8.后置处理器:请求之后的操作
9.断言:判断结果是否正确
10.监听器:收集测试结果
组件作用域:
1.兄弟(同级)组件
2.兄弟组件下的子组件
3.父组件
执行顺序:
测试计划》线程组》配置元件》前置处理器》定时器》逻辑控制器》取样器》后置处理器》断言》监 听器
九、使用Jmeter做接口测试
接口关联: 把上一个接口的返回值作为下一个接口的参数
后置处理器:(用组件之前可以先测试:在查看树中的RegExp Tester进行正则表达式测试)
1.正则表达式提取器(提取的值+左边界+右边界,原则是最小的唯一的值)
引用: ${token}
2.JSON提取器
$.tags[1].id
函数助手:
${__Random(100000,888888)} 生成6位数的随机数
${__Random_String(6,zxcvadfqwert)} 生成6位数的随机字符串
${__counter(true,)} 计数器每执行一次加一,从1开始
${__V} 执行一个带字符串变量名的表达式,即拼接
${__dateTimeConvert(,,,)} | 时间格式转换 |
---|---|
${__intSum(,,)} | 整数相加 |
${__P(,)} | 获取属性 |
${__setProperty(,,)} | 设置属性 |
${__time(,)} | 获取当前时间戳 |
批量删除
${_V(ids${__counter(true,)},)} 通过id进行批量删除,从1开始
计数器组件+${_V(ids${cs})} 通过id进行指定开始到结束批量删除
jmeter文件上传
文件名称:写文件路径名称
参数名称:写参数名
MIME类型:multipart/form-data
ter读取csv文件内容乱码解决
确保保存的csv文件为utf-8的格式
方法一:
修改jmeter.properties文件,(文件路径:jmeter安装位置\apache-jmeter\bin)sampleresult.default.encoding=UTF-8,把前面#去掉。
然后修改csv配置,动在jmeter上CSV里file encoding框里输入GBK或GB2312(支持中文简体)或者GB18030(支持简体和繁体)
再次运行,不会出现乱码现象。
方法二:
头部信息和默认值与下图配置一样,参数化那里写成gbk或者gb2312(前提是你请求参数中文乱码,如果请求参数没问题,用utf-8也行)
十、jmeter断言
1.状态断言, 200,能不能证明我的接口是返回正确的?
200只能代表接口有数据返回,但是不能代表返回的数据是对的。
响应文本:一般匹配json数据
响应代码:200
响应信息:OK
模式匹配模式:
包括:支持正则,与字符串一样
匹配:支持正则,与相等一样
相等:不支持正则,
字符串:不支持正则
2.业务断言,最核心的业务关键字
3.beanshell断言 重定向的接口。
一般数据库断言必用
主要是通过Failure来判断断言成功还是断言失败!
Failure=true;断言失败
Failure=false;断言成功
主要是通过FailureMessage来返回断言的信息
/先获取发帖接口的名字
String title =“码尚教育s{rn}”
log.info(title);
//获取数据库中的数据
String sub = vars.getObject(“result”) .get(0).get(“subject”);
log.info(sub);
if(title.equals(sub)){
Failure = false;
FailureMessage =“断言成功”;}
else{
Failure = true;
FailureMessage =”断言失败”;}
从一个页面到另一个页面有两种方式:
跳转:它会把这个页面的所有相关的数据带到下一个页面。
重定向:它不会吧这个页面的任何数据带到下一个页面。
自动重定向:a,d 跟随重定向:多次重定向的情况下,那么会吧所有重定向的页面全面显示出来。a,b,c,d
Jmeter执行数据库操作
应用场景:数据库断言
1.在测试计划中引入数据库的驱动文件
2.建立数据库连接池
3.发送JDBC数据库请求 Beanshell后置处理器加入如下代码获取数据库里面的值。
log.info("码尚教育百里老师真帅");
log.info(vars.getObject("result").get(0).get("username"));
log.info(vars.getObject("result").get(1).get("password"));
使用beanshell的场景:
1.数据库断言
2.接口加密(对称加密:AES,DES,BASE64 单向加密:MD5,SHA1—SHA256 非对称加密:RSA)
MD5加密:digest支持MD5,sha系列(除了sha3)
${_digest(MD5,admin…)}
${_digest(MD5,123..)}
Base64加密
方式一:${_base64Encode(123,)}
方式二
beanshell前置处理器:
import java.util.Base64;
//初始化一个Base64对象,调用encodeTostring()方法
String username = Base64.getEncoder(),encodeTostring(“admin”,getBytes(“UTF-8”));
String password = Base64.getEncoder(),encodeTostring(“123”getBytes(“UTF-8”));
vars.put(“us”,username);
vars.put(“pw”,password);
3.签名(混合加密和签名Sign) beanshell语言+java语言
十一、jmeter逻辑控制器
首先,我们先来看下,不勾选 “Interpret Condition as Variable Expression?”如何填写表达式。
根据上一段的意思 ,我们能发现,当不勾选后我们的表达式可以输入的更加直接,如1==1,1<=2,1!=2等,这里会判断是否成立,表达式不成立,则表示为false,不执行,反之,则执行里面内容。同时,表达式还可以将变量带入进去,如 ${__Random(1,10,)}<5 ,当随机数随到小于5的数就执行处理器下方的请求内容
其次 ,我们在来看下,勾选 “Interpret Condition as Variable Expression?”如何填写表达式。
我们知道勾选的作用是:
输⼊的条件表达式,不会使⽤JavaScript进⾏解析,⽽是将条件视为JMeter的变量。
如果需要进⾏条件判断,则需要使⽤__jexl3或者__groovy函数,来⽣成函数表达式。通过函数
如 ${__jexl3(${abcd}==“3”,)} 这里表达式的意思就是 当变量 adcd==3时,则输出true,表示执行表达式下的请求,反之则不请求,不只是“==”还可以用 <,>,<=,>=。等等的一些比较符,同时,还有一种写法,这种写法就是在表达式里用__groovy,如${__groovy (“${abcd}”==“3”,)},这个函数对比__jexl3函数来说,区别就是在使用__groovy函数时变量得用英语引号给括起来,其他的都是一样的
十二、Jmeter持续集成
应用场景:接口回归测试,多个测试人员实现版本控制。
全局配置: jmeter.propties
jmeter.save.saveservice.output_format=csv
jmeter.save.saveservice.response_data=true
jmeter.save.saveservice.samplerData=true
1、实现Jmeter的非GUI命令行运行。
-n 命令行模式执行
-t 制定Jmeter的jmx脚本文件的名称
-l 表示生成jtl报告名称
-e 生成HTML报告
-o 指定HTML报告路径(必须是一个空的文件夹)
jmeter -n -t test.jmx -l result.jtl -e -o results
Jmeter+Ant集成
1)下载ant并解压,解压后配置环境变量,把ant下的bin目录配置到path路径
D:\apache-ant-1.10.10\bin
2)配首build.xml
修改bulid.xml里面的四个位置
<!--需要调用的imeter目录,根据需要进行修改,本次使用的linux路径-->
<property name="jmeter .home" value="g:\apache-jmeter-5.2.1"/>
<property name="report.title" value="接门自动化测试"/>
<!-- jmeter生成jt1格式的结果报告的路径 -->
<property name="jmeter,result,jtl,dir" value-"E:\ants\jtl" />
<!-- jmeter生成html格式的结果报告的路径-->
<property name="jmeter.result.html.dir" value="B: ants html" />
<!--[详细报告] jmeter生成html格式的详细报告的路径-->
<property name-"jmeter.result,html,dirl" value-"report" />
<!-- 生成的报告的前缀-->
<property name="ReportName" value="接口自动化汇总报告" />
<property name="ReportName1" value="接口自动化详细报告"/>
<property name-"jmeter,result.jtlName" value-"$(jmeter,result,jtl.dir)/$(ReportName),jtl" />
<property name="jmeter,xesult.htmlName" value="$(jmeter,result.html,dix)/SReportName),html" />
<!--[详细报告]详细报告的文件名-->
<property name="jmeter.result.htmlNamel" value-"$(jmeter.result.html.dir1)/$(ReportNamel) .html" />
--------------------------------------------------
<!-- 该命令为执行命令-->
<target name-"test"><taskdef name-"jmeter" classname-"org.programerplanet, ant,taskdefs ,jmeter ,JMeterTask"<jmeter jmeterhome="$(jmeter.home)" resultlog="S(jmeter.result.jtlName)">
<!-- 声明要运行的脚本路径"*.jmx"指包含此目录下的所有jmeter脚本-->
<testplans dir="E:\ants" includes-"*jmx"/><property name="jmeter,save,saveservice,output format" value="xml"/></jmeter></target>
3.配置库JMeter的插件文件
把这个文件jmeter.results.shanhe.me.xsl拷贝到jmeter扩展文件夹extras里面
把extras里面的ant-jmeter-1.1.1.ar拷贝到an的lib目录下
4.直接通过ant命令执行脚本生成html报告
ant
十三、jmeter录制
添加http代理服务器-》控制面板->Internet选项->连接局域网设置上代理输入jmeter所在电脑的ip和8888端口(用完还原)-》目标控制器,Type(httpClent4,java)默认-》filter配置(排除模式:添加建议排除:后面添加.*)包含模式:添加录制的主机ip(.ip地址.)
十四、jmeter插件安装使用
1.下载一个插件管理包jmeter-plugins-manager版本jar,放到jmeter的lib/ext目录下重启jmeter,那么就有了插件管理
监控图的作用主要是:
1.看趋势,找性能拐点
2.写性能测试报告