自定义截图装饰器与pytest-conftest同时使用遇到的问题
场景/原因
使用pytest做UI自动化,driver和case_data写在了conftest中,测用例直接调用 另外写了一个装饰器,在测试用例运行完成后/报错后截图
代码如下
测试用例代码如下
from common.step_method import StepMethod
from common.public import *
class TestCases():
@get_screen_in_case_end_or_error
def test_001(self,driver,case_data):
'''
根据传进来的参数,执行测试用例
:param driver: 浏览器驱动
:param case_data: 测试用例数据
:return:
'''
allure.dynamic.feature(case_data["feature"])
allure.dynamic.story(case_data["story"])
allure.dynamic.title(case_data["case_name"])
step_method=StepMethod(driver=driver)
for step in case_data["case_steps"]:
with allure.step(step["case_step"]):
if hasattr(step_method, step["method"]):
func=getattr(step_method, step["method"])
func(**step)
else:
raise Exception(f'传入的方法:{step["method"]}不正确,请检查')
装饰器代码如下
def get_screen_in_case_end_or_error(func):
'''
测试用例运行完成或者发生错误的时候进行截图
:param func:
:return:
'''
def f1(*args,**kwargs):
try:
func(*args,**kwargs)
time.sleep(1)
get_screen_add_report(args[0].driver,'运行完成截图')
except:
time.sleep(1)
get_screen_add_report(args[0].driver,"异常截图")
raise
return f1
运行后报错
..\common\public.py:62 (TestCases.test_001)
args = (<test_cases.test_cases.TestCases object at 0x0000018C98FF0588>,)
kwargs = {}
def f1(*args,**kwargs):
try:
> func(*args,**kwargs)
E TypeError: test_001() missing 2 required positional arguments: 'driver' and 'case_data'
很明显,这两个写在conftest中的参数,并没有自动传进去,因为外面包了一层装饰器,导致pytest的conftest中的前置参数不能正常传进去了,经过查找,需要在装饰器中加@wraps(func)
修改装饰器
from six import wraps
def get_screen_in_case_end_or_error(func):
'''
测试用例运行完成或者发生错误的时候进行截图
:param func:
:return:
'''
@wraps(func)
def f1(*args,**kwargs):
try:
func(*args,**kwargs)
time.sleep(1)
get_screen_add_report(args[0].driver,'运行完成截图')
except:
time.sleep(1)
get_screen_add_report(args[0].driver,"异常截图")
raise
return f1
运行后报另外的错误
args = (<test_cases.test_cases.TestCases object at 0x0000028BC4C9D248>,)
kwargs = {'case_data': {'case_loc': (1, 11, 1, 2), 'case_name': '成功注册', 'case_steps': [{'case_name': '成功注册', 'case_step': '打开课程...e': '公共', ...}, 'driver': <selenium.webdriver.chrome.webdriver.WebDriver (session="f4f9ad26335cc919b4a9514e839f65f9")>}
@wraps(func)
def f1(*args,**kwargs):
try:
func(*args,**kwargs)
time.sleep(1)
> get_screen_add_report(args[0].driver,'运行完成截图')
E AttributeError: 'TestCases' object has no attribute 'driver'
driver是直接传给用例的,装饰器如何能用到这个driver参数呢
修改测试用例代码,把driver赋值给self.driver,在装饰器中可以用obj获取
from six import wraps
def get_screen_in_case_end_or_error(func):
'''
测试用例运行完成或者发生错误的时候进行截图
:param func:
:return:
'''
@wraps(func)
def f1(obj,*args,**kwargs):
try:
func(obj,*args,**kwargs)
time.sleep(1)
get_screen_add_report(obj.driver,'运行完成截图')
except:
time.sleep(1)
get_screen_add_report(obj.driver,"异常截图")
raise
return f1
case中代码如下
from common.step_method import StepMethod
from common.public import *
class TestCases():
@get_screen_in_case_end_or_error
def test_001(self,driver,case_data):
'''
根据传进来的参数,执行测试用例
:param driver: 浏览器驱动
:param case_data: 测试用例数据
:return:
'''
self.driver=driver
allure.dynamic.feature(case_data["feature"])
allure.dynamic.story(case_data["story"])
allure.dynamic.title(case_data["case_name"])
step_method=StepMethod(driver=driver)
for step in case_data["case_steps"]:
with allure.step(step["case_step"]):
if hasattr(step_method, step["method"]):
func=getattr(step_method, step["method"])
func(**step)
else:
raise Exception(f'传入的方法:{step["method"]}不正确,请检查')
最后解决,没有报错
|