QA Co-pilot
91 subscribers
326 photos
1 video
49 links
QA Co-pilot 🚀

Ваш другий пілот у світі тестування.

👨‍💻 Для кого: Для тестувальників-практиків, які хочуть рости.
🎯 Про що: Делегуємо рутину нейромережам, прискорюємо роботу та звільняємо час на головне.
❌ Чого тут немає: Нудної теорії та води.
Download Telegram
📡 Tech Radar: Головне для QA цього тижня

Привіт, екіпаж! Понеділок — час оновлювати тулбокс. Два інструменти, які зараз активно обговорюють у ком'юніті:

1️⃣ Playwright UI Mode (Time-Travel Debugging): Якщо ви досі дебажите тести через console.log або повільний інспектор — зупиніться. Запуск із прапорцем --ui відкриває повноцінне вікно, де ви можете буквально "відмотати" час назад. Ви бачите DOM, network та console на кожній мілісекунді виконання тесту.

2️⃣ Faker.js — Deterministic Seeds: Всі люблять генерувати фейкові імена та емейли. Але що робити, коли тест впав, а рандомні дані змінилися при перезапуску? Faker додав можливість задавати faker.seed(123). Тепер ваші дані рандомні, але однакові при кожному прогоні. Ідеально для відтворення плаваючих багів!


Що затестите першим? 👇
🔥 — Playwright UI Mode!
👀 — Faker.js Seed, давно шукав(ла) це.
⚔️ Битва підходів: Візуальні тести (Pixel-Perfect) проти DOM-Асертів

Ще одна тема понеділка! Як перевірити, що ваш Angular-компонент виглядає правильно?

🥊 Підхід 1: Visual Regression (Скріншоти)
Ви робите скріншот сторінки і порівнюєте його з еталоном.

Мінус: Тести стають надзвичайно крихкими (flaky). Дизайнер змінив тінь на кнопці на 1 піксель, або змінився рендер шрифтів у CI/CD на Linux — і всі тести "почервоніли".


🥊 Підхід 2: DOM-Асерти (Логічні перевірки)
Ви перевіряєте лише те, що важливо: expect(btn).toHaveClass(/primary/) та expect(btn).toBeVisible().

Плюс: Куленепробивна стабільність. Колір кнопки вас не обходить, головне — збережена бізнес-логіка і правильні CSS-класи.


Вердикт QA Co-pilot: Скріншотні тести мають право на життя ТІЛЬКИ в Storybook для ізольованих UI-компонентів. В End-to-End тестах використовуйте виключно DOM-перевірки.

А як ви шукаєте візуальні баги? 👇
🔥 — Тільки DOM, не хочу розбирати впавші скріншоти.
👀 — Робимо скріншоти, але боляче...
👍1
🧨 Руйнівники IT-міфів: "100% Code Coverage означає відсутність багів"

Привіт, екіпаж! Сьогодні б'ємо по найпопулярнішому менеджерському міфу.

❌ Міф: "Наш SonarQube показує 100% покриття коду тестами. Ми можемо спокійно релізити, багів немає!"

💥 Реальність:
Code Coverage показує лише те, які рядки коду виконувалися під час тестів. Але він НЕ гарантує, що ви перевірили результат!

Ви можете написати тест, який викликає функцію calculateSalary(), і не написати жодного expect(). Покриття буде 100%, а функція може повертати null.


✅ Як має бути:
Справжній показник надійності — це Mutation Testing (наприклад, Stryker). Цей інструмент штучно вносить баги у ваш код (міняє + на -) і перевіряє, чи впадуть ваші тести. Якщо не впали — ваші тести сліпі, незалежно від відсотків покриття!


Ганяєтесь за 100% покриттям? 👇
🔥 — Ні, фокусуємось на критичних бізнес-сценаріях!
👀 — У нас KPI на 80% покриття, пишемо тести заради цифри...
🧠 Задача з Senior співбесіди: "Подорож у часі"

Продовжуємо вівторок задачею з лайв-кодингу.

Умови: На сайті є банер "Знижка згорить завтра об 11:00". Як автоматизувати перевірку того, що банер дійсно зникає, коли настає час Х?

❌ Відповідь Джуна: "Я створю тестовий банер, який зникає через 5 секунд, поставлю sleep(5000) у тесті і перевірю." (Погано: хардкод логіки під тести).

