← Python мануфактура

Після цього уроку ви зможете

Конспект і таймкоди

0:00

Чому вбудованої pytest-playwright fixture недостатньо

Проєкт сам контролює storage_state, авторизовані та Free contexts, відкриття й закриття page. Через це готові fixtures плагіна не покривають потрібний lifecycle, а tracing доводиться інтегрувати у власний шар.

Перед tracing виправляється побічна проблема: Free test відкривав два browser instances, бо вимагав fixture, результат якої не використовував. Видалення зайвої залежності прибирає другий запуск браузера.

Що змінилося після запису

Плагін уже має `retain-on-failure`

У відеоЧерез custom fixture architecture у відео вручну інтегровано tracing і pytest hook.

АктуальноПоточний pytest-playwright plugin підтримує --tracing retain-on-failure. Якщо тест використовує стандартні plugin fixtures, спершу варто перевірити цю option; custom hook потрібен, коли lifecycle контролюється власними fixtures.

Перевірено 2026-07-31

5:45

`yield` і життєвий цикл context

Fixture створює context, завантажує готовий state або виконує login і записує його, після чого віддає page через yield. Код після yield є teardown і закриває page/context.

Важливо повертати вже створену page, а не викликати new_page() ще раз. Так test actions, trace і cleanup належать одному browser context.

9:55

Перший варіант tracing і проблема дублювання

Запис запускається через context.tracing.start(screenshots=True, snapshots=True, sources=True), а перед закриттям context завершується tracing.stop(path=...). Trace Viewer показує Playwright actions, DOM snapshots, source files і network.

Якщо вставити start/stop у кожну низькорівневу fixture, код дублюється, а один session trace змішує кілька тестів. Tracing переноситься у test-scoped app fixtures, щоб кожен тест мав окремий lifecycle.

Термін

Playwright trace

Артефакт із recorded browser actions, DOM snapshots, network і source context, який відкривається в Trace Viewer.

15:15

Окремий ZIP на основі pytest `request`

Built-in fixture request надає request.node.name, тому trace можна назвати ім’ям конкретного тесту й зберігати в test-results/traces/<test>.zip. Це робить артефакт однозначним і придатним для CI.

ZIP відкривається командою playwright show-trace <path>. На timeline видно переходи, clicks, fills, assertions, snapshots, network і Python sources, що дає більше діагностичної інформації, ніж відео самого браузера.

21:55

Чому зберігати лише failed traces

Trace для кожного успішного тесту швидко збільшує обсяг CI artifacts. Простий варіант «зберігати все» допустимий для малого набору з коротким retention, але кращий контракт — залишати ZIP лише коли тест упав.

Артефакт має жити достатньо, щоб інженер устиг провести root-cause analysis. Retention і upload налаштовуються на рівні CI; сама fixture відповідає лише за локальне створення файлу.

Термін

retain-on-failure

Поточна pytest-playwright CLI option для запису trace кожного тесту й видалення запису після успішного завершення.

25:45

`pytest_runtest_makereport` і фази виконання

Fixture не знає результат тесту напряму, тому conftest.py підключає hook pytest_runtest_makereport. Hook отримує звіт для кожної фази та записує його в атрибут node, наприклад rep_setup, rep_call, rep_teardown.

Для assertion failure самого тесту перевіряється request.node.rep_call.failed. setup охоплює код до yield, call — тіло тесту, teardown — код після yield. Якщо потрібно зберігати trace також при fixture setup failure, це окреме розширення контракту; демонстрація фокусується на call.

Що змінилося після запису

Актуальний pytest pattern використовує `item.stash`

У відеоУ відео phase reports записуються як динамічні attributes на test node, наприклад rep_call.

АктуальноПоточний official pytest example використовує typed StashKey та item.stash. Manual Playwright tracing також не записує pytest assertion як traced action; він показує browser context навколо failure.

Перевірено 2026-07-31

Термін

pytest_runtest_makereport

pytest hook, який формує TestReport для фаз setup, call і teardown; custom fixture може використати report для рішення про artifact retention.

Приклад коду

Збереження reports на pytest node

from typing import Dict

import pytest
from _pytest.reports import TestReport
from _pytest.stash import StashKey

phase_reports_key = StashKey[Dict[str, TestReport]]()

@pytest.hookimpl(wrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
    report = yield
    item.stash.setdefault(phase_reports_key, {})[report.when] = report

Зберігає reports фаз у typed pytest stash, щоб teardown fixture могла перевірити failure потрібної фази.

Очікуваний результат: Після фази call item.stash[phase_reports_key]["call"] містить відповідний TestReport.

Потрібно: pytest

30:45

`get_or_create_context` без дублювання

Звичайний і Free flows дублювали перевірку state path, options для new_context, login та повернення page. Спільна функція get_or_create_context будує context і повідомляє, чи потрібна авторизація.

Верхні fixtures залишають предметні кроки: звичайна зберігає авторизований state; Free додатково перемикає проєкт і зберігає Free state. Спільний helper не повинен поглинати ці відмінності лише заради меншої кількості рядків.

35:55

Мінімальна tracing fixture і перевірка green path

Tracing helpers приймають page.context, тому app fixture не мусить окремо повертати context. start_tracing() централізує options, а stop_tracing_on_failure() або записує ZIP, або зупиняє tracing без path.

Після рефакторингу запускаються Free та Enterprise тести. Вони проходять, а папка traces залишається порожньою — це позитивна перевірка, що successful tests не створюють артефакт.

Увага

Перевірте обидві гілки retention

Green test не повинен залишати ZIP, а навмисний assertion failure має створити один trace з назвою конкретного тесту.

Практика

Red/green перевірка trace retention

  1. Запустіть один green test і переконайтеся, що ZIP не створено.
  2. Тимчасово зробіть його assertion неправильним і повторіть запуск.
  3. Відкрийте єдиний ZIP через playwright show-trace, після чого поверніть тест у green state.

Результат: Green path не створює trace; failure path створює один читабельний artifact для потрібного test ID.

39:40

Навмисний failure і перевірка Trace Viewer

Один locator навмисно змінюється на неправильний. Тест падає, з’являється ZIP із назвою тесту, а Trace Viewer показує останній успішний крок і assertion, який не знайшов очікуваний елемент.

Після доказу failure path тимчасову помилку треба прибрати й повернути suite у green state. Завершена зміна комітиться в окремій гілці; у командній роботі вона проходить pull request, а не пряме злиття без review.

Джерела та додаткові матеріали

  • Playwright Trace Viewer ↗Microsoft Playwright · перевірено 2026-07-31

    Підтверджує й актуалізує поняття уроку, пов’язані з Playwright trace.

  • pytest reports in fixtures ↗pytest project · перевірено 2026-07-31

    Підтверджує й актуалізує поняття уроку, пов’язані з pytest_runtest_makereport.

  • Playwright Pytest Plugin Reference ↗Microsoft Playwright · перевірено 2026-07-31

    Підтверджує й актуалізує поняття уроку, пов’язані з retain-on-failure.