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

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

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

0:00

Навіщо майструвати IDE під себе

Можливості IDE варто сприймати як частину інженерної практики, а не як набір необов’язкових трюків. Скорочення й шаблони допомагають стандартизувати повторювані дії так само, як KISS, DRY, YAGNI, патерни та SOLID стандартизують роботу з кодом.

На відміну від генерації коду за допомогою ШІ, налаштована команда IDE виконує наперед визначене перетворення. Вона не вигадує API й щоразу дає той самий результат. Перш ніж додавати автоматизацію, корисно певний час писати конструкції вручну: це формує розуміння функцій, викликів, контексту й оператора ..

1:23

Безпечний рефакторинг і навігація

На прикладі повторюваних рядків показано Refactor → Introduce Variable: PyCharm створює змінну з виділеного виразу й може замінити всі його входження. У демонстрації на macOS використовується ⌘⌥V; на Windows або Linux слід дивитися актуальне скорочення безпосередньо в меню IDE. Так само винесено повторювані значення classical і BDD у зрозуміло названі змінні.

IDE підсвічує невикористаний код сірим, тому зайві параметри й імпорти можна швидко знаходити та видаляти. Окрема команда оптимізує імпорти після змін.

Для навігації показано:

- ⌘B — перейти до оголошення або реалізації символу під курсором;
- ⌘⌥← і ⌘⌥→ — повернутися до попереднього місця редагування або перейти вперед;
- перехід на початок чи кінець рядка замість ручного руху курсора.

Головна звичка: спочатку шукати дію в контекстному меню й дивитися її назву та скорочення, а вже потім за потреби змінювати keymap.

Увага

Shortcuts залежать від keymap

Комбінації клавіш у відео показані на macOS і частково налаштовані автором. Знаходьте дію за назвою в меню або Settings → Keymap і перевіряйте локальну комбінацію та конфлікти.

5:15

Швидкий шлях від DOM до локатора

У браузерних DevTools вмикається режим вибору елемента на сторінці. Після кліку потрібний вузол одразу знаходиться в HTML, де можна перевірити унікальність майбутнього селектора. У прикладі селектор має знаходити рівно один елемент.

Ручний процес — скопіювати значення, повернутися в PyCharm і загорнути його в page.locator(...) — повторюється багато разів. Це хороший кандидат для локального шаблону: структура виклику стабільна, а змінюється лише селектор.

7:07

Власні postfix templates для Playwright

Postfix Completion налаштовується через Settings (⌘, на macOS). Postfix template застосовується до виразу ліворуч від крапки. Спеціальна змінна $EXPR$ означає цей вираз, а $END$ визначає, де залишиться курсор після розгортання.

Створено кілька Python-шаблонів:

- "selector".locator перетворює селектор на page.locator("selector");
- вираз із postfix expect обгортається в expect(...);
- скорочений варіант на кшталт expvis одразу створює expect(...).to_be_visible().

Під час першого налаштування locator вираз помилково був додатково взятий у лапки, через що PyCharm формував неправильний код. Після виправлення $EXPR$ підставляється як готовий вираз. Це важливе правило: шаблон має додавати лише відсутню структуру, а не повторно форматувати вже валідний фрагмент.

Такий ланцюжок скорочує типовий шлях до перевірки: знайти селектор, вставити його як рядок, застосувати .locator, а потім .expvis. Результат детермінований і не потребує повторної перевірки припущень генеративної моделі.

Термін

Postfix template

Шаблон PyCharm, який за ключем після крапки перетворює вже введений вираз з урахуванням його типу та контексту.

Термін

$EXPR$ і $END$

$EXPR$ підставляє вираз, до якого застосовано custom postfix template; $END$ задає позицію курсора після завершення перетворення.

Приклад коду

Target expression для postfix locator

page.locator($EXPR$)$END$

Мінімальна target expression для custom postfix template: готовий вираз підставляється через $EXPR$, а курсор після розгортання переходить у $END$.

Очікуваний результат: Вираз ліворуч від postfix перетворюється на аргумент page.locator(...).

