Cara mengambil tangkapan layar pada kegagalan kasus uji dengan PyTest

Saat ini saya menggunakan solusi berikut untuk mengambil tangkapan layar di akhir setiap fungsi pengujian dengan PyTest. Bagaimana cara memastikan bahwa tangkapan layar diambil hanya jika pengujian gagal? Ini adalah pertanyaan tentang mekanisme PyTest. Pertanyaan ini BUKAN tentang selenium atau appium.

Saya menemukan pertanyaan serupa di sini di Stackoverflow, tapi tidak persis sama. Solusi yang diberikan untuk pertanyaan-pertanyaan lain tidak menjawab pertanyaan saya. Karena mengambil tangkapan layar pada kegagalan pengujian dengan PyTest adalah masalah umum, saya yakin masalah ini memerlukan jawaban terpisah dan cukup spesifik.

@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')

person Ostap Didenko    schedule 13.02.2020    source sumber
comment
Ini adalah topik yang cukup populer dan disebutkan beberapa kali di dokumen. Contoh perlengkapan: Pembuatan informasi hasil tes tersedia di perlengkapan, contoh kait: laporan/kegagalan pengujian pascaproses.   -  person hoefling    schedule 13.02.2020
comment
Saya menemukan artikel-artikel itu, namun solusinya tidak begitu mudah untuk masalah saya. Saya percaya, karena ini adalah masalah yang cukup umum, lebih baik untuk memberikan jawaban yang spesifik dan langsung pada sasaran serta semacam katalog praktik terbaik.   -  person Ostap Didenko    schedule 18.02.2020


Jawaban (2)


Berikut adalah solusi lengkap untuk file conftest.py Anda untuk menjalankannya tanpa kepala di wadah buruh pelabuhan:

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)
person Ostap Didenko    schedule 10.05.2020

Ada cara lain, mirip dengan yang dilakukan oleh @Ostap: menggunakan pytest_runtest_makereport (dokumen, referensi API ) kemampuan pascapemrosesan. Sedikit lebih sederhana:

@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")
person Mate Mrše    schedule 20.04.2021