1.接口
概念
接口就是数据交互的通道,在系统或组件之间,完成数据的传递。
类型
1.按照协议划分,协议不同,接口类型不同。HTTP、TCP、UDP、IP、FTP、USB...
2.按语言划分,Java、c++、python...
3.按范围划分,系统之间和程序内部。
系统之间:内部系统之间 和 内部系统与外部系统之间
程序内部:方法(函数)和方法(函数)之间,类和类之间,模块和模块之间。
2.接口测试
测试系统或组件之间交互数据的正确性,以及逻辑依赖关系的正确性。
原理
模拟客户端向服务器端发送请求,服务器接受请求后进行相应的业务处理,并向客户端返回响应数据,检查响应数据是否符合预期。
数据(预期结果)从哪来:根据用户需求来
怎样校验:借助工具或代码模拟客户端,不一定需要前端界面。
特点
1.提早介入,符合测试的质量控制迁移原则
2.接口测试可以发现页面操作发现不了的问题,如支付密码输入非数字字符或特殊字符
3.低成本高收益,接口的一个bug可能对应上册界面n个bug
4.接口测试不同于传统的单元测试,站在用户的角度展开测试
实现方式
工具实现:postman、jmeter、fiddler
代码实现:python+unitTest+requests
自动化接口测试
利用工具或代码代替人工自动判断响应结果和预期结果是否一致,依赖断言。
3.HTTP协议
协议:就是规则,要求协议的双方必须严格遵守
HTTP:超文本传输协议,基于请求、响应的应用层协议,目前互联网广泛使用的协议。
特点
1、支持客户端/服务器模式
2、简单快速(数据可以在url中携带传递)
3、灵活(支持的语法格式比较多)
4、无连接
5、无状态
URL
统一资源定位符,标识互联网上一个具体的资源(页面、图片),HTTP使用URL来建立连接传输数据。
语法格式
协议:http和https
域名:本质IP地址(定位网络环境中的一台主机)
端口号:在主机上定位一个应用,没有指定的话,默认跟随http默认端口号(80),https默认端口443,MySQL3306,redis6379
资源路径:对应网页的源代码或网络中的一个数字资源(图片)
资源路径可以为空,如有查询参数,则资源路径为?之前域名(端口号)之后的内容。如果没有查询参数,则一直到末尾都是资源路径。
查询参数:传参给网页源代码。
以?与资源路径隔分、多个查询参数用&隔分、参数语法k=v形式
HTTP请求
作用:1、由客户端发送给服务器2、规定发送给服务器的数据的语法格式
整体格式:请求行、请求头、空行、请求体
fiddler抓包验证
请求行
作用:指定请求方法和请求资源
请求方法:GET(查询),没有请求体
POST(新增),适用登录注册,有请求体
PUT(修改),有请求体
DELETE(删除),没有请求体
协议版本:http1.1(主要使用)、http1.2、http2.0
请求头
向服务器描述客户端(浏览器)的基本信息
格式:K:V
User-Agent:向服务器描述浏览器的类型
Content-Type:向服务器描述请求体的数据类型(form、json)
请求体
POST和PUT有请求体
请求体的数据类型受请求头中Content-Type的值的影响
4.HTTP响应
作用:由服务器发送给客户端、规定了服务器回发给客户端的 数据的 语法格式
格式:响应行(状态行)、响应头、空行、响应体
状态码:
响应头
向客户端(浏览器)描述服务器的基本信息
格式:K:V
Content-Type:向客户端描述响应体的数据类型(html、json、form、image)
响应体
http响应报文,大多数是有响应体的、响应体的数据类型受Content-Type的影响
5.传统风格接口
- 使用GET、POST完成所有数据的增删改查
- 针对用户的某一个操作,URL不唯一
- 状态码统一使用200(不管是否成功)
优点:对开发技术要求低、代码实现灵活
6.RESTful风格的接口
一种设计风格,只是提供一组设计原则和约束条件
- 使用GET、POST、PUT、DELETE实现增删改查
- 使用一个URL对应唯一一个资源
- 状态码一般根据实际操作情况加以区分
如何鉴定是否是RESTful接口?
1、使用GET、POST、PUT、DELETE实现增删改查
2、数据资源的定位符是否唯一
3、在URL中不使用动词,而替换使用名词(比如不使用 “添加add、删除delete、修改modify”,而都使用users,依据请求方法来界定操作),此条不是特别重要。
7.接口测试流程
1.结合需求文档,进行需求分析
2.结合开发提供的接口文档,进行接口分析
3.出具接口测试用例(送审)
4.执行接口测试用例
用例:postman、fiddler、jmeter
代码:python+UnitTest+requests
5.缺项管理与跟踪
6.生成测试报告
7.接口自动化持续集成(可选)
8.接口文档
又称为API文档,描述接口相关信息的文档,一般由开发人员编写。
作用
- 方便前端开发人员和后端开发人员在开发时对接
- 在人员更迭时,能方便新入职的员工快速接手项目
- 方便测试人员编写接口测试用例
展现形式
在线文档:html
离线文档:xmind、word、pdf、excel
结构
基本信息:
接口描述
URL:(协议+域名)+资源路径
请求方法
请求参数:
请求头
请求体(GET、DELETE没有)
返回结果:
状态码、状态描述
响应体
9.接口文档解析
以登录接口为例:
http请求:
- 请求行:
- 请求方法:POST
- URL:http://ihrm-test.itheima.net/api/sys/login
- 协议版本(默认HTTP1.1)
- 请求头:Content-Type:application/json
- 请求体:{"mobile": "xxx","password": "xxxx"}
http应答:
- 响应行:状态码、状态描述:200 OK
- 响应头:无
- 响应体:
以员工修改接口为例:
http请求:
- 请求行:
- 请求方法:PUT
- URL:http://ihrm-test.itheima.net/api/sys/user/:target
- 协议版本(默认HTTP1.1)
- 请求头:Content-Type:application/json、Authorization:xxxxxxxxxxxxxxxxxxx
- 请求体:{"username": "xxx","password": "xxxx","departmentId": "xxx"}
http应答:
- 响应行:状态码、状态描述:200 OK
- 响应头:无
- 响应体:
10.接口用例设计
为什么要写接口用例?
1.防止漏测
2.管理工作进度,评估工作量
3.面试
接口测试的测试点
功能测试
单接口功能测试:手工测试中的单个业务模块,一般对应一个接口。如登录业务对应一个登录接口,加入购物车业务对应一个加入购物车接口,订单业务对应一个订单接口。借助工具或代码组织接口所需要的数据,展开测试,绕开前端。
业务场景功能测试:按照用户实际使用场景,梳理接口业务场景。组织业务场景时只需做正向测试即可。一般建议用最少的用例覆盖最多的业务场景,如登录->搜索商品->加购物车->下单->支付->评价。
性能测试
- 响应时长:从发出请求,到服务器回发响应,所经历的时长
- 吞吐量:TPS(单位时间事务数),如1s内,接口所能处理的 请求数量
- 并发数:同一时间,同时向服务器的接口发送请求,所能正确处理的数量
- 服务器资源利用率:接口工作中,服务器硬件资源使用占比情况
安全测试
攻击安全:由专业安全测试工程师完成
业务安全:敏感数据是否加密(密码、身份证)、SQL注入(在用户输入数据的位置,写入SQL语句,测试是否能得到数据库的查询结果)。
设计方法与思路
与手工设计相同之处
接口用例设计的 测试点,与手工页面 业务功能的 测试点 几乎完全一样
手工功能用例设计要点:
1、测试布局 、控件的位置是否精准
2、针对用户名的编辑框中的数据值,展开测试
正向:正确手机号
反向:手机号位数非11位、手机号不是纯数字、手机号为空
3、针对密码编辑框中测试:展开测试
正向:正确密码
反向:错误密码、密码为空、密码格式不正确、密码长度不正确
4、针对验证码编辑框,展开测试
正向:正确验证码
逆向:错误验证码、过期验证码、验证码为空
接口用例设计要点:
1、手工页面中的用户名编辑框,对应接口中key为username的value值,所以要针对username的值展开测试
正向:正确手机号
反向:手机号位数非11位、手机号不是纯数字、手机号为空
2、手工页面的密码编辑框,对应接口中key为password的value值,所以要针对password的值展开测试
正向:正确密码
反向:错误密码、密码为空、密码格式不正确、密码长度不正确
3、手工页面的验证码编辑框,对应接口中key为verify_code的value值,所以要针对verify_code的值展开测试
正向:正确验证码
逆向:错误验证码、过期验证码、验证码为空
与手工设计不同之处
1、手工数据测 输入框中的数据是否正确,而接口测试测 参数对应的参数值 是否正确
2、接口测试不止对参数值进行测试,还可以对 参数本身 进行测试,以添加员工为例
正向参数:
必选参数:所有的必选都包含
组合参数:所有的必选+任意一个或多个可选参数
全部参数:所有的必选+所有的可选
反向参数:
多参:多出一个或多个必选参数(可以任意指定)
少参:缺少一个或多个必选参数
无参:没有参数
错误参数:参数名错误
单接口测试用例
- 编号、标题、用例名称、优先级、预置条件、接口名称、测试方法、URL、请求头、请求体(请求数据)、预期结果
以登录接口为例
数值正向:
登录成功
数值反向:
手机号为空
手机号有特殊字符
手机号不足11位
手机号超出11位
手机号未注册
密码错误
密码为空
密码有特殊字符
密码1位
密码100位
参数正向:
必选参数(组合参数)
参数反向:
多参
少参
无参
错误参数
业务场景测试用例
分析测试点
- 业务场景尽量遵循用户实际使用场景,按顺序调用接口进行测试
- 尽量使用最少的测试用例,覆盖最多的业务场景
登录成功--添加员工--查询员工--修改员工--查询员工--删除员工--查询员工列表
- 一般情况下,只需要测试 正向 的业务场景即可
依赖关系:
1、登录成功返回的“令牌”,被添加 、查询、修改、删除所依赖。
2、添加员工成功,返回 员工id,这个id被查询、修改、删除所依赖。
11.Postman断言
断言:让程序判断预期结果和实际结果是否一致
- 利用postman自带的断言机制,帮助我们自动判断 预期结果和实际结果 是否一致
- 使用的是JavaScript脚本语言,写在tests标签页中。在TestResult标签中显示。
1、断言响应状态码 Status code is 200
//断言响应状态码为200
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
//pm代表postman的一个实例
//test()代表postman实例的一个方法,有两个参数:
// 参数一:"Status code is 200"断言完成后,给出的提示信息
// 参数二:function () {pm.response.to.have.status(200);}代表匿名函数调用,函数调用的结果会传进去
// pm.response.to.have.status(200);代表postman的响应结果中有状态码200
2、断言响应体是否包含某个字符串 Contains string
//断言响应体中包含xxx字符串
pm.test("Body matches string", function () {
pm.expect(pm.response.text()).to.include("xxx");
});
//"Body matches string"断言完成后给出的提示信息
//pm.expect(pm.response.text()).to.include("xxx")postman实例预期结果中包含"xxx"字符串
3、断言响应体是否等于某个字符串(对象)is equal to a string
//断言响应体等于某个字符串(对象)
//断言响应体等于某个字符串(对象)
pm.test("Body is correct", function () {
pm.response.to.have.body({
"success": true,
"code": 10000,
"message": "操作成功!",
"data": "644a7aef-4c89-4a07-a1b7-8b10bdf0458c"
});
});
//pm.response.to.have.body({
// "success": true,
// "code": 10000,
// "message": "操作成功!",
// "data": "644a7aef-4c89-4a07-a1b7-8b10bdf0458c"
//});
//代表postman的响应结果中有响应体为{
// "success": true,
// "code": 10000,
// "message": "操作成功!",
// "data": "644a7aef-4c89-4a07-a1b7-8b10bdf0458c"
//});
4、断言JSON数据--JSON value check
//断言响应体中的JSON数据
pm.test("Your test name", function () {
var jsonData = pm.response.json();//变量jsonData的值为json格式的响应体数据
pm.expect(jsonData.value).to.eql(100);//jsonData.value指代key,to.eql指代key对应的value
});
5、断言响应头--Content-Type header check
//断言响应头中Content-Type
pm.test("Content-Type is present", function () {
pm.response.to.have.header("Content-Type");//响应结果中响应头有Content-Type
});
6、工作原理
12.全局变量和环境变量
//设置
pm.globals.set("全局变量名",全局变量值);
//界面获取
语法:{{全局变量名}}
用在:查询参数、请求头、请求体
//代码获取
var 接收变量名 = pm.globals.get("全局变量名");
//设置
pm.environment.set("环境变量名",环境变量值);
//界面获取
语法:{{环境变量名}}
用在:查询参数、请求头、请求体
//代码获取
var 接收变量名 = pm.environment.get("环境变量名");
13.Postman请求前置脚本
时间戳:表示当前系统时间,从1970.1.1 00:00:00~现在所经历的秒数
请求前置脚本(pre-request):在HTTP请求发送之前会自动执行里面的代码
ex:调用百度首页接口,传时间戳给服务器
1、创建”请求前置脚本“用例集和http请求页
2、指定请求方法GET,URL:http://www.baidu.com
3、在script->pre equest写入代码,获取时间戳,写入到全局代码中
//获取时间戳
var timestamp = new Date().getTime()
//将时间戳保存在全局变量中
pm.globals.set("glo_timestamp",timestamp)
4、点击send按钮,促使标签页代码自动执行,点击右上角小眼睛图标,查看Globals中多出一个全局变量
5、在URL中借助查询参数,使用全局变量。点击send按钮,发送带有时间戳的请求
6、在view->postman console中查看
工作原理
14.Postman关联
当请求之间有依赖关系,比如一个请求的入参是另一个请求返回的数据,这时候需要借助全局变量、环境变量来解决接口之间的依赖关系
实现步骤:
以A接口 返回的数据,供B接口使用为例:
1、组织A接口http请求数据,发送A接口请求
2、获取A接口返回的响应数据,写入全局、环境变量中
3、组织B接口的http请求,从全局、环境变量中获取 A返回的数据
ex-1:请求 获取天气接口,提取响应结果中的城市,将城市名给百度接口使用。
1、创建”请求前置脚本“用例集和http请求两个页
2、组织A接口请求方法、URL,发送http请求
3、获取响应结果中的json数据,从数据中提取城市名,保存到全局变量中
//获取响应数据
var jsonData = pm.response.json();
//获取城市名
var city = jsonData.weatherinfo.city
//写入全局变量中
pm.globals.set("g_city",city)
4、点击右上角小眼睛图标,查看Globals中多出一个全局变量
5、组织B接口请求方法、URL,发送http请求
6、在B接口的查询参数中,指定使用全局变量{{g_city}}
7、在view->postman console中查看
ex-2:实现添加员工接口,依赖登录(使用环境变量)
1、创建环境
2、登录接口,存储令牌到环境变量中
//获取json响应结果
var jsonData = pm.response.json();
//获取令牌数据
var token = jsonData.data
//将令牌写入到环境变量中
pm.environment.set("env_token",token)
3、添加员工接口,获取环境变量令牌
15.Postman参数化
参数化:将http请求需要的数据、断言,组织到一个文件当中,从postman导入文件中,可以实现http请求发送、断言。
应用场景:针对同一个接口,组织 n条 不同的测试用例,数据格式完全相同。
数据文件简介
CSV :
- 优点:数据组织的格式简单
- 缺点:不支持布尔类型(原因:postman读取csv文件后,将所有的非数值数据自动添加""包裹,变成了字符串类型)
- 不支持复杂数据类型(字典、列表)
- 不支持参数测试
- 应用场景:当有大量测试数据时,适用
JSON :
- 优点:支持布尔类型、复杂数据类型、参数测试
- 缺点:相同的数据量,json文件远大于csv文件
- 应用场景:测试数据量较少(几百条),需要进行参数测试
编写数据文件
1、CSV在记事本编写
username,pwd,msg
13209098989,123456,登录成功
18909093443,123456,密码错误
15954540909,123456,账号不存在
编写完成后重命名文件为.csv格式,然后使用postman,导入文件,点击preview查看是否正确
2、JSON
同样,使用postman,导入文件,点击preview查看是否正确
读取数据文件数据
根据使用位置不同,有两种方法
第一张:请求参数(请求行、请求头、请求体)中,使用数据文件中的数据
使用{{}}包裹csv文件第一行的字段名,或json文件的key名
第二种:代码script中,使用数据文件中的数据
使用postman内置关键字pm.iterationData.csv文件的字段名 或 pm.iterationData.json文件的key名
ex:批量查询手机号所属运营商,体验运营商数据准确性
接口:http://cx.shouji.360.cn/phonearea.php?number=13209098989
测试数据:
手机号:
运营商:联通
手机号:18909093443 运营商:电信
手机号: 15954540909 运营商:移动
tel,sp
13209098989,联通
18909093443,电信
15954540909,移动 csv文件
将eql(data.sp)修改为eql(pm.iterationData.sp);data已经被弃用
批量执行用例集
1、点击用例集名称,选择run按钮,进入Runner标签页中
2、在Runner标签页中 用例集内的所有 请求页会被默认自动选中,导入csv文件
3、点击Run xxxxx按钮,批量执行用例集
16.Postman测试报告
使用Newman
newman run 测试用例集名.json -e 环境变量文件 -d 数据文件 -r html --reporter-html-export 测试报告名称.html
-e 环境变量文件 -d 数据文件非必须
如果添加 -r html参数后,执行命令报错,是因为没有安装newman-reporter-html
步骤:
1、导出用例集(建议创建空目录存储用例集,层级不要太深)
2、导出环境文件
3、在用例集所在目录地址栏输入cmd打开终端
4、键入命令,生成测试报告
持续更新中,见下篇----------------------------------------------------------------------------------------------------