Потрібно: PyCharm with Python support

Практика

Створити два postfix templates

  1. Створіть Python postfix template locator, який обгортає вираз у page.locator(...).
  2. Створіть postfix template expvis для expect(...).to_be_visible().
  3. Перевірте обидва шаблони на трьох різних селекторах і переконайтеся, що лапки не дублюються.

Результат: Кожен шаблон стабільно створює синтаксично валідний Python-код, а курсор залишається в очікуваному місці.

13:05

Змінні, intention actions і Extract Method

Окремий postfix template експериментально перетворює вираз на присвоєння змінній. Він корисний лише тоді, коли справді економить дії; якщо шаблон незручно визначає позицію курсора або працює не для всіх виразів, його краще спростити чи не використовувати.

⌥Enter відкриває intention actions для поточного контексту. У меню можна рухатися клавішами й вибирати, наприклад, перейменування елемента. Перейменування через IDE змінює всі пов’язані входження, тому безпечніше за ручний пошук і заміну.

Refactor → Extract Method (⌘⌥M у показаному keymap) переносить виділений фрагмент у новий метод. PyCharm визначає потрібні аргументи й можливі значення, що повертаються. У прикладі перевірки кнопки винесено в check_manage_button, після чого до викликів усередині методу додано self. Це спосіб прибрати дублювання на рівні поведінки, не переписуючи код вручну.

Практичне зауваження з демонстрації: to_have_text() не варто вважати повною заміною перевірки видимості. Якщо видимість є окремою вимогою сценарію, її треба перевіряти явно.

18:14

Власні скорочення для створення файлів

Створення Page Object постійно починається з нового Python-файлу. У Project view командою ⌘N відкривається меню New, яке можна фільтрувати простим набором Python і вибрати Python File або Python Package без мишки.

Щоб скоротити шлях ще більше, у Settings → Keymap знайдено відповідні дії й призначено власні комбінації: одну для Python-файлу, іншу для Python-пакета. Конкретні клавіші не є універсальним стандартом — їх слід обирати під власну ОС і перевіряти на конфлікти в keymap.

У меню створення також видно вбудовані шаблони на кшталт Python unit test. Вони демонструють наступний рівень автоматизації: IDE може створювати не порожній файл, а одразу потрібну початкову структуру.

21:24

File template для Page Object

Page Object і Page Component мають повторювану основу: імпорти Playwright, клас, __init__, збереження page, базову перевірку завантаження та часто return self. Замість копіювання цієї «шапки» створено власний шаблон у Settings → Editor → File and Code Templates.

У file template змінна ${NAME} підставляє назву, яку вводять під час створення файлу. Після збереження в меню New з’являється окремий тип Page Object; вибір цього пункту створює клас з підготовленими імпортами й методами.

Під час live coding шаблон кілька разів виправляється: додаються пропущені self, закривається дужка, коригуються відступи. Це нормальний цикл налаштування: створити пробний файл, дочекатися синтаксичних та інспекційних підказок IDE, виправити шаблон і повторити генерацію. Перевіряти потрібно саме згенерований файл, а не лише текст у вікні налаштувань.

Оскільки поточні Page Object і Page Component мають однакову основу, одного file template достатньо. Окремі шаблони варто додавати лише тоді, коли їхня структура реально розійдеться.

Термін

File template

Шаблон PyCharm для створення нового файла з визначеними назвою, розширенням і початковим вмістом. Project-scoped templates зберігаються в .idea/fileTemplates і можуть бути спільними для команди.

Практика

Створити file template для Page Object

  1. Створіть custom file template з імпортом Page, класом, __init__, self.page і return self.
  2. Використайте ${NAME} для назви створюваного класу або файла.
  3. Створіть пробний Page Object і виправте всі syntax та inspection errors у самому шаблоні.

Результат: Новий Page Object створюється одним пунктом меню та не містить syntax або unresolved reference errors.

27:20

Локатори й доступність у реальному інтерфейсі

