如何将失败场景截图嵌入Behave的JSON/HTML测试报告?
我来帮你搞定这个问题——把失败场景的截图嵌入到Behave的HTML或JSON报告里其实有几种靠谱的方式,我分两种报告类型给你详细拆解:
Behave自带的HTML报告支持直接附加图片,咱们只需要修改after_scenario钩子,在保存截图的同时把它附加到报告中就行:
首先,先确保截图目录存在(避免报错),可以在before_all里加一段创建目录的代码:
def before_all(context): import os os.makedirs("failed_scenarios_screenshots", exist_ok=True)
然后修改你的after_scenario函数,新增附件逻辑:
import datetime def after_scenario(context, scenario): if scenario.status == "failed": time_now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") screenshot_filename = f"{scenario.name}_{time_now}_failed.png" screenshot_path = f"failed_scenarios_screenshots/{screenshot_filename}" # 保存截图到本地 context.browser.save_screenshot(screenshot_path) # 将截图附加到Behave报告 with open(screenshot_path, "rb") as img_file: context.attach( img_file.read(), content_type="image/png", name=screenshot_filename )
最后运行Behave时指定生成HTML报告:
behave -f html -o test_report.html
打开生成的test_report.html,找到失败的场景,你会看到一个「Attachments」区域,点击里面的截图文件名就能直接查看图片了。如果想要更定制化(比如把截图直接显示在报告正文里),可以复制Behave默认的HTML模板,修改模板代码在失败场景区块添加<img>标签调用附件内容,不过大部分场景用默认的附加功能就足够了。
JSON报告的处理分两种情况,取决于你想把截图内容直接嵌入JSON,还是只存文件路径:
方式1:嵌入Base64编码的截图(默认方案)
同样用context.attach方法,Behave的默认JSON报告器会自动把图片转成Base64编码并添加到报告的attachments字段中。代码和上面HTML的after_scenario完全一样,只需要运行时指定JSON输出:
behave -f json -o test_report.json
打开JSON文件后,失败场景对应的节点下会有attachments数组,包含图片的Base64数据、类型和文件名,适合需要把报告和截图打包传输的场景。
方式2:仅存储截图文件路径(适合大截图)
如果截图体积较大,嵌入Base64会让JSON文件变得臃肿,这时候可以自定义一个JSON报告器,只把截图路径写入报告:
- 创建一个自定义格式化器文件
custom_json_formatter.py:
from behave.formatter.json import JSONFormatter class CustomJSONFormatter(JSONFormatter): def scenario_end(self, scenario): # 先调用父类方法完成基础JSON结构 super().scenario_end(scenario) # 从scenario的自定义数据中获取截图路径 screenshot_path = scenario.user_data.get("screenshot_path") if screenshot_path: # 把路径添加到当前场景的JSON节点中 self.current_feature["elements"][-1]["screenshot_path"] = screenshot_path
- 修改
after_scenario,把截图路径存入scenario.user_data:
def after_scenario(context, scenario): if scenario.status == "failed": time_now = datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S") screenshot_filename = f"{scenario.name}_{time_now}_failed.png" screenshot_path = f"failed_scenarios_screenshots/{screenshot_filename}" context.browser.save_screenshot(screenshot_path) # 把路径存入scenario的自定义数据 scenario.user_data["screenshot_path"] = screenshot_path
- 运行Behave时指定自定义格式化器:
behave -f custom_json_formatter.CustomJSONFormatter -o test_report.json
这样生成的JSON报告里,失败场景节点会多一个screenshot_path字段,直接指向本地截图文件的位置。
内容的提问来源于stack exchange,提问作者Den Silver

