python+pytest接口自动化之token关联登录的实现

在PC端登录公司的后台管理系统或在手机上登录某个APP时,经常会发现登录成功后,返回参数中会包含token,它的值为一段较长的字符串,而后续去请求的请求头中都需要带上这个token作为参数,否则就提示需要先登录。

这其实就是状态或会话保持的第三种方式token

一. 什么是token

token 由服务端产生,是客户端用于请求的身份令牌。第一次登录成功时,服务端会生成一个包含用户信息的加密字符串token,返回给客户端并保存在本地,后续客户端只需要带上token进行请求即可,无需带上用户名密码。

token原理简单概括如下:

  • 用户首次登录成功后,服务端会生成一个token值,服务端会将它保存保存在数据库中,同时也会将它返回给客户端;
  • 客户端拿到token值后,保存在本地;
  • 后续客户端再次发送除登录外的其他请求时,会把保存在本地的token值作为参数一起发送给服务端;
  • 服务端收到客户端的请求后,会拿发送过来的token值与保存在数据库中的token值进行比较;
  • 如果两个token值相同, 则说明当前用户处于登录状态;
  • 如果数据库中没有这个token值或者token值已经生效,则需用户重新登录。

二. token场景处理

公司某管理后台系统,登录后返回token,接着去请求其他接口时请求头中都需要加上这个token,否则提示请先登录。

请求该系统的登录接口如下:

1

2

3

4

5

6

7

8

9

10

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文件中。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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文件

    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放在请求参数中,视被测试项目具体情况而定),再发送请求。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

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():

    查询个人信息(需要先登录系统)

    # 先从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。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

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。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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()

执行测试用例结果如下:

说明思路二也是可行的,当然这里只执行了一条测试用例,如果执行很多的用例,效果会是怎样还没去验证,大家可以试试看。

三. 总结

  • 相对于Session/Cookies来说,请求量较大或者涉及第三方接口的系统,使用token更适合。
  • 有些项目token是放在请求头中发送的,而有一些项目则是放在请求参数里发送的,做接口自动化时要明确是哪种方式。
  • 接口自动化处理token时这两种思路可任选一种,如果使用pytest框架的话建议尝试思路二。
​现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:485187702【暗号:csdn11】

最后感谢每一个认真阅读我文章的人,看着粉丝一路的上涨和关注,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走! 希望能帮助到你!【100%无套路免费领取】

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值