前言:
最近一段时间在公司使用 Pytest+Allure+Request 实现了一套接口自动化项目,特意来总结和分享一下。
为什么选择这一套技术呢?
1. 之前是用java进行测试开发的,python不是很熟悉,网上随便搜的...
2. pytest有点类似java的testng, Allure的源代码就是Java(其实用到后面会发现目前对Python的支持不是很好), Request是最简单的python发送http/https请求的方式了
3. Allure 报告可以直接挂载到Jenkins 上展示,可以很好的完成CI/CD流程,也可以自动发送邮件,这个在一定程度上解决了项目上下游生态的问题。
接口自动化的第一个难点:
做过的都知道, 几乎所有的接口都需要鉴权的,然后你可能遇到的问题是:
1. 如何用request 获取登录cookie
2. 如果登录后使用的cookie还是无法访问怎么办?
3. 有些项目是单点登录的,登录情况复杂,等等
4. 目前很多后端开发也不知道怎么获取cookie,可能很多情况需要测试自己去摸索。
一些总结:
-------------------------------------------------------------------------------------------------------------
- 登录密码混淆, 单点登录, 登录需要签名,签名使用了base64, sha256等加密方式
- request获取cookie的方式有很多种,这个百度就行,这里暂且不提,我使用的是request.session()
session_test = requests.session()
session_test.post(login_url, parm, headers=header, verify=False)
- 获取cookie的时候,你的请求Headers 里面一定要加上(User-Agent):
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"
4. 单点登录的情况,在登录之后,一定要再去访问一下它发生跳转的那条URL,这点非常重要,否则你的cookie不全
【推荐一种方式是使用抓包工具将登陆过程录制下来,去找那一条授权的URL,这里我后续会推荐一个插件】
5. 签名使用sha256加密的,需特别注意py3 和py2的区别,同样的代码py3加载出来的值可能完全不同,这个需要自行调试。
# 提供一种方式进行编解码,重点是hmac方法里面调用需要bytes 格式, base64编码需要bytes, 另外就是针对开发的方式调整位数,py3解出来的格式是 u'XXXX', py2直接是 xxxx
def decode(key, content): h = hmac.new( bytes(base64.urlsafe_b64decode(key)), bytes(content.encode('utf-8')), 'SHA256' ).digest() temp = str(base64.urlsafe_b64encode(bytes(h))) signature = temp[2:-1] print("sign: ", signature) return signature
是否需要封装请求方式Request?
拿到项目的cookies之后,很多人其实会去做一个请求方式的封装,其实做过系统项目的都知道,方法进行封装会一定程度上提升编码效率,而且也好管理,这里我给出一个建议
1. 如果你所测试的项目是单一的,登录入口唯一, 接口返回都是json格式(或者后端统一了格式)。 完全推荐封装request.post /request.get等方法
2. 如果你所测试的项目包含多个项目,或者跨项目的流程测试(一条接口用例可能需要登录3个平台),接口返回的数据格式未必标准化, 这种情况下,封装的收益就非常低,不建议封装。
可能遇到的问题:
1. 由于登录的session过多,跳转也多, request 抛出:
"requests.exceptions.TooManyRedirects: Exceeded 30 redirects" 错误提示是requests库有太多的重定向:超过了30个重定向。
如果你去百度,答案基本是抄的,就是提醒你 在请求的时候加上: allow_redirects=False
这样做的后果是你关闭了session的重定向功能,如果请求里面有重定向,那么可能访问不了, 我的建议是直接修改Request 库源代码的重定向值,我就改成了100
2. 访问https 链接时, 返回404/403 ,请求的时候加上: verify=False
3. 打印返回,要使用 response.text