今天呢我们就来聊聊接口自动化测试之token关联登录,在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录。
这其实就是状态或会话保持的第三种方式token。

token 由服务端产生,是客户端用于请求的身份令牌。第一次登录成功时,服务端会生成一个包含用户信息的加密字符串token,返回给客户端并保存在本地,后续客户端只需要带上token进行请求即可,无需带上用户名密码。
token原理简单概括如下:
公司某管理后台系统,登录后返回token,接着去请求其他接口时请求头中都需要加上这个token,否则提示请先登录。
请求该系统的登录接口如下:
- import requests
- import json
-
- headers = {"Content-Type": "application/json;charset=utf8"}
- url = "http://127.0.0.1:5000/login"
- _data = {
- "username": "刘德华",
- "password": "123456"
- }
- res = requests.post(url=url, headers=headers, json=_data).text
- print(res)
结果如下:
- {
- "code": 1000,
- "msg": "登录成功!",
- "token": "sh34ljjl08s32730djsh34ljjl08s32730djsh34ljjl08s32730djsh34ljjl08s32730djsh34ljjl08s32730djsh34ljjl08s32730dj"
- }
在对这样的项目做接口自动化测试时,需要先请求登录接口拿到token,再去请求别的接口。每次请求其他接口时先请求一次登录接口,这样做虽然可行,但这样不仅会降低自动化的执行效率,而且每次都请求登录也会对服务器资源造成浪费。
这里介绍如下两种处理思路。
1. 思路一
在执行用例之前,先请求登录接口,并将返回的token值存储在文件中(如yaml文件),后续请求需要用到token值则从该文件。
python中yaml文件的读写请参考我之前的文章Python读写yaml文件(使用PyYAML库)。
1、运行接口自动化测试框架,初始化时先请求登录接口,获取token值,并写入指定的yaml文件中。
- import requests
- import json
- import yaml
-
- def get_token():
- '''
- 请求登录接口,获取token
- :return:
- '''
- headers = {"Content-Type": "application/json;charset=utf8"}
- url = "http://127.0.0.1:5000/login"
- _data = {
- "username": "刘德华",
- "password": "123456"
- }
- res = requests.post(url=url, headers=headers, json=_data).text
- res = json.loads(res)
- token = res["token"]
- return token
-
-
- def write_yaml(token):
- '''
- 写入yaml文件
- :return:
- '''
- t_data = {
- "token": token
- }
- with open("yaml文件路径", "w", encoding="utf-8") as f:
- yaml.dump(data=t_data, stream=f, allow_unicode=True)
-
-
- if __name__ == '__main__':
- token = get_token() # 获取token
- write_yaml(token) # 将token值写入yaml文件
2、执行测试用例时先读取yaml文件中token值,并将token加入headers中(也有些是将token放在请求参数中,视被测试项目具体情况而定),再发送请求。
- import requests
- import yaml
- import pytest
- import json
-
- def read_yaml():
- '''
- 读yaml文件
- :return:
- '''
- with open('yaml文件路径', 'r', encoding='utf-8') as f:
- result = yaml.load(f.read(), Loader=yaml.FullLoader)
- token = result["token"]
- return token
-
-
- def test_check_user():
- '''
- 查询个人信息(需要先登录系统)
- :return:
- '''
- # 先从yaml文件中读取token
- token = read_yaml()
- # 再将token添加到请求头中
- headers = {
- "Content-Type": "application/json;charset=utf8",
- "token": token
- }
-
- url = "http://127.0.0.1:5000/users/3"
- res = requests.get(url=url, headers=headers).text
- # 返回结果为json格式,转换为字典
- res = json.loads(res)
- # 断言code是否为1000
- assert res["code"] == 1000
-
-
- if __name__ == '__main__':
- pytest.main()
这里仅仅只是举例说明,而在实际的框架中,我们需要把这些诸如yaml文件的读写这样的函数单独封装在某个模块中,供其他模块调用,这样会代码会更加清晰简洁。
2、 思路二
利用pytest中的Fixture函数,作用域设置为session,并返回token值,后续测试方法/函数调用该Fixture函数。
pytest中Fixture的使用请参考我之前的文章pytest(6)-Fixture(固件)。
1、首先,在conftest中定义一个作用域为session的Fixture函数,用于请求登录接口返回token。
- import pytest
- import requests
- import json
-
- @pytest.fixture(scope="session")
- def get_token_fixture():
- '''
- 作用域为session的fixture函数,返回token
- :return:
- '''
- headers = {"Content-Type": "application/json;charset=utf8"}
- url = "http://127.0.0.1:5000/login"
- _data = {
- "username": "刘德华",
- "password": "123456"
- }
- res = requests.post(url=url, headers=headers, json=_data).text
- res = json.loads(res)
- token = res["token"]
- return token
2、接着,测试用例调用该Fixture。
- def test_check_user(get_token_fixture):
- '''
- 查询个人信息(需要先登录系统)
- :return:
- '''
- # 通过Fixture函数g获取et_token_fixture值,即token,再将token添加到请求头中
- headers = {
- "Content-Type": "application/json;charset=utf8",
- "token": get_token_fixture
- }
-
- url = "http://127.0.0.1:5000/users/3"
- res = requests.get(url=url, headers=headers).text
- res = json.loads(res)
- print(res)
- print(headers)
- assert res["code"] == 1000
-
-
- if __name__ == '__main__':
- pytest.main()
执行测试用例结果如下:

说明思路二也是可行的,当然这里只执行了一条测试用例,如果执行很多的用例,效果会是怎样还没去验证,大家可以试试看。
最后今天的文章就到这里了哟,喜欢的小伙伴可以点赞收藏加关注哟,希望这篇文章可以帮助到大家哟。