Під час пошуку елементів для наступного тесту видно, наскільки якість HTML впливає на автоматизацію. У модальному вікні частина елементів не має зручних семантичних ознак, стабільних назв або доступних ролей. Через це доводиться розглядати id, текст, структуру div і Accessibility Tree.

Кращий локатор спирається на доступну роль, ім’я або іншу стабільну продуктову ознаку. CSS-класи оформлення, випадкові вкладені контейнери й пробіли в тексті — крихка основа. Якщо елемент важко однозначно знайти, це може бути не лише проблемою тесту, а й сигналом недостатньої доступності чи тестованості інтерфейсу.

Після дослідження обирається невеликий реальний сценарій: створити сутність через кнопку, заповнити назву й перевірити наступний стан. Саме повторювані частини цього сценарію далі перетворюються на live templates.

Термін

Role locator

Playwright locator, який знаходить елемент за доступною роллю та зазвичай accessible name. Офіційна документація радить пріоритезувати user-facing attributes і explicit contracts на кшталт get_by_role().

Приклад коду

Role locator і видимість діалогу

from playwright.sync_api import Page, expect

def test_create_suite_dialog(page: Page) -> None:
    page.get_by_role("button", name="Create suite").click()
    expect(page.get_by_text("Select suite for test")).to_be_visible()

Мінімальний приклад Codex на основі актуального Playwright contract: інтерактивна кнопка знаходиться за role та accessible name, а неінтерактивний текст перевіряється через get_by_text().

Очікуваний результат: Після кліку на Create suite текст Select suite for test стає видимим.

Потрібно: pytest, pytest-playwright, playwright

Практика

Замінити крихкий локатор на user-facing locator

  1. Знайдіть у власному тесті інтерактивний елемент, який зараз шукається за CSS-класом або вкладеною структурою.
  2. Перевірте його role та accessible name у Accessibility Tree.
  3. Замініть локатор на get_by_role(..., name=...) і запустіть цільовий тест.

Результат: Локатор однозначно знаходить потрібний елемент, а тест проходить без nth(), first або прив’язки до CSS оформлення.

32:20

Live templates для методів і повторюваних блоків

На відміну від postfix template, Live Template розгортається в місці курсора з короткої абревіатури. У Settings створюється окрема група шаблонів для проєкту або Playwright, а контекст обмежується Python-файлами. Це не дає шаблону випадково з’являтися в нерелевантних типах файлів.

У шаблоні методу використовуються змінні для назви функції, аргументів або локатора та $END$ для фінальної позиції курсора. Після розгортання Tab переходить між редагованими полями. Якщо автоматичне перетворення назви в snake_case не працює передбачувано, простіше залишити явне введення назви, ніж ускладнювати шаблон.

На основі реального сценарію створено заготовку методу, який приймає дані, знаходить елемент через self.page.locator(...), виконує дію й повертає self. Потім метод перейменовується рефакторингом IDE, щоб назва оновилась і в оголошенні, і у виклику.

Термін

Live template

Шаблон коду, який вставляє наперед визначену конструкцію в позиції курсора; на відміну від postfix completion, він не потребує наявного виразу для перетворення.

38:42

Набір коротких Playwright-шаблонів

Для частих операцій створюються малі шаблони, кожен з яких прибирає конкретний повторюваний фрагмент:

- page.pause() для зупинки тесту й дослідження стану;
- заготовка методу Page Object із параметром і локатором;
- self.page.get_by_role(...) з курсором на ролі та подальших аргументах;
- виклик потрібного локатора з .click();
- очікування expect(button).to_be_hidden() після відправлення форми.

Шаблон get_by_role дає виграш не кількістю згенерованого коду, а тим, що не треба щоразу набирати self.page, назву методу й дужки. Після розгортання залишається вибрати роль, наприклад button, і вказати доступне ім’я.

Також показано запуск поточного тесту зі скорочення та переміщення цілого statement вгору або вниз (⌘⇧↑ / ⌘⇧↓ у демонстрації). Якщо комбінації в локальному keymap інші, дію слід знайти за назвами Move Statement Up і Move Statement Down.

Після кліку тест очікує зникнення кнопки. Це робить перехід до наступної сторінки явним: подальші дії починаються лише після підтвердженої зміни стану.

