之前写的自动化测试框架调用的是BeatuifulReport(https://github.com/TesterlifeRaymond/BeautifulReport)来做的报告表现(以下简称BR)。群里有小伙伴使用BR时发现其是使用装饰器进行的截图传递,不知道怎么用。我试着来分析一下:
git的Readme里有如下的说明:
可以看到,将图片拼接到HTML实际上是add_test_img()装饰器的业务。点进去看代码如下:
def add_test_img(*pargs):
"""
接受若干个图片元素, 并展示在测试报告中
:param pargs:
:return:
"""
def _wrap(func):
@wraps(func)
def __wrap(*args, **kwargs):
img_path = os.path.abspath('{}'.format(BeautifulReport.img_path))
try:
result = func(*args, **kwargs)
except Exception:
if 'save_img' in dir(args[0]):
save_img = getattr(args[0], 'save_img')
save_img(func.__name__)
data = BeautifulReport.img2base(img_path, pargs[0] + '.png')
print(HTML_IMG_TEMPLATE.format(data, data))
sys.exit(0)
print('
')
if len(pargs) > 1:
for parg in pargs:
print(parg + ':')
data = BeautifulReport.img2base(img_path, parg + '.png')
print(HTML_IMG_TEMPLATE.format(data, data))
return result
if not os.path.exists(img_path + pargs[0] + '.png'):
return result
data = BeautifulReport.img2base(img_path, pargs[0] + '.png')
print(HTML_IMG_TEMPLATE.format(data, data))
return result
return __wrap
return _wrap
首先,装饰器的固定写法,定义一个_wrap(),然后再写一个__wrap()用@wraps保留原函数的属性。
接下去就是具体的业务逻辑了,先定义img_path的路径,然后用try except尝试去运行原函数,如果运行成功,将原函数的结果记入result变量;如果失败,则在原函数的参数里检查是否存在“save_img”函数,如果有,则说明需要保存图片,通过getattr函数获得’save_img’函数,并将当前函数的名字func.__name__
设为其参数并运行。默认的save_img函数在BR库的另一个py文件里:
BeautifulReport/tests/test_make_report.py
def save_img(self, img_name):
"""
传入一个img_name, 并存储到默认的文件路径下
:param img_name:
:return:
"""
self.driver.get_screenshot_as_file('{}/{}.png'.format(os.path.abspath(self.img_path), img_name))
这样,如果用户定义过save_img函数,那在执行抛异常时,就会自动去调用save_img函数去截图。
然后再将截图结果通过image2base函数转一下格式,赋给一个data变量。
可以看到image2base函数很简单,就是转格式而已:
@staticmethod
def img2base(img_path: str, file_name: str) -> str:
"""
接受传递进函数的filename 并找到文件转换为base64格式
:param img_path: 通过文件名及默认路径找到的img绝对路径
:param file_name: 用户在装饰器中传递进来的问价匿名
:return:
"""
pattern = '/' if platform != 'Windows' else '\\'
with open(img_path + pattern + file_name, 'rb') as file:
data = file.read()
return base64.b64encode(data).decode()
转好的base64格式字符串会被填充到一个HTML_IMG_TEMPLATE
常量里。
这个HTML_IMG_TEMPLATE
在之前定义过,可以点进去看是这么一个值:
HTML_IMG_TEMPLATE = """
"""
其实就是把图片拼接到一个HTML里啦。
经过这一步步操作,BR就做到了在抛异常时,自动截图并嵌入HTML的操作。
后面还有一段代码:
if len(pargs) > 1:
for parg in pargs:
print(parg + ':')
data = BeautifulReport.img2base(img_path, parg + '.png')
print(HTML_IMG_TEMPLATE.format(data, data))
return result
if not os.path.exists(img_path + pargs[0] + '.png'):
return result
data = BeautifulReport.img2base(img_path, pargs[0] + '.png')
print(HTML_IMG_TEMPLATE.format(data, data))
return result
这都很好理解了,就是有多个截图时,逐个去截并镶嵌到HTML里。