如何将fixture对象传入pytest_runtest_makereport实现失败用例自动截图?
解决方案
1. 单个测试文件中能否直接使用pytest_runtest_makereport
可以,pytest支持在测试脚本内直接定义钩子函数,不需要强制将钩子放到conftest.py文件中,你当前的定义方式是符合规范的。
2. 如何在钩子中获取fixture生成的driver实例
你当前代码报错的原因是pytest_runtest_makereport钩子的作用域内不存在mydriver变量。fixture生成的实例会存储在测试用例对象item的funcargs属性中,你可以通过item.funcargs['driver']直接获取当前测试用例对应的driver实例。
修改后的完整代码
import time from appium import webdriver import pytest # yield_fixture已废弃,改用标准fixture装饰器即可支持yield语法 @pytest.fixture(scope="function") def driver(): """测试前置准备""" desired_caps = {} desired_caps['platformName'] = 'Android' desired_caps['platformVersion'] = '11.0' desired_caps['deviceName'] = 'Samsung Galaxy A70' desired_caps['appPackage'] = 'com.example.mapkitbaseline' desired_caps['appActivity'] = 'com.example.mapkitbaseline.ui.CreationMapActivity' mydriver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps) yield mydriver mydriver.quit() def test_func1(driver): """测试HMS MapKit演示应用""" driver.implicitly_wait(30) time.sleep(5) elmnt = driver.find_element_by_id('com.example.mapkitbaseline:id/btnMapCreation4') assert elmnt.get_attribute('text').lower() == "supportmapfragmentfffffffffx" print(elmnt.get_attribute('text')) @pytest.mark.hookwrapper def pytest_runtest_makereport(item, call): pytest_html = item.config.pluginmanager.getplugin('html') outcome = yield report = outcome.get_result() extra = getattr(report, 'extra', []) if report.when == "call": xfail = hasattr(report, 'wasxfail') if (report.skipped and xfail) or (report.failed and not xfail): # 仅对使用了driver fixture的用例执行截图逻辑,避免报错 if 'driver' in item.funcargs: driver = item.funcargs['driver'] screenshot = driver.get_screenshot_as_base64() extra.append(pytest_html.extras.image(screenshot, '失败用例截图')) report.extra = extra
注意事项
- 代码中加了
if 'driver' in item.funcargs的判断,避免后续新增不需要driver的测试用例时钩子执行报错 - 原代码中
@pytest.mark.usefixtures("driver")可以省略,因为测试用例参数已经显式传入了driver,会自动加载fixture
内容的提问来源于stack exchange,提问作者Yavuz Yoldaş
相关产品推荐
相关产品推荐

