Fourth, airtest generates aggregated reports

After undertaking the previous airtest batch run test cases, the running results need to be compiled into a report. This article explains the implementation of the report after the test.

The picture below is the report directory that comes with airtest. The report is under the root directory of airtest and integrates the bootstrap framework, so the self-contained report report interface is still pretty good.

The structure of the project looks like this:

 

The following is the implementation process:

1. Initialize the log in the runner. The format of the log is log_year-month-day_hour-minute-second. Returns the log name after initialization.

2. Create a log when the script is executed. Each use case corresponds to a log, and these logs will be traversed in the report later.

 3. The execution entry of report, in the execution entry, instantiate a command line parser, add parameters to the command line parser, the implementation method is get_parser, then get the root path and log folder of the log, and get the log file After folder, traverse all the logs inside, get the script and output log files respectively, and get the log results by executing the main method, and finally set the report template through jinjia.

 

Add parameters to the command line, mainly add script parameters, output file parameters, and some other parameter settings, and these parameters will be recorded in the report file.

4. Create a summary_template.html file in the root directory of the project. The content of the summary_template.html file is as follows, which is used to display the report template. 

 5. The main method calls the LogToHtml class of airtest's built-in report to parse and render the log into HTML. At the same time, bind the custom rewritten report method to the LogToHtml object of airtest.

 6. Customize the report method to modify the way to obtain info. Through customization, we can specify the information content we need. For example, here I have customized steps, name, scale, test_result and other content.

 The above is the whole process of the entire aggregation report, and finally attach the source code of the report, please learn by yourself if you need it:

# -*- 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)

Guess you like

Origin blog.csdn.net/x_xingduo_2315/article/details/123646198