✅ Відповідь Сеньйора:
Ми замокаємо системний годинник прямо в браузері!

Сучасні фреймворки мають вбудовану машину часу. Наприклад, у Playwright ми використовуємо await page.clock.setFixedTime(new Date('2026-12-31T11:01:00')).

Браузер думатиме, що дедлайн уже минув, Angular-компонент миттєво перерахує час, і банер зникне. Нуль очікувань, 100% надійність.


Мокаєте час у тестах? 👇
🔥 — Постійно, це єдиний спосіб тестувати таймери!
👀 — Чесно? Навіть не знав(ла), що так можна.
🕵️‍♂️ Інженерний детектив: "Невидима перешкода" (або Z-Index пастка)

Привіт, екіпаж! Середа — час розслідувань.

Симптоми: Користувачі скаржаться, що кнопка "Купити" не натискається. Ви запускаєте Cypress/Playwright — тест клікає кнопку і світиться зеленим. Ви відкриваєте руками — кнопка реально не реагує на мишку!

🔍 Що сталося:
Playwright за замовчуванням має механізм "Actionability", але іноді він хибить. Фронтендер випадково розтягнув прозорий <div> (наприклад, невидимий тултип) поверх кнопки.

Візуально кнопка є. В DOM вона є. Але фізично курсор клікає по прозорому <div>, який лежить вище по z-index!


✅ Вирок:
У Playwright іноді використовують force: true для кліку. Це змушує фреймворк пробити DOM і клікнути елемент, ігноруючи перешкоди. Ніколи цього не робіть.

Якщо тест падає через "element intercepts pointer events" — це не нестабільний тест, це реальний баг UI, який блокує ваших живих користувачів.
📝 Ультимативна Шпаргалка: HTTP Status Codes (Версія для QA)

Ми всі знаємо 200 (OK) та 404 (Not Found). Але на співбесідах (і під час тестування NestJS бекендів) постійно плутають помилки клієнта. Зберігайте:

401 Unauthorized: "Я не знаю, хто ти". (Ти забув передати токен авторизації, або він прострочений).

403 Forbidden: "Я знаю, хто ти, але тобі туди не можна". (Ти залогінений як звичайний юзер, а намагаєшся видалити проєкт як Адмін).