47:55

Дані Faker, запуск і перевірка сценарію

Для унікальної назви використовується Faker. Вираз із назвою компанії перетворюється на змінну через створений postfix template, змінна перейменовується на змістовну target_suite_name і передається в метод створення.

Непотрібні вбудовані postfix templates можна вимикати, щоб список підказок не заважав. Водночас експеримент із власним .var показує межу автоматизації: якщо шаблон не залишає курсор у корисному місці, його треба виправити, а не пристосовувати робочий процес до невдалого шаблону.

Сценарій запускається й проходить послідовно: авторизація, створення проєкту, закриття README, відкриття діалогу створення тесту. У режимі паузи перевіряється DOM і вибирається текст Select suite for test; для нього додається шаблон get_by_text(...), після чого expect(...).to_be_visible() підтверджує появу модального вікна.

Якщо попередній debug-процес ще приєднаний, повторний запуск може чекати на його завершення. Після коректного продовження або зупинки процесу тест проходить. Наприкінці тест перейменовується відповідно до перевірюваної поведінки, а не до проміжних технічних кроків.

54:13

Завершення тесту й різниця між шаблонами

Після успішного запуску тест перейменовується відповідно до перевірюваної поведінки. Для ще одного повторюваного фрагмента створюється простий live template, який розгортається в return self. Це підтримує ланцюжкові виклики Page Object без повторного ручного набору.

Плагіни не є основою цього процесу. У викладача встановлений Junie, але частіше для окремих задач використовується Claude Code. Головний приріст швидкості в уроці дають штатні засоби PyCharm: пошук у Settings, keymap, рефакторинги та шаблони. Параметри сторонніх плагінів варто змінювати лише під реальну потребу.

Підсумкова модель трьох механізмів:

- **postfix template** застосовується після виразу через крапку та обгортає або перетворює цей вираз;
- **live template** розгортає за абревіатурою блок коду в позиції курсора;
- **file template** створює новий файл із готовою структурою.

На практиці postfix зручний для locator або expect, live template — для page.pause(), get_by_role() і повторюваних методів, а file template — для Page Object. Ці механізми доповнюють один одного й не потребують зовнішнього генератора.

58:29

File template для Playwright-тесту й висновки

Останній приклад — file template для нового Playwright-тесту. У ньому заздалегідь зберігається типова шапка: імпорти, базова структура тесту, потрібні фікстури та місце, де після створення файла має залишитися курсор. Назву тестової функції зрештою залишено для явного введення: автоматичне формування з назви файла не дало достатньо зручного результату.

Після вибору нового типу файла в меню PyCharm створює готовий каркас, у якому можна відразу ініціалізувати потрібний Page Object і продовжити сценарій. Це завершує повний шлях автоматизації: file template створює структуру, live templates додають типові блоки, postfix templates перетворюють окремі вирази, а штатні рефакторинги безпечно змінюють уже написаний код.

Практичний порядок впровадження:

1. Виписати дії та конструкції, які повторюються щодня.
2. Для кожної обрати найменший механізм: shortcut, postfix, live або file template.
3. Обмежити шаблон потрібною мовою чи контекстом.
4. Перевірити згенерований код на реальному сценарії.
5. Вимкнути невикористовувані шаблони й залишити лише ті, що справді прискорюють роботу.

Налаштування IDE має зменшувати кількість механічних дій, але не приховувати зміст коду. Експериментувати варто поступово: додавати один шаблон під реальне повторення, користуватися ним у роботі й лише тоді переходити до наступного.

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

  • Postfix completion ↗JetBrains · перевірено 2026-07-31

    Описує актуальний шлях налаштування, $EXPR$, $END$ та різницю між postfix і live templates.

  • File and Code Templates ↗JetBrains · перевірено 2026-07-31

    Пояснює scope custom file templates, їхні типи, налаштування і зберігання project templates.

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

    Фіксує актуальну рекомендацію пріоритезувати user-facing locators, зокрема get_by_role(), get_by_label() і get_by_text().