目录
一、读懂Restful API接口文档
BaseUrl
一个完整的接口URL是由baseurl+接口相对url组成.
例:Baseurl: https://xscs.com/
用处:
- 指明接口所在的服务器
- 切换接口所在的服务器
- 修改和迁移接口的完整URL
Endpoint
Endpoint=method+url(一个接口地址),类似抓包的请求头数据
get /todo
post /todo
参数对象
request: 请求行、请求头、正文。最重要的是清楚参数在什么位置。
如:path:在请求行;header在请求头;cookie参数在请求头
正文对象
正文对象是多个参数的集合,放在http请求正文中。
类型:
- application/json
- application/xml
- application/x-www-form-urlencoded(表单)
- multipart/form-data(上传文件的表单)
例:
鉴权方式
鉴权,通过一种方式证明身份。
OSA中的鉴权方式:
- api-key:应用程序编程接口密钥。在请求中添加指定字符串(由api提供者颁发给开发者或应用程序的唯一字符串)
- http:在请求头加上身份凭据,如cookies、token
二、requests基本用法
request : 请求
requests : HTTP Client
优势:
- 提供便捷的发送http请求的api
- 支持自动重定向
- 支持session机制(让多个请求使用同一个身份发送请求)
- 支持代理设置
- 支持鉴权
- 支持自定义请求设置
不支持异步请求,不支持HTTP2
aiohttp:
- 原生支持异步,并发性能非常优秀
- 支持httpclient 和http server
httpx:
httpx python接口框架自测用的client
优势:
- 提供类似requests便捷api和功能
- 支持异步
- 支持请求WSGI \ ASGI(python web 框架使用的接口)
- 支持http 2
常用的http方法:
- post: 用于提交数据,通常会导致服务器状态改变或其他的副作用
- get : 请求数据,通常指用于获取数据
- head:请求一个和get相同的响应,但是没有响应正文
- put :使用请求正文中的数据,替换掉目标资源的数据
- pacth :使用请求正文中的数据,对目标资源进行局部修改
- delete :删除指定资源
- options : 查询目标资源支持的选项
options 请求就是预检请求(preflight request),可用于检测服务器允许的 http 方法。当发起跨域请求时,由于安全原因,触发一定条件时浏览器会在正式请求之前自动先发起 OPTIONS 请求,即 CORS 预检请求,服务器若接受该跨域请求,浏览器才继续发起正式请求。
上传文件
上传文件:
1、将文件二进制内容放在body中,服务端读取body即可得到文件内容
2、使用表单进行文件上传,在body传递文件名,文件内容,文件类型等信息,可以同时上传多个文件
使用data发送正文;自定义请求头:content-type:application/octet-stream
with open ("test.txt","rb") as f:
data=f.read() #一次性将文件内容全部读取
headers={"content-type":"application/octet-stream"}
req=requests.post("url",headers=headers,data=data)
f=open("test.txt","rb")
headers={"content-type":"application/octet-stream"}
req=requests.post("url",headers=headers,data=f) #文件内容读一点,输出一点
使用表单上传文件
表单结构是一个K-V,所以表单发送文件也需要构造字典,通过files参数传递给requests
field_name:file
file的多种写法:
- fileobj
- {“file_name”:“file_content”}
- {“file_name”:“file_content” , “content_type”}
之所以有多种写法是以为fileobj可以在文件对象中字典获取文件的名字、内容等信息
标准写法:
f=open("test.txt","rb")
req=requests.post(url,files={'file':f})
三、Requests核心组件
API
API组件总结:
1、requests.get()\post()函数都是调用了requests.request(),区别仅仅是使用的HTTP client方法不同。
2、requests.request()做了以下事情:
- 创建session实例
- 使用session发送请求
- 返回session获得响应
request
Request对象是对HTTP请求报文的封装,通过设置和读取request属性,实现了对http请求报文的读取和修改。
发送post请求,需要根据请求正文的长度,来决定请求头content-length的值
常用属性:
response
response对象是对http响应报文的封装,通过设置和读取response属性,实现了对http响应报文的读取和修改。
响应作为一个结果,应该是不可修改的。但是有一个例外:encoding
常用属性:
Session
session:会话,用来表示有同一个用户发送多个请求之间的关系。一个session对应多个请求.
Session对象是网络请求实际操作角色:
1.建立网络连接,传输http报文
2.对发送报文前,对数据进行处理
通过对session属性的读取和设置,对网络请求的设置,同时实现对request的设置。
常用属性:
由一个session发送的多个请求,具备共同点:
- 相同的默认参数
- 复用tcp连接
- 自动的合并cookies(一个会话中,多个请求会自动处理身份验证)
改进session
结合接口自动化测试实际情况,进行http请求的时候,有以下特点:
1、由于一般项目中会有:测试环境、生产环境、开发环境,一般都是BaseUrl不一样,其他都一样。所以一般会将该值设置为全局变量,变更时便于环境切换。
2、请求频繁,host基本固定
3、记录http原始报文(请求+响应报文)
4、restful api一般使用固定格式的正文
5、mock需求,等等
支持BaseUrl
开发环境、测试环境、线上环境,仅仅host不同,path等其他参数都一样。
- 最好不要在用例中拼接url
- 不建议手动切换环境
四、支持mock接口
由第三方库request-mock来实现。就是还未开发的接口,可以通过设定理想值,来达到目的。
重学!!还不太懂
在实际项目中,一般只测试核心的接口,
五、如何做接口测试—项目实战
这里主要简单讲一下接口用例的调试,将接口调试完成,导入到httprunner中执行。
需要准备的资料:接口文档
工具:httprunner、har2tavern、python3.6.8
1、熟悉项目
1、了解业务功能,核心功能等接口信息。
2、测试接口还是测业务:
- 新功能接口测试
- 旧功能测试业务
接口文档不规范:
- 让开发改
- 自己维护一份正确的版本
接口文档不清楚:
- 向开发反馈,调整文档内容
- 让开发给出请求示例
如何测试匿名接口:
- 先抓包,再重放
2、接口初探
先将所有的接口粗略跑一边看下是否能跑通过。
小技巧:
一共有2种将接口文档转换为在线restful文件的方式:
1.通过swagger工具将接口文档转换为在线的restful格式。在线工具链接
2.访问接口文件,通过开发者工具抓包获取api-docs文件,再通过swagger接口将需要测试接口的json文档转换为标准的restful风格形式。 https://editor.swagger.io/?_ga=2.95662367.2091464379.1686450256-777026941.1686450255
操作步骤:
- 1.通过浏览器的开发者工具查看接口文档的请求信息
- 2.在vs code中新建一个json文件,将api-docs的内容copy到里面
- 3.通过代码访问接口,看接口是否可以跑通。一般像500这种接口就是坏了的接口。
代码如下:
import json
import requests
session=requests.Session()
with open("ApiInfo.json",encoding="utf-8") as f:
info=json.loads(f.read())
host=info['host']
basePath=info['basePath']
BaseUrl="http://"+host+basePath
# print(BaseUrl)
# 将所有的接口请求一次,尝试找出坏(未实现,信息不全等)的接口
for path in info['paths']:
for method in info['paths'][path]:
# print(method,path)
url=BaseUrl+path
req=session.request(method,url)
print(req.status_code,req.text,url)
结果如下:
3、首先测试匿名接口(针对web项目)
1.业务逻辑简单的,不需要关联的
2.数量多,不需要研究接口文档
步骤:
1、抓包(以fiddler为例)
- 配置代理
- 配置证书
- 筛选接口内容(不登录的情况下,跑一下系统的功能)
- 保存抓包内容到xxx.har文件(fiddler选择export session—>all session—>选择文件类型为HTTPArchive V1.1保存)
2、生成用例(以tavern为例),tavern会自动将har文件内容生成一个个yaml文件,一个文件就是一个用例,通过pytest可以自动执行。
- ①pip install har2tavern(pytest\tavern\requests\har2tavern)
- ②har2tavern转换yaml文件:har2case xx.har -2y
-2y表示yaml格式 - ③pytest
3、更新用例
如果接口发生变化
1.修改用例文件的内容
2.修改内容过多的话,重新录制har文件
手动?自动?
自动的方法:通过playwright使用devtools控制浏览器
- 自动操作元素,使接口得到访问
- 将接口请求记录下拉导出har文件
- 生成用例并执行
解决自动登录问题的方法:
- 1.开启万能验证码、自动获取验证码
- 2.拿到获取验证码的接口
- 3.拿到获取token的接口
4、梳理业务和接口之间的关系
去了解各个接口之间的返回信息,接口之间的关系。返回接口之间的关联等等。
5、写代码测试
6、一个真实的bug
修改请求头像,接口可以跑通,但是通过UI操作无法跑通。
1.首先通过接口测试,可以跑通,证明后端可能没问题
2.mock一个存在的图片,看是否成功
3.检查接口文档和实际前端的接口的url是否一致,可以通过浏览器的开发者工具结合查看。
简化步骤
1、fiddler抓包har接口文件;
2、将har转换为yaml文件;
3、在yaml文件,结合浏览器的开发者模式抓包查看各个接口之前的参数关联关系,通过动态获取;
4、修改完各个接口之后,本地调试看是否接口都能通过: hrun xxx.yaml 查看生成的报告结果,若还有失败的,就一直循环调试直到pass为止!
接口自动化深入了解见:点我