400 Bad Request: "Ти відправив технічну діч". (Синтаксична помилка, не валідний JSON, бракує обов'язкового поля).

422 Unprocessable Entity: "Формат правильний, але бізнес-логіка проти". (Ти відправив ідеальний JSON з полем email, але цей email вже зайнятий у PostgreSQL).


Перевіряйте не просто факт помилки, а її ТОЧНИЙ код у ваших API тестах!
🔥 Прожарка інструментів: Selenium WebDriver (Легенда, якій час на пенсію)

Привіт, екіпаж! Сьогодні смажимо прабатька всієї UI-автоматизації.

🟢 Як нам це продають: "Це стандарт! Він підтримує навіть Internet Explorer 8 і будь-які мови програмування!"

🥩 Прожарка:
1️⃣ Пекло версій: Скільки життів згоріло через помилку SessionNotCreatedException: This version of ChromeDriver only supports Chrome version X. Ви оновили браузер — тести впали. Потрібно постійно менеджити драйвери (так, є WebDriverManager, але це ще один костиль).

2️⃣ Архітектура: Selenium працює через HTTP-запити до драйвера. Він фізично не може зазирнути всередину браузера, перехопити мережу чи працювати з LocalStorage так само елегантно і швидко, як Playwright чи Cypress (які спілкуються через CDP протокол).


Вердикт: Якщо ви стартуєте новий проєкт у 2026 році — Selenium є найгіршим вибором з точки зору швидкості розробки (DX). Залиште його для підтримки легасі.
🩻 Рентген співбесіди: "Тестування Webhooks"

Продовжуємо четвер питанням для мідлів+.

Питання: "Ваш додаток інтегровано з платіжною системою. Коли оплата проходить, стороння система відправляє Webhook (асинхронний POST запит) на ваш бекенд. Як це протестувати?"

❌ Відповідь Джуна: "Я оплачу на UI і буду робити sleep(10000) або постійно оновлювати сторінку, поки баланс не зміниться."

✅ Відповідь Сеньйора:
Я взагалі не буду чіпати сторонню систему. Я використаю API-клієнт в автотестах і сам відправлю POST-запит на наш ендпоінт вебхука (наприклад, /api/webhooks/stripe), імітуючи payload від платіжки з правильними signature-заголовками.

Або, якщо треба протестувати реальний флоу, підніму локальний тунель через Ngrok у CI/CD, щоб стороння система могла "достукатися" до мого тестового оточення.
💩 Код з душком: Магічні числа (або "Чому саме 5?")

Привіт, екіпаж! П'ятниця — вивітрюємо антипатерни.

Знайдіть проблему:
test('Відображення списку статей', async ({ page }) => {
await expect(page.locator('.article-card')).toHaveCount(5);
});

Чому це тхне:
Що таке 5? Це хардкод. Якщо хтось додасть нову статтю в базу даних — тест впаде, хоча функціонал працює. Вам доведеться йти в код і міняти 5 на 6. Це перетворює підтримку тестів на рутину.

✅ Як має бути:
Завжди спирайтеся на динамічні дані. Якщо ви мокаєте мережу — беріть довжину з моку. Якщо берете з бази — робіть запит:
// 🚀 Ідеально
const articlesMock = [{id: 1}, {id: 2}];
await page.route('**/api/articles', route => route.fulfill({ json: articlesMock }));
await expect(page.locator('.article-card')).toHaveCount(articlesMock.length);

Додали елемент у масив? Тест адаптується автоматично.
⚔️ Битва підходів: Page Object Model (POM) проти Custom Fixtures

Завершуємо тиждень класичною битвою архітектур у Playwright.

🥊 Підхід 1: Page Object Model (Класика)
Ви створюєте клас LoginPage з методами fillEmail() та clickSubmit().

Проблема: З часом класи стають гігантськими ("Божественний об'єкт"), вимагають постійного new LoginPage(page) і засмічують пам'ять.


🥊 Підхід 2: Playwright Fixtures (Сучасність)
Ви інкапсулюєте кроки прямо в інфраструктуру тесту. Тест просто просить те, що йому треба у параметрах:
test('buy item', async ({ loggedInUser, cartInfo }) => { ... })

Перевага: loggedInUser сам під капотом відкриє сторінку, залогіниться, перевірить сесію і віддасть готовий стан. Жодних new, максимальна ізоляція та перевикористання.


Вердикт: POM все ще крутий для опису селекторів (аби не дублювати locator), але для складних флоу переходьте на кастомні Fixtures — це робить ваші тести чистими як сльоза.
🛰 Екіпаж, на зв'язку твій Ко-пілот.

Привіт! Сьогодні без технічних новин та розбору тест-кейсів. Сьогодні ми про головне. ☕️

Хочеться просто підтримати один одного і нагадати, як ми дорожимо кожним, хто з нами в цьому екіпажі. Цей канал — не про політичний шум, він про взаємодію та підтримку.

Сьогоднішня ніч для Києва та області була складною. Твій Ко-пілот на зв’язку, ми разом в цьому штормі. Маю надію, що кожен з вас цілий. Пам'ятайте головне: після темряви завжди приходить світло.

Якщо вам потрібна моральна підтримка або просто хочете з кимось поспілкуватись — пишіть в коментарях. Ми разом проживемо ці емоції. Хто в безпеці — підтримайте своїх. Просто зателефонуйте друзям, перевірте зв'язок.

Ми все переживемо і будемо рухатись далі! Разом.
❤2
🧨 Руйнівники IT-міфів: "100% Code Coverage означає відсутність багів"

Привіт, екіпаж! Сьогодні б'ємо по найпопулярнішому менеджерському міфу, який змушує команди писати тести заради галочки. ☕️

❌ Міф: "Наш SonarQube показує 100% покриття коду тестами. Ми можемо спокійно релізити, багів немає!"

💥 Реальність (Бум!):
Code Coverage показує лише те, які рядки коду виконувалися під час прогону тестів. Але він абсолютно НЕ гарантує, що ви перевірили результат!

Ви можете написати автотест, який викликає функцію calculateSalary(), і не написати жодного expect(). Рядки коду виконаються, покриття буде 100%, а функція насправді може повертати null і ламати продакшен.


✅ Як має бути (Підхід Архітектора):
Справжній показник надійності — це Mutation Testing (Мутаційне тестування, наприклад, через інструмент Stryker).

Цей інструмент штучно вносить баги у ваш код (міняє + на -, видаляє виклики функцій) і перевіряє, чи впадуть ваші автотести. Якщо тести залишилися зеленими — вони сліпі, і ваші 100% покриття не варті нічого.


А ви ганяєтесь за відсотками покриття? 👇
🔥 — Ні, фокусуємось на критичних бізнес-сценаріях!
👀 — У нас KPI на 80% покриття, іноді пишемо тести заради цифри...
🤯 — Стоп, тобто тести можуть проходити, навіть якщо логіка зламана?!
🧠 Задача з Senior співбесіди: "Невловимі WebSockets"

Привіт, екіпаж! Другий пост на сьогодні. Беремо задачу з лайв-кодингу, на якій часто "пливуть" кандидати, коли мова заходить про сучасні real-time додатки. ☕️

Умови задачі:
Ви тестуєте систему живих сповіщень. Додаток тримає постійне з'єднання через WebSockets (стандартна історія для NestJS бекендів).
Коли статус вашого замовлення змінюється, бекенд пушить івент у сокет, і на фронтенді миттєво вискакує тост: "Замовлення відправлено".

Питання: Як надійно автоматизувати цей флоу в E2E-тесті, враховуючи, що повідомлення може прилетіти через 10 мілісекунд, а може затриматися на 2 секунди через мережу?


❌ Відповідь рівня Junior (Хибний шлях):
"Я тригерну зміну статусу через API, поставлю жорсткий sleep(3000) про всяк випадок, і перевірю, чи з'явився тост у DOM".

Чому це провал: Якщо сокет затримається на 3.1 секунди, тест впаде. А якщо прийде миттєво — ви просто так спалите час у CI/CD.


✅ Відповідь рівня Senior (Підхід Архітектора):
Ми не будемо покладатися на сліпі таймери. Ми будемо "слухати" сам WebSocket-канал на рівні браузера!

У Playwright є можливість перехоплювати не тільки HTTP, але й фрейми всередині WS-з'єднань:
// 1. Створюємо "пастку" для конкретного WebSocket повідомлення
const wsMessagePromise = page.waitForEvent('websocket', ws => {
return ws.url().includes('/notifications');
}).then(ws => ws.waitForEvent('framereceived', frame =>
frame.payload.includes('order_shipped')
));

// 2. Тригеримо зміну статусу через API
await api.changeOrderStatus('shipped');

// 3. Тест піде далі ТІЛЬКИ в ту мілісекунду, коли прилетить потрібний фрейм
await wsMessagePromise;

// 4. Тільки тепер перевіряємо UI
await expect(page.locator('.toast')).toBeVisible();

Результат: Тест працює зі швидкістю світла. Ніяких "блимаючих" падінь через нестабільність мережі.

А ви вже автоматизували WebSockets? 👇
🔥 — Звісно, перехоплюємо фрейми як профі!
👀 — Поки тестуємо тільки звичайні HTTP (REST) запити...
🤯 — Чекайте, Playwright вміє читати дані всередині відкритого сокета?!
📝 Ультимативна Шпаргалка: Стан елемента в DOM (Visible vs Attached)

Привіт, екіпаж! Скільки разів ви ловили помилку Element is not visible, хоча в DevTools його чітко видно в HTML-коді? Сьогодні розбираємо життєвий цикл елемента на сторінці. Це база, без якої ваші асерти (перевірки) завжди будуть нестабільними. ☕️

У сучасних інструментах (Playwright, Cypress) елемент перед кліком проходить 4 стадії зрілості. Знати їх — обов'язок QA.

👻 Attached (Прикріплений)
Елемент фізично існує в DOM-дереві.

Пастка: Він може бути повністю прозорим (opacity: 0), мати display: none або нульовий розмір (0x0). Ви бачите його код у DevTools, але юзер на екрані його не бачить.

(В Angular це зазвичай відбувається при використанні [hidden]="true").


👁Visible (Видимий)
Елемент прикріплений (Attached), має реальні розміри (bounding box не нульовий) і не захований стилями.

Пастка: Він видимий, але може бути перекритий іншим елементом зверху (наприклад, напівпрозорим лоадером або невидимим тултипом).


🟢Enabled (Активний)
Елемент видимий, не перекритий, і на ньому немає атрибута disabled. Тільки на цій стадії з ним можна взаємодіяти.


🛑 Stable (Стабільний)
Елемент повністю завершив свою CSS-анімацію. Він більше не летить через половину екрану. Якщо фреймворк спробує клікнути до цієї стадії — він просто клікне в порожнечу.


Золоте правило перевірок (Asserts):
Тестуючи зникнення елемента, завжди питайте розробників, ЯК він зникає.

Якщо використовується умовний рендеринг (наприклад, новий синтаксис @if або старий *ngIf в Angular) — елемент ПОВНІСТЮ видаляється з DOM. Перевіряємо так:
await expect(locator).toHaveCount(0) або toBeAttached({ attached: false }).


Якщо ж елемент просто ховається через CSS — він залишається Attached, але перестає бути Visible. Перевіряємо так:
await expect(locator).toBeHidden().

А ви плутали Attached і Visible? 👇
🔥 — Знаю цю базу, мої тести надійні як швейцарський годинник!
👀 — Постійно ліплю .toBeVisible() на все підряд і страждаю...
🤯 — Чекайте, тобто елемент може бути в DOM, але не бути Visible?!
🤖 Навіщо нам ШІ-інтерв'юєр, якщо вже є ChatGPT?

Екіпаж, зв'язок відновлено. Останні два тижні в ефірі була тиша, бо я пішов копати одну думку. Зараз з кожної праски кричать про ШІ. Сотні обгорток над GPT, які обіцяють зробити з вас Senior QA за три дні.

Але давайте чесно: ви пробували пройти технічну співбесіду з базовим ChatGPT або Claude?

Це жахливо. Вони занадто "добрі" і поверхневі.
Ти кидаєш йому кривий локатор з прив'язкою до тексту, а він відповідає: "Ви на правильному шляху, який ви молодець, але можливо варто подивитись на...".

Справжній лід на співбесіді так не робить. Справжній лід запитає, чому ти не використав кастомні атрибути і як твій тест витримає асинхронний ререндеринг компонентів. Загальні ШІ працюють як Вікіпедія — вони видають довідку. А на співбесіді потрібен стрес, контекст і глибокі питання по архітектурі, патернах та CI/CD.

Справжній симулятор співбесід не має бути просто діалоговим вікном. Це має бути повноцінний апп (наприклад, швидкий Telegram Mini App з нормальною архітектурою під капотом), який пам'ятає твої слабкі місця, не дає підказок і безжально "робить рев'ю" твоєму коду.

Як ви думаєте, чи є сенс у такому вузькоспеціалізованому, хардкорному ШІ-менторі саме для QA? Чи базової підписки на ChatGPT вистачає з головою? Пишіть ваші думки 👇
🕵️‍♂️ Code Review: Знайди вбивцю CI/CD

Екіпаж, розімнемо мізки. Уявіть ситуацію: Junior QA приносить вам такий код на Playwright.

Він клянеться, що на його потужному макбуці тест працює ідеально в 100% випадків. Але щойно цей код потрапляє в CI/CD пайплайн, тест періодично намертво зависає на кілька хвилин і падає по таймауту.
// Зберігаємо профіль користувача
await page.getByRole('button', { name: 'Save Profile' }).click();

// Чекаємо, поки бекенд відповість успішним статусом
await page.waitForResponse(res =>
res.url().includes('/api/users/profile') && res.status() === 200
);

// Перевіряємо, що з'явився тост про успіх
await expect(page.locator('.toast-success')).toBeVisible();


Де тут закладена бомба уповільненої дії? Виберіть правильний варіант в опитуванні нижче 👇
⚙️ Хардкорний розбір: Як не зламати базу в тестах (Angular + NestJS + Prisma)

Екіпаж, забуваємо про абстрактні задачки. Сьогодні розбираємо реальну архітектуру.

Маємо сучасний стек: важкий Angular на фронтенді, NestJS під капотом, який спілкується з PostgreSQL через Prisma ORM.

Головний біль (State Leakage):
Ви пишете E2E тест на Playwright, який реєструє юзера.
Перший прогін — ідеально (зелений).
Другий прогін — тест падає, бо NestJS віддає помилку 400: User with this email already exists. Стан бази "забруднився".


❌ Як роблять мідли (Милиці):
Пишуть в кінці тесту крок "Видалити акаунт" через UI. Але якщо тест впав посередині — видалення не спрацює, і база залишиться брудною.

Або ще гірше — намагаються мокати Prisma прямо в NestJS. Але тоді це вже не E2E тест, а фікція.


✅ Як будують архітектори (Hardcore QA):
Ми не чіпаємо UI для очищення. Ми використовуємо силу самої Prisma та кастомні фікстури Playwright!

Крок 1: Back-door у NestJS (Тільки для тестового середовища)
Створюємо прихований контролер у NestJS, який буде доступний ТІЛЬКИ коли змінна оточення NODE_ENV=testing. Цей контролер має один ендпоінт, який жорстко зачищає базу через транзакцію Prisma.

// testing.controller.ts (NestJS)
@Post('/teardown')
async cleanDatabase() {
// Prisma $transaction гарантує, що все видалиться або нічого
await this.prisma.$transaction([
this.prisma.user.deleteMany(),
this.prisma.order.deleteMany(),
// ...інші таблиці
]);
return { status: 'cleaned' };
}


Крок 2: Автоматизація в Playwright (Fixtures)
Замість того, щоб у кожному тесті писати beforeEach, ми створюємо кастомну фікстуру. Вона буде автоматично смикати наш NestJS ендпоінт ПЕРЕД кожним тестом.

// fixtures.ts (Playwright)
import { test as base } from '@playwright/test';

export const test = base.extend({
cleanDb: [async ({ request }, use) => {
// Дія ДО тесту: смикаємо Prisma через бекенд
await request.post('http://localhost:3000/api/testing/teardown');

await use(); // Тут виконується сам тест
}, { auto: true }], // auto: true означає, що це відпрацює для ВСІХ тестів
});


Результат:
Кожен ваш тест (навіть якщо ви запустили їх 100 паралельно) починається з абсолютно чистої таблиці PostgreSQL. Ніяких конфліктів даних, ніяких "моргаючих" (flaky) тестів. Angular отримує чистий бекенд, Playwright літає.

А як ви менеджите тестові дані у своїх базах? 👇
🔥 — Тільки хардкор, тільки ізольовані транзакції в БД!
👀 — Пишу унікальні email-и через Date.now() і не парюсь...
🤯 — Зачекайте, Playwright вміє робити auto: true фікстури?!
🗣 Soft Skills: Чому твій ідеальний код нікого не хвилює (якщо ти мямлиш)

Екіпаж, сьогодні відійдемо від Playwright та баз даних. Поговоримо про зброю, яку більшість QA ігнорує — ваш голос.

Ви можете написати геніальну архітектуру автотестів або знайти критичний Memory Leak. Але якщо на демо перед замовником ви ковтаєте закінчення, невпевнено бубоните або не можете чітко пояснити розробнику, в чому суть бага — ваша експертиза множиться на нуль. Впевнена комунікація продавлює тікети швидше за будь-які лог-файли.

Як прокачати артикуляцію (Хардкорний метод)
Не обов'язково йти на дорогі курси ораторської майстерності. Є один жорсткий, але максимально дієвий інструмент, який я сам регулярно використовую.

Вам знадобиться звичайний винний корок і 10 хвилин часу.

1️⃣ Затискаєте корок між передніми зубами (не дуже глибоко, просто щоб зафіксувати).

2️⃣ Відкриваєте будь-яку складну технічну документацію або набір важких скоромовок.

3️⃣ Починаєте читати вголос, намагаючись максимально чітко та гіпертрофовано вимовляти кожен звук крізь цю перешкоду.


Спочатку ви будете звучати кумедно, а м'язи обличчя почнуть горіти вже через дві хвилини. Але коли ви витягнете корок і просто скажете "Доброго ранку, команда", ваш голос звучатиме настільки чисто, об'ємно і впевнено, що розробники самі підуть фіксити баги без зайвих суперечок.

Челлендж для сміливих:
Готові перевірити свою дикцію прямо зараз? Записуйте голосове повідомлення в коментарі під цим постом і прочитайте на одному диханні цю QA-скоромовку:

"Сеньйор-тестувальник тестив-тестив рест-апі, та не витестував, бо флоу бекенду флудив фіктивними фікстурами".


Хто не посоромиться і скине найчіткіше войс-повідомлення — отримає від мене персональний респект. Погнали! 👇
❤2
🏋️‍♂️ "Сушка" для автотестів: Як скинути зайву вагу з вашого CI/CD

Екіпаж, сьогодні поговоримо про фітнес для вашого коду.

Коли ми тільки починаємо писати E2E-тести, наш фреймворк стрункий і швидкий. Але минає півроку, тестів стає сотні, і наш CI/CD пайплайн перетворюється на неповороткого важковаговика. Прогін займає 40 хвилин, тести "задихаються" і падають через нестачу пам'яті.

Фреймворку потрібна жорстка сушка і правильні спортивні добавки.

🍔 Що таке "жир" у ваших тестах?
Це хардкоджені sleep(5000), дублювання коду в beforeEach (коли кожен тест заново логіниться через UI) та використання важких локаторів. Це порожні калорії, які сповільнюють виконання.


💊 Спортивне харчування для Playwright:
Щоб ваш фреймворк став рельєфним і швидким, йому потрібні правильні інструменти:

🔹API-логін замість UI (L-карнітин для тестів): Навіщо кожного разу клікати форму авторизації? Отримуйте токен через бекенд за мілісекунди і "згодовуйте" його браузеру. Це спалює десятки хвилин часу в CI/CD.

🔹Паралелізація та Шардінг (Креатин для CI/CD): Дайте вашим тестам вибухову силу. Розбивайте виконання на кілька потоків (workers) у GitHub Actions або GitLab CI. Нехай тести біжать одночасно на різних машинах, як під час інтенсивного спліту.

🔹Гнучкі очікування (Правильна розминка): Використовуйте waitForResponse або waitForSelector замість фіксованих пауз. Тест має діяти рівно тоді, коли система готова, не витрачаючи зайвої енергії.

Проведіть аудит свого фреймворку. Скільки "зайвої ваги" тягнуть ваші автотести на кожному прогоні?

А скільки хвилин зараз займає фулл-прогін ваших тестів? 👇
🔥 — До 5 хвилин, мій фреймворк — атлет!
👀 — Десь 15-20 хвилин, є над чим працювати.
🤯 — Більше години... ми запускаємо їх тільки на ніч.
❤1
🤖 ШІ не напише за тебе автотести (якщо ти не вмієш давати йому контекст)

Всі вже пробували генерувати тести через ChatGPT або Claude. Зазвичай запит виглядає так:
"Напиши мені E2E тест на Playwright для форми реєстрації".

Що ми отримуємо? Нейромережа видає шаблонний код із документації, який розіб'ється на першому ж кастомному компоненті Angular і поняття не має, як працює ваш бекенд. ШІ — це не магія. Це просто дуже швидкий джун, якому потрібне чітке ТЗ.

Щоб отримувати робочий код, а не галюцинації, промпт має бути архітектурним. Ось формула, якою користуюся я:

1️⃣ Задаємо роль і точний стек:
"Дій як Senior QA Automation. Твій стек: Playwright + TypeScript. Ми тестуємо важкий Angular-додаток, який спілкується з NestJS бекендом."


2️⃣ Даємо контекст середовища і бази даних:
"Враховуй, що авторизація працює через JWT-токен у LocalStorage. База даних — PostgreSQL, ми працюємо з нею через Prisma ORM. Тести мають бути повністю незалежними."


3️⃣ Ставимо точкову задачу (з фокусом на API, а не тільки UI):
"Згенеруй структуру E2E тесту для флоу 'Блокування юзера'. Включи в код: 1) генерацію тестових даних через API перед тестом, 2) перехоплення (mock) відповіді від POST /api/users/block, щоб не чекати реальної відповіді бази. Напиши код з використанням Page Object Model."


З таким запитом ви отримуєте не абстрактну кашу, а готовий скелет із правильним перехопленням запитів та підготовкою даних. Залишається лише прописати ваші реальні локатори.

А як у вас стосунки з ШІ на проєктах? 👇
🔥 — Пишу промпти на 3 сторінки, щоб отримати ідеальний скрипт.
👀 — Використовую суто як Google на максималках (пошук помилок).
🤯 — ШІ генерує маячню, пишу всі локатори руками.
👌1