最新出炉,2024年精品文章python+pytest接口自动化-token关联登录_pytest token

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • username2: Lilei
  • password2: 888888
    deviceName: null
    appPackage: ~
    bool1: True

读取结果:



{‘os’: ‘Android’, ‘osVersion’: 10, ‘account’: [{‘username1’: ‘xiaoqq’}, {‘password1’: 123456}, {‘username2’: ‘Lilei’}, {‘password2’: 888888}], ‘deviceName’: None, ‘appPackage’: None, ‘bool1’: True}


#### 4,从yaml中读取多组数据


yaml多组数据时,每组数据之间需要用3横杠分隔'---',如下:



os: Android
osVersion: 10
account1:
username1: xiaoqq
password1: 123456

os: ios
osVersion: 12
account1:
username2: Lilei
password2: 888888


从yaml中读取多组数据时需要使用`yaml.load_all()`方法,返回结果为一个生成器,需要使用for循环语句获取每组数据。代码如下:



@author: 给你一页白纸

import yaml

with open(‘./yamlData.yml’, ‘r’, encoding=‘utf-8’) as f:
result = yaml.load_all(f.read(), Loader=yaml.FullLoader)
print(result, type(result))
for i in result:
print(i)


读取结果:



<generator object load_all at 0x000001F78EBD5B48> <class ‘generator’>
{‘os’: ‘Android’, ‘osVersion’: 10, ‘account1’: {‘username1’: ‘xiaoqq’, ‘password1’: 123456}}
{‘os’: ‘ios’, ‘osVersion’: 12, ‘account1’: {‘username2’: ‘Lilei’, ‘password2’: 888888}}


### 五,写入yaml文件


#### 1,单组数据写入yaml文件


使用yaml.dump()方法,加入`allow_unicode=True`参数防止写入的中文乱码,如下:



@author: 给你一页白纸

import yaml

apiData = {
“page”: 1,
“msg”: “地址”,
“data”: [{
“id”: 1,
“name”: “学校”
}, {
“id”: 2,
“name”: “公寓”
}, {
“id”: 3,
“name”: “流动人口社区”
}],
}

with open(‘./writeYamlData.yml’, ‘w’, encoding=‘utf-8’) as f:
yaml.dump(data=apiData, stream=f, allow_unicode=True)


写入结果:



data:

  • id: 1
    name: 学校
  • id: 2
    name: 公寓
  • id: 3
    name: 流动人口社区
    msg: 地址
    page: 1

#### 2,多组数据写入yaml文件


使用yaml.dump\_all()方法,如下:



@author: 给你一页白纸

import yaml

apiData1 = {
“page”: 1,
“msg”: “地址”,
“data”: [{
“id”: 1,
“name”: “学校”
}, {
“id”: 2,
“name”: “公寓”
}, {
“id”: 3,
“name”: “流动人口社区”
}],
}

apiData2 = {
“page”: 2,
“msg”: “地址”,
“data”: [{
“id”: 1,
“name”: “酒店”
}, {
“id”: 2,
“name”: “医院”
}, {
“id”: 3,
“name”: “养老院”
}],
}

with open(‘./writeYamlData.yml’, ‘w’, encoding=‘utf-8’) as f:
yaml.dump_all(documents=[apiData1, apiData2], stream=f, allow_unicode=True)


写入结果:



data:

  • id: 1
    name: 学校
  • id: 2
    name: 公寓
  • id: 3
    name: 流动人口社区
    msg: 地址
    page: 1

data:

  • id: 1
    name: 酒店
  • id: 2
    name: 医院
  • id: 3
    name: 养老院
    msg: 地址
    page: 2

在Python中除了PyYAML库之外,还有ruamel.yaml库也可以对yaml文件进行读写操作,后续再记笔记进行介绍。


