Python+Selenium如何自动为截图添加测试名及参数ID/序号
问题:自动生成包含测试名+参数ID/序号的截图文件名
我正在学习基于Page Object模式的Python+Selenium测试编写,现有如下测试代码:
import pytest @pytest.mark.parametrize("first_name", [double_first_name, empty_form, long_first_name], ids=["double_first_name", "empty_form", "long_first_name"]) def test_reg_form_name(browser, first_name): passport_reg_page = RegForm(browser) passport_reg_page.go_to_site() passport_reg_page.reg_page() passport_reg_page.reg_first_name(first_name) passport_reg_page.reg_button() passport_reg_page = RegFormExpectations(browser) passport_reg_page.reg_expect_name() assert passport_reg_page.reg_expect_name() # 修正原代码中的变量名错误 browser.save_screenshot('screenshots/test_reg_1.png')
我希望截图名称能自动包含测试名+参数ID,或者至少包含测试名+参数运行序号,比如生成类似test_reg_form_name_double_first_name.png或test_reg_form_name_001.png这样的文件名。
曾尝试以下方法:
def test_name(self, request): testname = request.node.name return testname
但收到提示“Method 'test_name' may be 'static'”;另外,使用test_reg_page.__name__可获取函数名,但手动写入函数名意义不大。
解决方案
方法1:直接在测试函数中使用pytest的request fixture
pytest的request fixture可以直接获取当前测试的元数据,包括测试名称、参数ID、参数索引等,无需额外封装。
修改测试函数,添加request参数,然后构造文件名:
import pytest @pytest.mark.parametrize("first_name", [double_first_name, empty_form, long_first_name], ids=["double_first_name", "empty_form", "long_first_name"]) def test_reg_form_name(browser, first_name, request): passport_reg_page = RegForm(browser) passport_reg_page.go_to_site() passport_reg_page.reg_page() passport_reg_page.reg_first_name(first_name) passport_reg_page.reg_button() passport_reg_page = RegFormExpectations(browser) passport_reg_page.reg_expect_name() assert passport_reg_page.reg_expect_name() # 方案A:测试名+参数ID(处理掉括号特殊字符) test_full_name = request.node.name.replace("[", "_").replace("]", "") screenshot_path = f"screenshots/{test_full_name}.png" # 方案B:测试名+参数序号(格式化为3位数字) # test_name = request.node.function.__name__ # param_index = f"{request.node.callspec.index + 1:03d}" # 序号从1开始,补零到3位 # screenshot_path = f"screenshots/{test_name}_{param_index}.png" browser.save_screenshot(screenshot_path)
说明:
request.node.name返回完整测试标识(如test_reg_form_name[double_first_name]),替换括号后得到test_reg_form_name_double_first_namerequest.node.function.__name__可单独获取测试函数名test_reg_form_namerequest.node.callspec.index返回参数索引(从0开始),加1后格式化为3位数字,得到001、002这类序号
方法2:封装成可复用的工具函数
如果多个测试用例都需要生成这种命名的截图,可以把逻辑封装成工具函数,避免重复代码:
# 工具函数文件(比如utils.py) def get_screenshot_filename(request, use_id=True): """ 根据request生成截图文件名 :param request: pytest的request fixture :param use_id: 是否使用参数ID,False则使用参数序号 :return: 格式化后的文件名 """ test_name = request.node.function.__name__ if use_id: # 获取参数ID,替换特殊字符 param_id = request.node.callspec.id.replace("[", "_").replace("]", "") return f"{test_name}_{param_id}.png" else: # 获取参数序号,格式化为3位数字 param_index = f"{request.node.callspec.index + 1:03d}" return f"{test_name}_{param_index}.png"
然后在测试函数中调用:
from utils import get_screenshot_filename @pytest.mark.parametrize("first_name", [double_first_name, empty_form, long_first_name], ids=["double_first_name", "empty_form", "long_first_name"]) def test_reg_form_name(browser, first_name, request): # ... 测试逻辑 ... # 使用参数ID命名 screenshot_name = get_screenshot_filename(request) # 或者使用序号命名 # screenshot_name = get_screenshot_filename(request, use_id=False) browser.save_screenshot(f"screenshots/{screenshot_name}")
解决你之前的方法问题
你之前写的test_name函数提示“may be static”,是因为函数不需要self参数(只有类中的方法才需要self)。改成下面这样就可以正常使用:
def get_test_name(request): testname = request.node.name return testname
然后在测试函数中调用get_test_name(request)即可获取测试名+参数ID的字符串。
内容的提问来源于stack exchange,提问作者VladQA
相关产品推荐
相关产品推荐

