尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

8. 一键出报告,结果填入HTML模板

8. 一键出报告,结果填入HTML模板 配套动画视频在《8. 一键出报告结果填入HTML模板》源代码在《评论区置顶》。截图有了还差一份能打开看的测试报告。这一节把结果填进 HTML 模板先声明工具入参再把输出路径和截图路径规范到工程内有 test_results.json 就读并合并用例截图没有则从文本里解析总计/通过/失败。接着用 Jinja2 把结果填进 templates/report_template.html写出能本地打开的网页并返回通过率任一步异常则返回错误信息。模板要用到 Jinja2提前装好即可pip install Jinja2先定义工具入参test_output 是结果文本output_path 是报告保存路径screenshots 是截图路径列表。调用时要把截图路径传进来否则报告里看不到图。工具名是 generate_test_reportAgent 按这个名字调用class GenerateReportInput(BaseModel): test_output: str Field(description测试输出结果) screenshots: list Field(default_factorylist, description截图路径列表) output_path: str Field(description报告保存路径) class GenerateReportTool(BaseTool): name: str generate_test_report description: str 根据测试结果生成HTML测试报告 args_schema: Type[BaseModel] GenerateReportInput_run 里先做路径规范化。传入的路径可能是 /testcases/...也可能是相对路径。用 _resolve 统一成工程根目录下的绝对路径截图列表里每一项同样处理。screenshots 为 None 时按空列表处理。整个 _run 包在 try/except 里任一步异常都返回错误信息def _run(self, test_output: str, output_path: str, screenshots: list None) - str: base_dir os.path.dirname(os.path.abspath(__file__)) def _resolve(path): if path.startswith(/): return os.path.normpath(os.path.join(base_dir, path.lstrip(/))) return path if os.path.isabs(path) else os.path.normpath( os.path.join(base_dir, path)) output_path _resolve(output_path) if screenshots is None: screenshots [] screenshots [_resolve(s) for s in screenshots]取数时优先看 testcases/test_results.json。有就 json.load并把每个用例 screenshots 里的 path 合并进截图列表。没有 JSON就调用 _parse_output 从 test_output 文本里解析总计、通过和失败results_file os.path.join(base_dir, testcases, test_results.json) if os.path.exists(results_file): with open(results_file, r, encodingutf-8) as f: test_results json.load(f) for tc in test_results.get(test_cases, []): for s in tc.get(screenshots, []): p s.get(path) if isinstance(s, dict) else s if p and p not in screenshots: screenshots.append(p) else: test_results self._parse_output(test_output)渲染阶段根据 passed/total 算通过率 rate把外部传入的 screenshots 与各用例内截图去重合并成 all_shots用 FileSystemLoader 加载 templates/report_template.html把 results、rate、type_labels、all_shots、report_dir 和 to_relative_path 传给模板。to_relative_path 把截图绝对路径转成相对报告文件的路径并把反斜杠换成 /本地打开 HTML 时图片才能显示report_dir os.path.dirname(os.path.abspath(output_path)) rate (results[passed] / results[total] * 100) if results[total] 0 else 0 type_labels {before: 测试前, after: 测试后, failed: 失败时, error: 错误时, step: 步骤截图} all_shots [] seen set() for s in screenshots: if s not in seen: all_shots.append(s) seen.add(s) template_dir os.path.join(os.path.dirname(os.path.abspath(__file__)), templates) env Environment(loaderFileSystemLoader(template_dir)) template env.get_template(report_template.html) def to_relative_path(abs_path: str, base_dir: str) - str: try: rel os.path.relpath(abs_path, base_dir) return rel.replace(\\, /) except Exception: return abs_path.replace(\\, /) html template.render( resultsresults, raterate, type_labelstype_labels, all_shotsall_shots, report_dirreport_dir, to_relative_pathto_relative_path) return html最后调用 _build_html 得到完整 HTML 字符串确保输出目录存在再写入 output_path。返回值带上总计、通过、失败和通过率中间抛异常时返回「生成报告失败…」html self._build_html(test_results, screenshots, output_path) output_file Path(output_path) output_file.parent.mkdir(parentsTrue, exist_okTrue) with open(output_file, w, encodingutf-8) as f: f.write(html) total test_results.get(total, 0) passed test_results.get(passed, 0) failed test_results.get(failed, 0) rate (passed / total * 100) if total 0 else 0 return f报告生成成功{output_path}\n总计:{total} 通过:{passed} f失败:{failed} 通过率:{rate:.1f}%要把启停截图和出报告串起来可以用 open_app_screenshot_close_report先调用 open_app_screenshot_close 拿到 shot_path再拼一份单用例结构的 test_results 写入 test_results.json最后调用 GenerateReportTool._runscreenshots 参数带上 [shot_path]报告页面里才会有这张图shot_path open_app_screenshot_close(screenshot_path) passed 1 if shot_path else 0 failed 0 if shot_path else 1 case_shots [] if shot_path: case_shots.append({type: step, label: app_screenshot, path: shot_path}) test_results { total: 1, passed: passed, failed: failed, test_cases: [{ case_id: TC_OPEN_SHOT_CLOSE, case_name: 启动App截图关闭, status: passed if shot_path else failed, screenshots: case_shots, }], } with open(results_file, w, encodingutf-8) as f: json.dump(test_results, f, ensure_asciiFalse, indent2) shot_list [shot_path] if shot_path else [] report_msg GenerateReportTool()._run(, report_path, shot_list)这样从启停截图到 HTML 报告就接上了本地打开报告文件就能看到通过率和对应截图。配套动画视频在《8. 一键出报告结果填入HTML模板》源代码在《评论区置顶》。
返回列表