接口测试
1、概念
测试系统组件间接口的一种测试,重点关注数据传递。
一般用于多系统间交互开发,或者拥有多个子系统的应用系统开发的测试。
2、REST
Representational State Transfer,一种软件架构风格,可以降低开发的复杂性,提高系统的可伸缩性。
最早是由Roy Fielding博士发表的论文中提到的,一种分布式系统的应用层解决方案。可以让Client端和Server端进一步解耦。
- POST:创建资源
- GET:获取资源
- PUT:更新资源
- DELETE:删除资源
幂等性(Idempotent):是一个数学上的概念,在这里表示发送一次和多次请求引起的边界效应是一致的(POST不是幂等方法)。
安全性:GET、HEAD和OPTIONS均被认为是安全的方法,因为它们都是对数据的获取,不存在“边界效应(Side Effect)”。
设计规范:
- 协议:使用HTTPS协议,确保交互数据的安全传输
- 域名:应该尽量将API部署在专用域名下面(
https://api.example.com
) - 版本控制:将版本号放在URL或者Header中
- 路径:只能包含名词,而不能包含动词
- 过滤信息:
?limit=10
?offset=10
?page=1
?sortby=name
- Hypermedia API:在返回结果中提供相关资源的链接,连接其他API方法
- 验证(Authentication):确定用户是其声明的身份,比如提供账户的密码
- 授权(Authorization):保证用户有对请求资源特定操作的权限。比如用户的私人信息只能自己能访问,其他人无法查看。
HTTP状态码:
- 200(OK):如现有资源已经被修改
- 201(Created):如新资源被创建
- 202(Accepted):如已接受处理请求但尚未完成(异步处理)
- 301(Moved Permanently):资源的URI被更新
- 400(Bad Request):非法请求参数
- 404(Not Found):资源不存在
- 406(Not Acceptable):服务端不支持所需表示
- 415(Unsupported Media Type):不支持的媒体类型
- 500(Internal Server Error):服务器内部错误
- 503(Service Unavailable):当前服务无法处理请求
返回结果设计
{
"message": "uri_not_found",
"code": 10001,
“request": "GET /api/example/v2/photo/123"
}
通用的错误码
- GET /class:列出所有班级
- POST /class:新建一个班级
- GET /class/ID:获取某个班级
- PUT /class/ID:更新某个班级
- DELETE /class/ID:删除某个班级
- GET /class/ID/student:获取某个班级里的所有学生
- GET /class/ID/student/ID:获取某个班级里的某个学生
3、功能测试
(1)测试覆盖
- 业务流程
- 边界值,特殊字符
- 参数类型,必选项、可选项等
- 并发数
- 吞吐量,TPS
- 出错率
- 敏感数据加密
- 恶意攻击等
(2)测试步骤
- 了解接口格式
- 编写测试用例
- 测试用例评审
- 开始测试
- 完成测试报告
(3)Postman
https://www.getpostman.com/
是由Google开发的一款页面调试与发送网页HTTP请求,并且能运行测试用例的Chrome插件。
HTTP Header:
-
Accept:指定客户端能够接收的内容类型
-
Content-Type:指定服务端所返回的MIME类型
application/x-www-form-urlencoded(默认),Key-Value键值对
application/json:JSON格式
multipart/form-data:(上传)二进制数据格式
-
Accept-Charset:浏览器可以接受的字符编码集
-
Authorization:HTTP授权的证书
-
Referer:由哪个网页(上一个)请求过来的
Test Results:测试用例
tests["http status code is 200"] = responseCode.code === 200;
tests["response body has id"] = responseBody.has("id");
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});
pm.test("Response time is less than 300ms", function () {
pm.expect(pm.response.responseTime).to.be.below(300);
});
4、示例
(1)GET请求1
GET /api/user
Header:Content-Type=application/json
Body:空
Response:所有用户信息
Status code:200
正向用例:返回所有信息
负向用例:
- 一个不存在的id
- URL输入不正确
(2)GET请求2
GET /api/user/{id}
Header:Content-Type=application/json
Body:空
Response:指定ID的用户信息
Status code:200
错误返回:Code-4,Message-找不到指定id信息
正向用例:返回某个信息
负向用例:
- 一个不存在的id
- URL输入不正确
(3)POST请求
POST /api/user
Header:Content-Type=application/json
Body:name(字符类型,不能为空、不能重复),age(数值类型,0~100之间),salary(浮点类型,不传默认为0)
Response:保存的用户信息
Status code:201
错误返回:
Code-5,Message-对象已经存在
Code-6,Message-参数不匹配
正向用例:输入正确参数,新增一条信息
负向用例:
- 参数name为空/重复
- 参数age为0/-1/100/101/字符串/null/空
- 参数salary为整数/带小数/负数/null/空
(4)PUT请求
PUT /api/user/{id}
Header:Content-Type=application/json
Body:name(字符类型,不能为空、不能重复),age(数值类型,0~100之间),salary(浮点类型,不传默认为0)
Response:更新指定ID的用户信息
Status code:200
正向用例:输入正确参数,修改一条信息(特殊字符,中文等)
负向用例:
-
参数id为空/无效值
-
参数name为空/重复
-
参数age为0/-1/100/101/字符串/null/空
-
参数salary为整数/带小数/负数/null/空
(5)DELETE请求1
DELETE /api/user/{id}
Header:Content-Type=application/json
Body:空
Response:删除指定ID的用户信息
Status code:204(成功状态响应码,表示该请求已经成功了,但是客户端客户不需要离开当前页面。)
正向用例:删除某个信息
负向用例:
- 一个不存在的id
- URL输入不正确
(6)DELETE请求2
DELETE /api/user
Header:Content-Type=application/json
Body:空
Response:删除所有用户信息
Status code:204(成功状态响应码,表示该请求已经成功了,但是客户端客户不需要离开当前页面。)
正向用例:删除所有信息
负向用例:
- 一个不存在的id
- URL输入不正确