如何使用 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')



一只斗牛犬
浏览 99回答 2
2回答

守着星空守着你

conftest.py这是在 docker 容器中无头运行文件的完整解决方案:import timefrom datetime import datetime    import pytestimport osfrom selenium import webdriver as selenium_webdriverfrom 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 timedef 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")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python