pyhton+yaml+pytest+allure框架封装-全局变量接口关联
上一篇写到用fixture来进行全局变量,但是我们不可能只有对应的token 在工作中会有很多对应的数据。在框架层面中如果一直用fixture是不那么合理的。那怎么解决呢 ?
我们还使用全局变量 用字典的方式来进行存储。 针对于全局变量认定为内置属性,外部不可修改,我们提供对应的方法,可以对这个属性进行修改、增加和显示。
那具体要怎么做呢? 展示
我们先创建一个文件夹,文件夹中创建一个python文件 这个文件是专门用来存储全局变量的
好 我们接下来写一个类,那为什么是类 刚才有说到 提供对应的方法,可以对这个属性进行修改、增加和显示。类是继承对象的
因为外部不可更改 我们需要提供方法 进行修改、增加和显示。
1、通过key来进行设置
2、通过key去获取数据
3、通过字典去设置对应的数据
4、显示我们对应的全局变量
我们现在一个方法一个方法的写 来实现我们以上说的4点
通过key来进行设置
def set_dict(self,key,value):
self._my_dict[key] = value
通过key去获取数据
def get_dict(self,key):
return self._my_dict.get(key,None)
通过字典去设置对应的数据
def set_up_dict(self,dic):
self._my_dict.update(dic)
显示我们对应的全局变量
def show_dict(self):
return self._my_dict
写完后我们测试一下代码
# 测试代码
# 实例化 g_test 类
context = g_test()
# 调用 set_dict 对key进行设置
context.set_dict('name','xiaowang')
# 调用 show_dict 打印字典
print(context.show_dict())
# 调用 get_dict 方法 并获取name的值
print(context.get_dict('name'))
# 调用 set_up_dict 设置对应数据
data = {'token':'1234543','age':22}
context.set_up_dict(data)
print(context.show_dict())
运行结果
好!
现在全局变量我们已经定义好了,那我们要进行一个什么操作呢?
我们的目标是不是要进行接口关联,接口关联提取的数据肯定是要放到全局变量当中去,。我们要实现关联,所以我们要进行封装,通过我们对应的相应数据 进行数据提取的方法。提取的方法用jsonpath 。那我们提取jsonpath并存储到全局变量
那我们知道了要提取数据 要先清楚几件事
1、提取的数据是什么
2、提取的表达式是什么
3、提取的下标是什么
4、提取了之后保存到全局变量名是什么
在关键字中写入发送请求(前两篇有写过,可以往前翻)我们在发送请求之后的相应数据进行存储操作,我们导入刚才声明的类调用我们刚才的方法来存储一下,然后拿到我们的数据(对象.方法传入我们返回的值)后变成json格式。
附:之前写入的关键字
import allure
import requests
class Test_Keys:
# 发送请求
@allure.step('参数数据:发送post请求')
def request_post(self,**kwargs):
# 发送请求
response = requests.post(**kwargs)
return response
@allure.step('参数数据:发送get请求')
def request_get(self,**kwargs):
response = requests.get(**kwargs)
return response
然后我们创建新的关键字
@allure.step('参数数据:提取json数据并存储到全局变量')
def ex_jsondata(self,**kwargs):
pass
然后我们把当前的响应数据存储一下 ,我们先导入我们之前的全局变量
from test_case.global_files.global_variable import g_test
然后存储当前的响应数据
class Test_Keys:
# 发送请求
@allure.step('参数数据:发送post请求')
def request_post(self,**kwargs):
# 发送请求
response = requests.post(**kwargs)
# 我们把当前的响应数据存储一下
g_test().set_dict('current_response',response)
return response
提取json数据
@allure.step('参数数据:提取json数据并存储到全局变量')
def ex_jsondata(self,**kwargs):
# 拿到我们的响应数据
response = g_test().get_dict('current_response').json()
# 拿到对应提取表达式 json,通过get方法获取kwargs的值,如果没有拿到对应None
ex_value = kwargs.get('ex_value',None)
# 拿到对应下标 默认为0
ex_index = kwargs.get('ex_index',0)
# 如果没有拿到下标没有值或者为空 我们都给它一个0的值
if ex_index is None:
ex_index = 0
# 提取数据
ex_data = jsonpath.jsonpath(response,ex_value)[ex_index]
# 通过提取的数据,存储到对应变量,到全局变量中
g_test().set_dict(kwargs['varname'],ex_data)
然后我们打印
# 打印我们的数据
print(g_test().show_dict())
print('-----------')
print(ex_data)
到这一步我们就封装好啦
封装好了以后我们要有对应的改动 在测试用例 就不能通过jsonpath而是要通过关键字key 来调用我们对应的方法了。
我们回到用例中先导入我们封装好的关键字
from key_words.test_keys import Test_Keys
然后在请求和jsonpath中进行修改
我们上一个接口拿到的值 比如token是要传给下一个接口用的 所以我们从全局变量中获取数据
也是一样的改动
然后我们就可以运行啦
结果
附代码:
全局变量及方法文件
# 类继承
class g_test(object):
# 内置属性外部不可更改
_my_dict = {}
# 1、通过key来进行设置
def set_dict(self,key,value):
self._my_dict[key] = value
# 2、通过key去获取数据
def get_dict(self,key):
return self._my_dict.get(key,None)
# 3、通过字典去设置对应的数据
def set_up_dict(self,dic):
self._my_dict.update(dic)
# 4、显示我们对应的全局变量
def show_dict(self):
return self._my_dict
# 测试代码
# 实例化 g_test 类
context = g_test()
# 调用 set_dict 对key进行设置
context.set_dict('name','xiaowang')
# 调用 show_dict 打印字典
print(context.show_dict())
# 调用 get_dict 方法 并获取name的值
print(context.get_dict('name'))
# 调用 set_up_dict 设置对应数据
data = {'token':'1234543','age':22}
context.set_up_dict(data)
print(context.show_dict())
关键字文件
# 存放关键字的文件 常用的接口请求过程的操作
# 类名 方法保持一致
import allure
import requests
import jsonpath
from global_files.global_variable import g_test
class Test_Keys:
# 发送请求
@allure.step('参数数据:发送post请求')
def request_post(self,**kwargs):
# 发送请求
response = requests.post(**kwargs)
# 我们把当前的响应数据存储一下
g_test().set_dict('current_response',response)
return response
@allure.step('参数数据:发送get请求')
def request_get(self,**kwargs):
response = requests.get(**kwargs)
# 我们把当前的响应数据存储一下
g_test().set_dict('current_response', response)
return response
@allure.step('参数数据:提取json数据并存储到全局变量')
def ex_jsondata(self,**kwargs):
# 拿到我们的响应数据
response = g_test().get_dict('current_response').json()
# 拿到对应提取表达式 json,通过get方法获取kwargs的值,如果没有拿到对应None
ex_value = kwargs.get('ex_value',None)
# 拿到对应下标 默认为0
ex_index = kwargs.get('ex_index',0)
# 如果没有拿到下标没有值或者为空 我们都给它一个0的值
if ex_index is None:
ex_index = 0
# 提取数据
ex_data = jsonpath.jsonpath(response,ex_value)[ex_index]
# 通过提取的数据,存储到对应变量,到全局变量中
g_test().set_dict(kwargs['var_name'],ex_data)
print('--------------------')
print(g_test().show_dict())
print('--------------------')
return ex_data
用例1登陆用例文件
import allure
from key_words.test_keys import Test_Keys
test_key = Test_Keys()
@allure.title('登陆成功测试用例')
def test_01_login():
with allure.step('第一步,登陆操作'):
url = "http://www.hghghhg.com/index.php?s=/login"
params = {
"application": "app",
"application_client_ty1pe": "weixin"
}
data = {
'accounts': 'nihao',
'pwd': '123456',
'type': 'username'
}
# 发送请求
ret = test_key.request_post(url=url, params=params, data=data)
# 获取我们的相应数据.msg
mag_ret = test_key.ex_jsondata(ex_value='$..msg',var_name='msg_results')
print("当前提取的数据为:", mag_ret)
# 根据对应的.msg进行断言处理
assert mag_ret == "登录成功", f'错误,我们当前返回的值是:{mag_ret}'
# 获取token
token_ret = test_key.ex_jsondata(ex_value='$..token',var_name='token')[0]
print("当前提取的数据为:", token_ret)
return token_ret
用例2 加入购物车用例文件
# 用例文件
import allure
from global_files.global_variable import g_test
# 导入我们封装的关键字
from key_words.test_keys import Test_Keys
test_key = Test_Keys()
@allure.title('加入购物车成功测试用例')
def test_02_addcar():
# 从全局变量获取数据
token_ret = g_test().get_dict('token')
with allure.step('第二步,加入购物车'):
url = 'http://www.jgjgjjg.com/index.php?s=/save'
params = {
"application": "app",
"application_client_type": "weixin",
'token': token_ret
}
data = {
"goods_id": "3",
"spec": [{
"type": "3",
"value": "4"
},
],
"stock": 1
}
ret = test_key.request_post(url=url, params=params, data=data)
mag_ret = test_key.ex_jsondata(ex_value='$..msg',var_name='msg_results')
print('当前提取数据为:', mag_ret)
assert mag_ret == '加入成功', f'失败,返回的的是:{mag_ret}'
运行文件
# 运行文件
import subprocess
import pytest
py_args = [
'-s', # 禁用所有捕获和输出重定向
'-v', # 显示详细的信息
# '--capture=sys', # 输出调试信息,设置级别,打开实时输出(根据需要启用)
'--alluredir=allure-results', # 执行过程的数据存放在allure-results中
# '--clean-alluredir' # 如果需要清理alluredir,请确保此选项在--alluredir之前(但这不是pytest的标准选项,可能是自定义的)
]
print('run pytest with args:', py_args)
# 使用pytest.main()函数运行测试
if __name__ == "__main__":
pytest.main(py_args)
# 生成测试报告
try:
result = subprocess.run(['allure', 'generate', '-c', '-o', 'allure-report'], check=True)
print("Allure report generated successfully.")
except subprocess.CalledProcessError as e:
print(f"Failed to generate Allure report: {e}")
# 尝试合并报告(如果combine_allure是有效的)
try:
from allure_combine import combine_allure # 确保在需要时才导入,避免在模块导入时出错
combine_allure('./allure-report')
except ImportError:
print("combine_allure module is not available. Skipping report combining.")
except Exception as e:
print(f"An error occurred while combining reports: {e}")
好啦 就到这里啦