如何在自动化测试失败截图中标记失败区域(添加矩形框)
在Allure失败截图中添加标记/矩形框的解决方案
要给失败用例的截图添加标记(比如红色矩形框),核心是将浏览器截图转为可编辑图像,定位失败元素坐标后用绘图工具添加标记,再将修改后的图像附加到Allure报告中。以下是具体实现步骤:
1. 安装依赖
需要用到Pillow库处理图像,执行安装命令:
pip install pillow
2. 修改conftest.py中的截图逻辑
更新log_on_failure fixture,添加图像编辑和画框逻辑:
from PIL import Image, ImageDraw import io import time import pytest import allure from allure_commons.types import AttachmentType from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium import webdriver @pytest.hookimpl(hookwrapper=True, tryfirst=True) def pytest_runtest_makereport(item, call): outcome = yield rep = outcome.get_result() setattr(item, "rep_" + rep.when, rep) return rep @pytest.fixture() def log_on_failure(request, setup_teardown): yield item = request.node driver = setup_teardown if item.rep_call.failed: # 获取原始截图并转为PIL图像对象 screenshot_bytes = driver.get_screenshot_as_png() img = Image.open(io.BytesIO(screenshot_bytes)) draw = ImageDraw.Draw(img) # 检查是否有失败元素记录,有则画红色矩形框 if hasattr(item, 'failed_element'): element = item.failed_element # 滚动到元素可见位置(避免元素在视口外) driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element) # 获取元素坐标和尺寸 rect = element.rect left, top = rect['x'], rect['y'] right, bottom = left + rect['width'], top + rect['height'] # 绘制红色矩形,线宽5 draw.rectangle([left, top, right, bottom], outline='red', width=5) # 将修改后的图像转为字节流 modified_screenshot = io.BytesIO() img.save(modified_screenshot, format='PNG') modified_screenshot.seek(0) # 附加到Allure报告 allure.attach( modified_screenshot.getvalue(), name=f"Fail_{request.function.__name__}_{time.strftime('%y_%m_%d_%H_%M')}", attachment_type=AttachmentType.PNG ) @pytest.fixture(params=["chrome"], scope="function") def setup_teardown(request): driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) driver.get(read_configuration("info", "site_url")) # 假设read_configuration是你的配置读取方法 request.cls.driver = driver driver.maximize_window() yield driver driver.quit()
3. 更新POM类的断言方法
在页面对象的断言方法中,当断言失败时将当前元素记录到测试节点:
from selenium.webdriver.common.by import By class MainHeader: def __init__(self, driver): self.driver = driver # 定义页面元素定位(根据实际项目调整) self.website_icon = driver.find_element(By.CSS_SELECTOR, ".header-icon") self.chatai_btn = driver.find_element(By.ID, "chatai-link") self.search_field = driver.find_element(By.NAME, "search") self.search_btn = driver.find_element(By.CSS_SELECTOR, ".search-btn") self.login_btn = driver.find_element(By.CLASS_NAME, "login-btn") def website_icon_is_displayed(self, test_node): try: assert self.website_icon.is_displayed() except AssertionError: test_node.failed_element = self.website_icon raise def chatai_is_displayed(self, test_node): try: assert self.chatai_btn.is_displayed() except AssertionError: test_node.failed_element = self.chatai_btn raise def search_field_is_displayed(self, test_node): try: assert self.search_field.is_displayed() except AssertionError: test_node.failed_element = self.search_field raise def search_button_displayed_and_able(self, test_node): try: assert self.search_btn.is_displayed() and self.search_btn.is_enabled() except AssertionError: test_node.failed_element = self.search_btn raise def login_button_displayed_and_able(self, test_node): try: assert self.login_btn.is_displayed() and self.login_btn.is_enabled() except AssertionError: test_node.failed_element = self.login_btn raise
4. 修改测试类传递测试节点
在测试方法中传入request对象,传递给POM的断言方法:
import pytest import allure from allure_commons.types import Severity @pytest.mark.usefixtures("setup_teardown", "log_on_failure") class TestMain: @allure.severity(Severity.NORMAL) def test_check_header_items(self, request): main = MainHeader(self.driver) main.website_icon_is_displayed(request.node) main.chatai_is_displayed(request.node) main.search_field_is_displayed(request.node) main.search_button_displayed_and_able(request.node) main.login_button_displayed_and_able(request.node)
注意事项
- 如果失败场景不是元素断言(比如页面跳转失败),则不会添加标记,直接使用原始截图
- 使用
element.rect获取坐标比location更准确,避免因浏览器视口差异导致的框位偏移 - 截图前滚动元素到视口中心,确保标记区域在截图范围内
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

