WebDriver报错:AttributeError: 'NoneType'对象无get_screenshot_as_file属性
问题排查与解决:全局Driver截图时触发NoneType错误
问题根源
你的代码中出现AttributeError: 'NoneType' object has no attribute 'get_screenshot_as_file'的核心原因有两个:
- 当setup fixture执行失败(比如浏览器启动失败、指定了不支持的浏览器名称),全局
driver会保持初始的None值,此时hook触发截图操作就会调用空对象的方法报错。 - 全局变量的作用域在pytest的hook执行流程中存在不可控性,比如hook执行时机与fixture生命周期不匹配时,
driver可能还未完成初始化。
解决方案
方案1:从测试实例获取Driver(推荐,无全局变量依赖)
放弃全局driver,改为从测试用例的类实例中获取setup fixture注入的driver属性,逻辑更健壮,符合pytest的fixture设计规范:
修改pytest_runtest_makereport和_capture_screenshot函数:
@pytest.mark.hookwrapper def pytest_runtest_makereport(item): """ Extends the PyTest Plugin to take and embed screenshot in html report, whenever test fails. :param item: """ pytest_html = item.config.pluginmanager.getplugin('html') outcome = yield report = outcome.get_result() extra = getattr(report, 'extra', []) if report.when == 'call' or report.when == "setup": xfail = hasattr(report, 'wasxfail') if (report.skipped and xfail) or (report.failed and not xfail): file_name = report.nodeid.replace("::", "_") + ".png" # 从测试用例实例中获取driver driver = None if hasattr(item, 'instance'): driver = getattr(item.instance, 'driver', None) # 仅当driver存在时才执行截图 if driver: _capture_screenshot(driver, file_name) html = '<div><img src="%s" alt="screenshot" style="width:304px;height:228px;" ' \ 'onclick="window.open(this.src)" align="right"/></div>' % file_name extra.append(pytest_html.extras.html(html)) report.extra = extra def _capture_screenshot(driver, name): driver.get_screenshot_as_file(name)
方案2:修复全局变量逻辑(兼容原有写法)
如果坚持使用全局driver,需增加空值判断,并在setup fixture中处理异常场景:
- 修改setup fixture,确保无论初始化是否成功都能安全销毁driver:
@pytest.fixture(scope="class", autouse=True) def setup(request): global driver driver = None service_obj = Service("/Users/ibrahim/SeleniumProjects/BrowserDrivers/chromedriver") browser_name = request.config.getoption("browser_name") try: if browser_name == "chrome": driver = webdriver.Chrome(service=service_obj) elif browser_name == "safari": driver = webdriver.Safari() elif browser_name == "firefox": driver = webdriver.Firefox() if driver: driver.get("https://rahulshettyacademy.com/angularpractice/") driver.implicitly_wait(5) driver.maximize_window() request.cls.driver = driver yield finally: # 仅当driver存在时执行关闭操作 if driver: driver.close()
- 修改截图函数,增加空值判断:
def _capture_screenshot(name): global driver if driver is not None: driver.get_screenshot_as_file(name)
内容的提问来源于stack exchange,提问作者djoker
相关产品推荐
相关产品推荐

