[英]How to capture screenshot on test case failure with PyTest
目前,我正在使用以下解決方案在 PyTest 的每個測試函數結束時截取屏幕截圖。 如何確保僅在測試失敗的情況下才截取屏幕截圖? 這是一個關於 PyTest 機制的問題。 這個問題與硒或 appium 無關。
我在 Stackoverflow 上發現了類似的問題,但並不完全相同。 為其他問題提供的解決方案不能回答我的問題。 由於使用 PyTest 截取測試失敗的屏幕截圖是一個常見問題,因此我認為它值得一個單獨且非常具體的答案。
@pytest.fixture(scope="function", autouse=True)
def take_screenshot(self, appium_driver):
yield
time.sleep(1)
current_filename_clean = os.path.basename(__file__).replace("test_", "").replace(".py", "")
current_test_name = os.environ.get("PYTEST_CURRENT_TEST").split(":")[-1].split(" ")[0].replace("test_", "")
appium_driver.get_screenshot_as_file(
f'test_reports/{current_filename_clean}_android_{current_test_name}_{datetime.today().strftime("%Y-%m-%d")}.png')
這是conftest.py
文件的完整解決方案,用於在conftest.py
容器中無頭運行:
import time
from datetime import datetime
import pytest
import os
from selenium import webdriver as selenium_webdriver
from selenium.webdriver.chrome.options import Options
# set up webdriver fixture
@pytest.fixture(scope='session')
def selenium_driver(request):
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = selenium_webdriver.Chrome(options=chrome_options)
driver.set_window_size(1920, 1080)
driver.maximize_window()
driver.implicitly_wait(5)
yield driver
driver.quit()
# set up a hook to be able to check if a test has failed
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
# execute all other hooks to obtain the report object
outcome = yield
rep = outcome.get_result()
# set a report attribute for each phase of a call, which can
# be "setup", "call", "teardown"
setattr(item, "rep_" + rep.when, rep)
# check if a test has failed
@pytest.fixture(scope="function", autouse=True)
def test_failed_check(request):
yield
# request.node is an "item" because we use the default
# "function" scope
if request.node.rep_setup.failed:
print("setting up a test failed!", request.node.nodeid)
elif request.node.rep_setup.passed:
if request.node.rep_call.failed:
driver = request.node.funcargs['selenium_driver']
take_screenshot(driver, request.node.nodeid)
print("executing test failed", request.node.nodeid)
# make a screenshot with a name of the test, date and time
def take_screenshot(driver, nodeid):
time.sleep(1)
file_name = f'{nodeid}_{datetime.today().strftime("%Y-%m-%d_%H:%M")}.png'.replace("/","_").replace("::","__")
driver.save_screenshot(file_name)
還有另一種方法,類似於@Ostap 的方法:使用pytest_runtest_makereport
( 文檔, API 參考)后處理功能。 簡單一點:
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
outcome = yield
rep = outcome.get_result()
if rep.when == 'call' and rep.failed:
now = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
driver.save_screenshot(f".\\Screenshots\\fail_{now}.png")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.