![](https://img-blog.csdnimg.cn/img_convert/c539e33d96b7fe00605fee371f2b1093.png)



1,运行接口自动化测试框架,初始化时先请求登录接口,获取token值,并写入指定的yaml文件中。



@author: 给你一页白纸

微信公众号:测试上分之路

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



> 
> [点我免费领取全套软件测试(自动化测试)视频资料(备注“csdn000”)]( )视频资料(备注“csdn000”)")
> 
> 
> 



@author: 给你一页白纸

微信公众号:测试上分之路

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的使用


#### 什么是固件


Fixture 翻译成中文即是固件的意思。它其实就是一些函数,会在执行测试方法/测试函数之前(或之后)加载运行它们,常见的如接口用例在请求接口前数据库的初始连接,和请求之后关闭数据库的操作。


我们之前在[APP UI自动化系列]( )中已经介绍过 unittest 的相关测试固件,如`setup`、`teardown`等。而 pytest 中提供了功能更加丰富的`Fixture`,用于实现`setup`、`teardown`功能。


#### 定义方式


使用`@pytest.fixture()`进行定义,简单示例如下:



import pytest

@pytest.fixture()
def before():
print(“连接数据库”)


#### 调用方式


调用单个fixture函数


* 方式一,使用**fixture**函数名作为参数

 

import pytest

@pytest.fixture()
def before():
print(“连接数据库”)

调用before

def test_01(before):
print(“执行test_01”)

* 方式二,使用 `@pytest.mark.usefixtures('fixture函数名')`装饰器

 

import pytest

@pytest.fixture()
def before():
print(“连接数据库”)

调用before

@pytest.mark.usefixtures(‘before’)
def test_01():
print(“执行test_01”)

* 方式三,使用`autouse`参数自动执行`fixture`函数

 

import pytest

fixture函数定义的时候使用autouse参数,作用域范围内的测试用例会自动调用该fixture函数

@pytest.fixture(autouse=True)
def before():
print(“连接数据库”)

自动调用before

def test_01():
print(“执行test_01”)



三种方式调用后的结果都如下:


![](https://img-blog.csdnimg.cn/img_convert/05af532a5e4b162e9ae9b6d28747db36.png)


我们可以看到,先执行了`fixture`函数,再执行测试函数。


调用多个fixture函数



import pytest

@pytest.fixture()
def before():
print(“连接数据库”)

@pytest.fixture()
def before_s():
print(“初始化数据”)

def test_01(before, before_s):
print(“执行test_01”)


调用多个 fixture 函数时,由前至后依次执行,所以`test_01()`调用时先执行`before`,再执行`before_s`。


对fixture函数重命名


定义`fixture`函数时,可以利用`name`参数进行重命名,方便用于调用,示例如下:



import pytest

@pytest.fixture(name=‘db’)
def connect_order_db():
print(“连接数据库”)

def test_01(db):
print(“执行test_01”)


#### 使用fixture传递测试数据


在执行完`fixture`函数后,有时需要将该`fixture`中得到到某些数据传递给测试函数/测试方法,用于后续的执行。


`fixture`中提供普通传递和参数化传递两种数据传递方式。


普通传递


示例如下:



import pytest

@pytest.fixture()
def before():
print(“连接数据库”)
return “连接成功!”

def test_01(before):
print(“执行test_01”)
assert before == “连接成功!”


注意,如果自定义的`fixture`函数有返回值,需要使用上面说的方式一调用才能获取`fixture`函数的返回值并传入测试函数中,方式二就无法获取返回值。


参数化传递


对`fixture`函数进行参数化时,需要使用参数`params`,并且需要传入参数`request`,简单示例如下:



import pytest

test_params = [1, 2, 0]
@pytest.fixture(params=test_params)
def before(request):
result = request.param
return result

def test_02(before):
print(“执行test_02”)
assert before

if name == ‘main’:
pytest.main()


执行结果:


![](https://img-blog.csdnimg.cn/img_convert/3e347881d02deee3d74e63492d9baf75.png)


可以看到,因为所调用的fixture函数进行了参数化,虽然只有一个测试函数但执行了3次。


#### conftest.py


上面我们举的例子都是把fixture函数放在测试用例模块里面,但如果很多测试模块需要引用同一个fixture函数怎么办,这是时候就需要把它放在命名为`conftest`的模块里,这样**同级或以下目录**中的测试用例便能调用这些自定义的fixture函数。


例如,有如下目录:



├─testcase
│ │
│ ├─test_module_01
│ │ test_case_1.py
│ │ test_case_2.py
│ │
│ ├─test_module_02
│ │ test_case_3.py


test\_module\_01 中的`test_case_1.py`与`test_case_2.py`都需要调用同一个 fixture 函数,那么我们只需要在 test\_module\_01 中新建`conftest.py`并编写这个`fixture`函数即可,示例如下:



├─testcase
│ │
│ ├─test_module_01
│ │ conftest.py
│ │ test_case_1.py
│ │ test_case_2.py
│ │
│ ├─test_module_02
│ │ test_case_3.py


`conftest.py`:



import pytest

@pytest.fixture(autouse=True)
def before():
print(“连接数据库”)


`test_case_1.py`:



def test_01():
print(“执行test_01”)


`test_case_2.py`:



def test_02():
print(“执行test_02”)


这样,执行这两个模块的测试用例时会自动先去调用`conftest.py`中的`before()`函数。


假设 test\_module\_02 中的 test\_case\_3.py 也需要调用这个`before()`函数,那么这个时候我们就需要在上一层即 testcase 中新建`conftest.py`并编写这个`before()`函数,才能在 test\_case\_3.py 中调用,如下:



├─testcase
│ │ conftest.py
│ │
│ ├─test_module_01
│ │ conftest.py
│ │ test_case_1.py
│ │ test_case_2.py
│ │
│ ├─test_module_02
│ │ test_case_3.py


`conftest.py`只作用于`同级`或`以下`目录中的测试模块,且需要**注意**,当`以下`层级中存在了另一个`conftest.py`,那么以下层级将由另一个`conftest.py`文件接管。


#### 作用域


pytest 的 fixture 作用域分`session`、`module`、`class`、`function`四个级别。在定义 fixture 函数的时候通过`scope`参数指定作用范围,默认为`function`。


* `session`,每次会话执行一次
* `module`,每个测试模块执行一次
* `class`,每个测试类执行一次
* `function`,每个测试方法执行一次


注意,对于单独定义的测试函数,class、function 都会起作用,可以从下列示例中看出来。


测试目录结构如下:



├─apiAutoTest
│ │ run.py
│ │
│ ├─testcase
│ │ │ conftest.py
│ │ │
│ │ ├─test_module_02
│ │ │ │ conftest.py
│ │ │ │ test_case_3.py
│ │ │ │ test_case_4.py


其中`conftest.py`代码如下:



import pytest

@pytest.fixture(scope=“session”, autouse=True)
def session_fixture():
print(“这是一个作用于session的fixture”)

@pytest.fixture(scope=“module”, autouse=True)
def module_fixture():
print(“这是一个作用于module的fixture”)

@pytest.fixture(scope=“class”, autouse=True)
def class_fixture():
print(“这是一个作用于class的fixture”)

@pytest.fixture(scope=“function”, autouse=True)
def function_fixture():
print(“这是一个作用于function的fixture”)


`test_case_3.py`代码如下:



import pytest

class TestOrder:

def test_a(self):
    print("test_a")
    
def test_b(self):
    print("test_b")

def test_c():
print(“test_c”)


`test_case_4.py`代码如下:



def test_e():

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

@pytest.fixture(scope=“function”, autouse=True)
def function_fixture():
print(“这是一个作用于function的fixture”)


`test_case_3.py`代码如下:



import pytest

class TestOrder:

def test_a(self):
    print("test_a")
    
def test_b(self):
    print("test_b")

def test_c():
print(“test_c”)


`test_case_4.py`代码如下:



def test_e():

[外链图片转存中…(img-gEysgpIk-1714852596403)]
[外链图片转存中…(img-GKTKHcox-1714852596403)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值