解析BeautifulReport的截图装饰器

解析BeautifulReport的截图装饰器

之前写的自动化测试框架调用的是BeatuifulReport(https://github.com/TesterlifeRaymond/BeautifulReport)来做的报告表现(以下简称BR)。群里有小伙伴使用BR时发现其是使用装饰器进行的截图传递,不知道怎么用。我试着来分析一下:

git的Readme里有如下的说明:
解析BeautifulReport的截图装饰器_第1张图片
可以看到,将图片拼接到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里。

你可能感兴趣的:(python,BeautifulReport)