四、airtest生成聚合报告

承接上一篇airtest批量运行测试用例后,运行结果需要整理出报告,此篇针对测试完后的报告实现作说明。

下图是airtest自带的report目录,report在airtest根目录下,集成了bootstrap框架,所以自带report报告界面还是比较好看的。

项目的结构如下所示:

 

下面是实现过程:

1、在runner中初始化log,log的形式是log_年月日_时分秒。初始化后返回log名字。

2、在脚本执行的时创建log。每个用例对应一个log,后续在report里面会遍历拿到这些log。

 3、report的执行入口,在执行入口中,实例化一个命令行解析器,往命令行解析器中添加参数,实现的方法是get_parser,然后获取log的根路径和log文件夹,拿到log文件夹后,遍历里面所有的log,分别拿到脚本和输出log文件,并且通过执行main方法得到log结果,最后通过jinjia设置报告模板。

扫描二维码关注公众号,回复: 16440907 查看本文章

 

实现命令行添加参数,主要添加脚本参数、输出文件参数、一些其他参数设置,这些参数将记录到报告文件里面。

4、在项目根目录下创建summary_template.html文件,summary_template.html文件的内容如下,用来显示报告模板。 

 5、main方法调用airtest自带report的LogToHtml类来解析渲染log到HTML中。同时将自定义重写的report方法绑定到airtest的LogToHtml对象上。

 6、自定义report方法来修改info的获取方式。通过自定义,我们可指定自己需要的信息内容。比如这里我自定义了steps、name、scale、test_result等内容。

 以上就是整个聚合报告的整个过程,最后附上report的源代码,需要的请自取学习:

# -*- coding: utf-8 -*-

import os
import io
import types
import shutil
import json
import jinja2
from airtest.utils.compat import decode_path
import airtest.report.report as R

HTML_FILE = "log.html"
HTML_TPL = "log_template.html"
STATIC_DIR = os.path.dirname(R.__file__)

def get_parger(ap):
    ap.add_argument("script", help="script filepath")
    ap.add_argument("--outfile", help="output html filepath, default to be log.html")
    ap.add_argument("--static_root", help="static files root dir")
    ap.add_argument("--log_root", help="log & screen data root dir, logfile should be log_root/log.txt")
    ap.add_argument("--record", help="custom screen record file path", nargs="+")
    ap.add_argument("--export", help="export a portable report dir containing all resources")
    ap.add_argument("--lang", help="report language", default="en")
    ap.add_argument("--plugins", help="load reporter plugins", nargs="+")
    return ap


def get_script_info(script_path):
    script_name = os.path.basename(script_path)
    result_json = {"name": script_name, "author": None, "title": script_name, "desc": None}
    return json.dumps(result_json)


def _make_export_dir(self):
    dirpath = self.script_root
    logpath = self.script_root
    # copy static files
    for subdir in ["css", "fonts", "image", "js"]:
        dist = os.path.join(dirpath, "static", subdir)
        shutil.rmtree(dist, ignore_errors=True)
        self.copy_tree(os.path.join(STATIC_DIR, subdir), dist)

    return dirpath, logpath


def report(self, template_name, output_file=None, record_list=None):
    """替换LogToHtml中的report方法"""
    self._load()
    steps = self._analyse()
    # 修改info获取方式
    info = json.loads(get_script_info(self.script_root))

    if self.export_dir:
        self.script_root, self.log_root = self._make_export_dir()
        output_file = os.path.join(self.script_root, HTML_FILE)
        self.static_root = "static/"

    if not record_list:
        record_list = [f for f in os.listdir(self.log_root) if f.endswith(".mp4")]
    records = [os.path.join(self.log_root, f) for f in record_list]

    if not self.static_root.endswith(os.path.sep):
        self.static_root = self.static_root.replace("\\", "/")
        self.static_root += "/"

    data = {}
    data['steps'] = steps
    data['name'] = os.path.basename(self.script_root)
    data['scale'] = self.scale
    data['test_result'] = self.test_result
    data['run_end'] = self.run_end
    data['run_start'] = self.run_start
    data['static_root'] = self.static_root
    data['lang'] = self.lang
    data['records'] = records
    data['info'] = info

    return self._render(template_name, output_file, **data)


def get_result(self):
    return self.test_result


def main(args):
    # script filepath
    path = decode_path(args.script)
    record_list = args.record or []
    log_root = decode_path(args.log_root) or path
    static_root = args.static_root or STATIC_DIR
    static_root = decode_path(static_root)
    export = decode_path(args.export) if args.export else None
    lang = args.lang if args.lang in ['zh', 'en'] else 'zh'
    plugins = args.plugins

    # gen html report
    rpt = R.LogToHtml(path, log_root, static_root, export_dir=export, lang=lang, plugins=plugins)
    # override methods
    rpt._make_export_dir = types.MethodType(_make_export_dir, rpt)
    rpt.report = types.MethodType(report, rpt)
    rpt.get_result = types.MethodType(get_result, rpt)

    rpt.report(HTML_TPL, output_file=args.outfile, record_list=record_list)

    return rpt.get_result()


if __name__ == "__main__":
    import argparse
    ap = argparse.ArgumentParser()
    args = get_parger(ap).parse_args()
    basedir = os.path.dirname(os.path.realpath(__file__))
    logdir = os.path.realpath(args.script)

    # 聚合结果
    results = []

    # 遍历所有日志
    for subdir in os.listdir(logdir):
        if os.path.isfile(os.path.join(logdir, subdir)):
            continue
        args.script = os.path.join(logdir, subdir)
        args.outfile = os.path.join(args.script, HTML_FILE)
        result = {}
        result["name"] = subdir
        result["result"] = main(args)
        results.append(result)

    # 生成聚合报告
    env = jinja2.Environment(
        loader=jinja2.FileSystemLoader(basedir),
        extensions=(),
        autoescape=True
    )
    template = env.get_template("summary_template.html")
    html = template.render({"results": results})

    output_file = os.path.join(logdir, "summary.html")
    with io.open(output_file, 'w', encoding="utf-8") as f:
        f.write(html)
    print(output_file)

猜你喜欢

转载自blog.csdn.net/x_xingduo_2315/article/details/123646198
今日推荐