tips:这个是 pytest+allure 基础,老手可以绕过
使用 pytest+allure 写自动化脚本时,可能会有预料之外(未作判断直接用)的异常情况:比如元素不存在、隐藏、被覆盖等等,可能会一个个测试方法都加上异常捕获的方式,比较重复。
其实利用装饰器,统一 test 的异常处理是比较方便和简单的,但要增加加一些其他功能(比如 webdriver 截图到 allure 中),且需避免一些 assert 异常被捕获"重复处理(比如重复截图)"的情况,可以这样做
[1] 首先有 webdriver 的包装类
class BrowserManager(object):
def __init__(self,...):
self.driver=webdriver.Chrome(...)
def snapAndGetPath(self,dir="./Tmp/Snaps/"):
"""
截图
:param dir:
:return:
"""
if not os.path.isdir(dir):
os.makedirs(dir)
picPath=dir+getTimeNumCode()+".png"
if self.driver.get_screenshot_as_file(picPath):
return picPath
else:
return None
def exceptionWithAllureSnap(self,exception:Exception):
"""
异常时截图用
:param exception:
:return:
"""
allure.attach.file(self.snapAndGetPath(),attachment_type=allure.attachment_type.PNG)
allure.attach(str(exception)+traceback.format_exc(),'元素异常')
[2] contest.py 中定义全局 fiexture:webdriver 的包装类的实例:xBM
bm=None
@pytest.fixture(scope='session',autouse=True)
def xBM(request):
"""
session级别:整个程序运行中,多个文件只运行一次
:param request:
:return:
"""
global bm
if bm is None or bm.driver is None:
bm=BrowserManager()
def end():
bm.driver.quit()
request.addfinalizer(end) # 最终关闭dirver
return bm
[3] 定义统一的异常处理装饰器
def wrap_exception(func):
"""
test的统一异常截图处理
:param func:
:return:
"""
@functools.wraps(func)
def wrap(*args,**kwargs):
xBM=kwargs.get("xBM")
try:
func(*args,**kwargs)
except Exception as e:
if xBM and not isinstance(e,AssertionError):
# 如果assert异常会截图处理,此处就不要重复截图和附加异常信息
xBM.exceptionWithAllureSnap(e)
raise e
return wrap
[4] 测试方法中使用
@wrap_exception
def testSample(xBM):
xBM.driver.get("https://xxxx.xxx.com")
xBM.driver.find_element_xpath("xxxx").send_keys("xxxx")
assert False,"看看assert异常是否正常处理"
总结:这样的好处是不用 test 方法中重复写各种异常处理。 这里只是个粗糙的说明,实际需跟具体情况细化