📡 Tech Radar: Головне за тиждень (25.05 – 31.05.2026) від QA Co-pilot
Привіт, екіпаж! Травень завершується, але індустрія не збавляє обертів. Цього тижня маємо потужні апдейти інструментів, якими користуються QA на абсолютно різних проєктах — від тестування API до мобільних додатків та навантаження. Зібрали для вас найважливіше без води. ☕️
👨🚀 Postman 12: ШІ-генерація Contract-тестів "з коробки"
📱 Appium 3.0 Beta: Налаштування середовища за 60 секунд
🚀 Grafana k6: Browser Module виходить у стабільний реліз
Що з цього потягнете на свій проєкт? 👇
🔥 — Postman AI: нарешті автоматизую ці нудні перевірки схем!
👀 — Appium 3.0: дайте два, ненавиджу налаштовувати ці драйвери.
🤯 — k6 Browser: давно хотів поєднати навантаження бекенду та фронтенду в одному звіті!
Привіт, екіпаж! Травень завершується, але індустрія не збавляє обертів. Цього тижня маємо потужні апдейти інструментів, якими користуються QA на абсолютно різних проєктах — від тестування API до мобільних додатків та навантаження. Зібрали для вас найважливіше без води. ☕️
👨🚀 Postman 12: ШІ-генерація Contract-тестів "з коробки"
Нарешті щось дійсно корисне для тих, хто днями сидить у колекціях API. Postman викотив велике оновлення, де вбудований AI-асистент навчився самостійно генерувати Contract-тести на основі вашої OpenAPI специфікації (Swagger).
Як це вплине на нас: Замість того, щоб руками писати перевірки на кожен тип даних (pm.expect(jsonData.id).to.be.a('number')), ви просто згодовуєте ШІ документацію, і він сам генерує скрипти для валідації всієї схеми відповідей. Час на покриття бекенду тестами скорочується в рази.
📱 Appium 3.0 Beta: Налаштування середовища за 60 секунд
Усі, хто хоч раз налаштовував мобільну автоматизацію з нуля, знають цей біль: завантажити Java, Android Studio, прописати змінні середовища, знайти сумісний ChromeDriver... Команда Appium викотила бету версії 3.0 із концепцією "Zero-Dependency".
Як це вплине на нас: Тепер достатньо однієї команди в терміналі (через спеціальний інсталятор), яка сама завантажує і лінкує всі необхідні драйвери та емулятори під ваш проєкт у контейнері. Мобільне тестування стає таким же простим у старті, як і веб!
🚀 Grafana k6: Browser Module виходить у стабільний реліз
Крута новина для тих, хто займається Performance-тестуванням. Раніше k6 був суто інструментом для бекенду (генерував запити на рівні протоколу). Тепер модуль для тестування браузера (k6 browser) став стабільним.
Як це вплине на нас: Ви можете в одному скрипті згенерувати навантаження на сервер у 1000 віртуальних користувачів через API, і одночасно запустити 1 реальний браузер, щоб виміряти, як сильно при цьому "гальмує" фронтенд (Web Vitals, час рендеру). Це дає реалістичну картину того, що відчуває юзер під час високого навантаження.
Що з цього потягнете на свій проєкт? 👇
🔥 — Postman AI: нарешті автоматизую ці нудні перевірки схем!
👀 — Appium 3.0: дайте два, ненавиджу налаштовувати ці драйвери.
🤯 — k6 Browser: давно хотів поєднати навантаження бекенду та фронтенду в одному звіті!
👍5
⚔️ Битва підходів: Junior vs. QA Architect (UI-Авторизація проти API State Injection)
Привіт, екіпаж! Сьогодні в нашій битві зійдуться два підходи до найпопулярнішої дії в будь-якому фреймворку — авторизації. Як ви заходите в систему перед тим, як протестувати, наприклад, створення профілю чи оплату кошика? ☕️
❌ Підхід Junior-автоматизатора (UI-Логін у кожному тесті)
Чому це антипатерн для великих проєктів: Уявіть, що у вас 100 тестів. Кожна UI-авторизація займає приблизно 3-4 секунди (завантаження сторінки, введення, запит, редирект, рендер дашборду). Ви просто так витрачаєте 5-6 хвилин дорогоцінного часу в CI/CD на кожному прогоні! А якщо фронтендери зламають кнопку логіну? У вас впадуть УСІ 100 тестів, хоча кошик, можливо, працює ідеально.
✅ Підхід QA Architect (API State Injection / Global Setup)
Чому це шедевр: Швидкість та ізоляція. Логін через бекенд та збереження стану займають мілісекунди. Playwright відкриває нову сторінку вже з готовими cookies або localStorage. Усі ваші 100 тестів починаються миттєво з потрібного місця.
Золоте правило: UI-авторизацію треба тестувати рівно один раз в окремому файлі login.spec.ts. Для всіх інших E2E-тестів (профіль, налаштування, кошик) — "чітеримо", підкладаючи готові токени під капот. Не тестуйте логін 100 разів, якщо ваша мета — перевірити кошик!
А як ви заходите в систему у своїх тестах? 👇
🔥 — Тільки збереження стану та API, мої тести літають!
👀 — Кожен тест чесно вводить логін і пароль через UI, зате надійно...
🤯 — А що, можна було просто зберегти куки у JSON?!
Привіт, екіпаж! Сьогодні в нашій битві зійдуться два підходи до найпопулярнішої дії в будь-якому фреймворку — авторизації. Як ви заходите в систему перед тим, як протестувати, наприклад, створення профілю чи оплату кошика? ☕️
❌ Підхід Junior-автоматизатора (UI-Логін у кожному тесті)
test.beforeEach(async ({ page }) => {
// Класика: чесно проходимо весь шлях через інтерфейс
await page.goto('/login');
await page.getByLabel('Email').fill('test@user.com');
await page.getByLabel('Password').fill('SuperSecret123!');
await page.getByRole('button', { name: 'Увійти' }).click();
await expect(page.locator('.dashboard')).toBeVisible(); // Чекаємо рендеру
});
test('Повинен додати товар у кошик', async ({ page }) => {
// ... логіка тесту
});Чому це антипатерн для великих проєктів: Уявіть, що у вас 100 тестів. Кожна UI-авторизація займає приблизно 3-4 секунди (завантаження сторінки, введення, запит, редирект, рендер дашборду). Ви просто так витрачаєте 5-6 хвилин дорогоцінного часу в CI/CD на кожному прогоні! А якщо фронтендери зламають кнопку логіну? У вас впадуть УСІ 100 тестів, хоча кошик, можливо, працює ідеально.
✅ Підхід QA Architect (API State Injection / Global Setup)
// Зберігаємо стан в окремому файлі (наприклад, global.setup.ts)
setup('Авторизація через API', async ({ request }) => {
// 1. Блискавично стукаємо в бекенд
const response = await request.post('/api/auth/login', {
data: { email: 'test@user.com', password: 'SuperSecret123!' }
});
// 2. Зберігаємо куки/токени у файл
await request.storageState({ path: 'auth.json' });
});
// У самому тесті:
test.use({ storageState: 'auth.json' }); // Playwright сам підкладе токени в браузер
test('Повинен додати товар у кошик', async ({ page }) => {
// Ми вже авторизовані! Просто йдемо на потрібну сторінку
await page.goto('/products');
// ... логіка тесту
});
Чому це шедевр: Швидкість та ізоляція. Логін через бекенд та збереження стану займають мілісекунди. Playwright відкриває нову сторінку вже з готовими cookies або localStorage. Усі ваші 100 тестів починаються миттєво з потрібного місця.
Золоте правило: UI-авторизацію треба тестувати рівно один раз в окремому файлі login.spec.ts. Для всіх інших E2E-тестів (профіль, налаштування, кошик) — "чітеримо", підкладаючи готові токени під капот. Не тестуйте логін 100 разів, якщо ваша мета — перевірити кошик!
А як ви заходите в систему у своїх тестах? 👇
🔥 — Тільки збереження стану та API, мої тести літають!
👀 — Кожен тест чесно вводить логін і пароль через UI, зате надійно...
🤯 — А що, можна було просто зберегти куки у JSON?!
👍1
🧨 Руйнівники IT-міфів: "100% Code Coverage гарантує відсутність багів"
Привіт, екіпаж! Сьогодні розбираємо найулюбленіший міф менеджерів, який змушує інженерів писати тисячі рядків марного коду просто заради зелених галочок у репортах. ☕️
❌ Міф: "Якщо наші Unit- та E2E-тести покривають 100% рядків коду, ми можемо спокійно релізити. Додаток ідеальний, багів там немає!"
💥 Реальність (Бум!):
Як виглядає 100% покриття, яке нічого не тестує:
Ви щойно витратили час, CI/CD "позеленів", SonarQube щасливий. Але якщо завтра хтось випадково зламає формулу і напише return price * 99, ваш тест цього не помітить, бо він нічого не перевіряє (Assertion-Free testing).
✅ Як має бути (Підхід Архітектора):
Золоте правило: Code Coverage — це інструмент для розробника, щоб знайти "сліпі зони" у критичній логіці, а не KPI для оцінки якості релізу.
А у вас на проєкті є культ 100% покриття? 👇
🔥 — У нас адекватні 70-80%, тестуємо тільки те, що реально може зламатися!
👀 — Сидимо, пишемо порожні тести просто заради SonarQube...
🤯 — Пішов гуглити, що таке мутаційне тестування, звучить як розрив мозку!
Привіт, екіпаж! Сьогодні розбираємо найулюбленіший міф менеджерів, який змушує інженерів писати тисячі рядків марного коду просто заради зелених галочок у репортах. ☕️
❌ Міф: "Якщо наші Unit- та E2E-тести покривають 100% рядків коду, ми можемо спокійно релізити. Додаток ідеальний, багів там немає!"
💥 Реальність (Бум!):
Code Coverage (покриття коду) — це найпідступніша метрика в IT. Вона показує лише те, що під час виконання тесту рушій (чи то Jest, чи Playwright) пройшов через певний рядок коду. Вона абсолютно не гарантує, що цей код працює правильно.
Як виглядає 100% покриття, яке нічого не тестує:
// Функція, яку ми "тестуємо"
function calculateDiscount(price: number, role: string) {
if (role === 'VIP') return price * 0.5;
return price;
}
// "Ідеальний" тест, який дасть 100% Coverage у звіті:
test('calculateDiscount coverage cheat', () => {
calculateDiscount(100, 'VIP');
calculateDiscount(100, 'Regular');
// Де перевірка expect()?! Її просто немає.
});
Ви щойно витратили час, CI/CD "позеленів", SonarQube щасливий. Але якщо завтра хтось випадково зламає формулу і напише return price * 99, ваш тест цього не помітить, бо він нічого не перевіряє (Assertion-Free testing).
✅ Як має бути (Підхід Архітектора):
🔹Тестуємо вимоги, а не рядки: Тести мають перевіряти бізнес-сценарії. Чи може юзер змінити пароль? Чи відправляється аналітика? Тестуйте логіку, а не синтаксис.
🔹Мутаційне тестування (Mutation Testing): Замість гонитви за відсотками, круті інженери використовують інструменти типу Stryker. Вони навмисно вносять баги (мутації) у ваш код перед запуском тестів. Якщо тести після цього залишаються зеленими — значить, вони сміттєві, навіть при 100% Coverage.
🔹Правило 80/20: Здорова мета — це 70-80% покриття критичного функціоналу. Спроба покрити останні 20% (геттери, прості конфіги, інтерфейси) зазвичай вимагає 80% бюджету часу і не приносить жодної користі проєкту.
Золоте правило: Code Coverage — це інструмент для розробника, щоб знайти "сліпі зони" у критичній логіці, а не KPI для оцінки якості релізу.
А у вас на проєкті є культ 100% покриття? 👇
🔥 — У нас адекватні 70-80%, тестуємо тільки те, що реально може зламатися!
👀 — Сидимо, пишемо порожні тести просто заради SonarQube...
🤯 — Пішов гуглити, що таке мутаційне тестування, звучить як розрив мозку!
👍1
🕵️♂️ Інженерний детектив: Справа про "Привида в Базі" (або Пастка Soft Delete)
Привіт, екіпаж! Середа — час нашої рубрики «Інженерний детектив». Сьогодні ми забудемо про UI-фреймворки та швидкість тестів. Розслідуємо справу суто на стику тестування бізнес-логіки та баз даних. З цим багом стикався кожен, хто хоч раз тестував реєстрацію. ☕️
Сцена злочину (Симптоми):
Ви тестуєте стандартний функціонал управління користувачами. Ваш тест (або ви руками) робить наступне:
І тут... Бум! Додаток падає з 500-ю помилкою (Internal Server Error) або видає алерт «Цей email вже зайнятий». Що за магія? Ви ж щойно його видалили!
❌ Хибний слід:
🔍 Що сталося насправді (Soft Delete та Індекси БД):
✅ Вирок та Рішення (Як це має перевіряти QA):
QA ніколи не повинен вірити зеленим повідомленням на UI.
Щойно ви бачите функцію "Видалити", ваш перший рефлекс — спробувати створити сутність із такими ж унікальними даними.
Як це фіксять архітектурно (підкажіть вашому бекендеру):
А як ви тестуєте видалення? 👇
🔥 — Завжди перевіряю створення дублікатів після видалення, це база!
👀 — Чесно? Якщо запис зник з таблиці на UI, я закриваю таску як Pass...
🤯 — Тобто мої дані насправді ніколи не видаляються з баз?!
Привіт, екіпаж! Середа — час нашої рубрики «Інженерний детектив». Сьогодні ми забудемо про UI-фреймворки та швидкість тестів. Розслідуємо справу суто на стику тестування бізнес-логіки та баз даних. З цим багом стикався кожен, хто хоч раз тестував реєстрацію. ☕️
Сцена злочину (Симптоми):
Ви тестуєте стандартний функціонал управління користувачами. Ваш тест (або ви руками) робить наступне:
🔹Створює користувача test@company.com.
🔹Успішно видаляє його через адмінку. UI показує зелений тост: «Користувача видалено». У списку його більше немає.
🔹Ви намагаєтесь зареєструвати нового користувача з тим самим email-ом test@company.com (адже він вільний!).
І тут... Бум! Додаток падає з 500-ю помилкою (Internal Server Error) або видає алерт «Цей email вже зайнятий». Що за магія? Ви ж щойно його видалили!
❌ Хибний слід:
Джун-тестувальник думає, що це проблема кешу браузера, і починає маніакально тиснути Ctrl+F5 або чистити LocalStorage. Коли це не допомагає, він заводить баг на фронтендера зі словами: "UI не оновлюється після видалення". Фронтендер ображається, бо він свою роботу зробив ідеально.
🔍 Що сталося насправді (Soft Delete та Індекси БД):
Справжній детектив дивиться глибше інтерфейсу. У сучасній розробці дані рідко видаляють фізично (команда DELETE в SQL). Замість цього розробники використовують патерн Soft Delete (М'яке видалення).
Коли ви натиснули «Видалити», бекенд просто оновив рядок у базі даних, проставивши прапорець is_deleted = true (або deleted_at = 2026-06-03).
Фронтенд навчений не показувати користувачів із цим прапорцем, тому зі списку він зник.
АЛЕ! У базі даних на колонці email досі висить жорстке обмеження унікальності (UNIQUE CONSTRAINT). База даних бачить, що рядок з таким email фізично існує (навіть якщо він "видалений"), і намертво блокує спробу створити дублікат, кидаючи критичну помилку!
✅ Вирок та Рішення (Як це має перевіряти QA):
QA ніколи не повинен вірити зеленим повідомленням на UI.
Щойно ви бачите функцію "Видалити", ваш перший рефлекс — спробувати створити сутність із такими ж унікальними даними.
Як це фіксять архітектурно (підкажіть вашому бекендеру):
1️⃣ Partial Index: Змінити індекс у базі даних, щоб він перевіряв унікальність тільки для активних записів (CREATE UNIQUE INDEX ON users (email) WHERE deleted_at IS NULL).
2️⃣ Анонімізація: Під час видалення бекенд має змінювати старий email на щось на кшталт test@company.com.deleted.123456, звільняючи оригінальний email для нових реєстрацій.
А як ви тестуєте видалення? 👇
🔥 — Завжди перевіряю створення дублікатів після видалення, це база!
👀 — Чесно? Якщо запис зник з таблиці на UI, я закриваю таску як Pass...
🤯 — Тобто мої дані насправді ніколи не видаляються з баз?!
🤝2❤1👍1
🔥 Прожарка інструментів: Автономні ШІ-тестувальники (або Чому нейромережі поки не заберуть вашу роботу)
Привіт, екіпаж! Четвер — час розпалювати гриль. Сьогодні ми відкладемо класичні фреймворки і поговоримо про найбільший хайп 2026 року. Про інструменти (а-ля Devin для QA, автономні AI-агенти та No-Code ШІ платформи), які менеджери купують з надією звільнити половину відділу тестування. ☕️
🟢 Як нам це продавали (Очікування):
🥩 Прожарка (Сувора реальність):
⚖️ Вердикт QA Co-pilot:
Штучний інтелект — це фантастичний інструмент. Це ваш другий пілот (саме тому ми так і називаємося ✈️), який ідеально згенерує складну регулярку, допоможе скласти SQL-запит для підготовки даних або згенерує мок-відповідь для API.
Але довірити ШІ повну автономію в написанні E2E-тестів — це як дати стажеру доступ до продакшену в перший робочий день. ШІ генерує код, але Архітектор генерує надійність.
А як ви використовуєте ШІ в роботі? 👇
🔥 — Тільки як помічника (Copilot): прошу згенерувати дрібні функції або локатори!
👀 — Чесно? Інколи прошу ChatGPT написати весь тест цілком, а потім півдня його фікшу...
🤬 — Взагалі не пускаю ШІ до свого коду, він пише суцільне легасі!
Привіт, екіпаж! Четвер — час розпалювати гриль. Сьогодні ми відкладемо класичні фреймворки і поговоримо про найбільший хайп 2026 року. Про інструменти (а-ля Devin для QA, автономні AI-агенти та No-Code ШІ платформи), які менеджери купують з надією звільнити половину відділу тестування. ☕️
🟢 Як нам це продавали (Очікування):
"Більше ніякого кодингу! Ви просто згодовуєте штучному інтелекту посилання на сайт, або даєте лінк на тікет у Jira. ШІ сам аналізує сторінку, сам придумує тест-кейси, сам пише код і сам його підтримує. QA-інженер тепер просто сидить і п'є смузі, поки агенти роблять усю роботу!"
🥩 Прожарка (Сувора реальність):
1️⃣ Генерація спагеті-коду: ШІ чудово пише лінійні скрипти. Але він абсолютно не розуміє архітектури вашого конкретного проєкту. Він не знає, що у вас є глобальна auth.fixture, складні Page Objects або хелпери для роботи з базою даних. Він просто нагенерує вам "простирадло" з хардкодними селекторами, яке неможливо інтегрувати у ваш красивий фреймворк.
2️⃣Галюцинації бізнес-логіки: Агент бачить кнопку "Купити" і намагається її клікнути. Але він не розуміє, що за бізнес-вимогами ця кнопка має бути активною ТІЛЬКИ для користувачів з підпискою рівня "Premium". ШІ просто видасть помилку "Element not interactable", або ще гірше — почне писати милиці (force: true), щоб зламати вашу ж логіку заради зеленої галочки.
3️⃣Сліпота до станів (State Blindness): Нейромережі тестують UI, але погано розуміють невидимі процеси. Наприклад, те саме "м'яке видалення" з бази даних (Soft Delete) або мікрозатримки анімацій. Вони бачать ідеальну "щасливу стежку", але ігнорують складні крайові випадки (Edge cases), де зазвичай і ховаються найкритичніші баги.
⚖️ Вердикт QA Co-pilot:
Штучний інтелект — це фантастичний інструмент. Це ваш другий пілот (саме тому ми так і називаємося ✈️), який ідеально згенерує складну регулярку, допоможе скласти SQL-запит для підготовки даних або згенерує мок-відповідь для API.
Але довірити ШІ повну автономію в написанні E2E-тестів — це як дати стажеру доступ до продакшену в перший робочий день. ШІ генерує код, але Архітектор генерує надійність.
А як ви використовуєте ШІ в роботі? 👇
🔥 — Тільки як помічника (Copilot): прошу згенерувати дрібні функції або локатори!
👀 — Чесно? Інколи прошу ChatGPT написати весь тест цілком, а потім півдня його фікшу...
🤬 — Взагалі не пускаю ШІ до свого коду, він пише суцільне легасі!
👍1
💩 Код з душком: "Магічні числа" в API-тестах (або Чому ваші пайплайни падають по понеділках)
Привіт, екіпаж! П'ятниця — традиційний час вивітрювати "смердючий" код з репозиторіїв. Ми вже розбиралися з крихкими UI-локаторами та залежними тестами. Сьогодні ліземо під капот і препаруємо найпопулярніший гріх при тестуванні бекенду. Говоримо про хардкод і статичні дані. ☕️
Знайдіть проблему в цьому тесті:
Чому цей код тхне:
✅ Як це виглядає після код-рев'ю Senior-інженера:
Тест ніколи не повинен розраховувати на те, що в базі "вже щось є". Він має сам забезпечити себе даними, отримати динамічний ідентифікатор (UUID або автоінкремент) і працювати виключно з ним.
Чому це шедевр:
Цей тест абсолютно автономний і куленепробивний. Ви можете запускати його в 100 потоків паралельно, на порожній чи заповненій базі — він ніколи не перетнеться з іншими тестами, бо щоразу генерує унікальні сутності і посилається тільки на них.
Золоте правило: Якщо у ваших API-тестах є захардкоджені ID (наприклад 100500, user-123), рано чи пізно цей тест зрадить вас у пайплайні. Генеруйте дані "на льоту".
А як у вас справи з тестовими даними? 👇
🔥 — Тільки динамічна генерація, мій фреймворк сам створює все необхідне!
👀 — Грішу хардкодом... У нас є спеціальний тестовий юзер, якого ми всі боїмося видалити.
🤯 — А що робити, якщо бекенд не має ендпоінту для створення юзера?!
Привіт, екіпаж! П'ятниця — традиційний час вивітрювати "смердючий" код з репозиторіїв. Ми вже розбиралися з крихкими UI-локаторами та залежними тестами. Сьогодні ліземо під капот і препаруємо найпопулярніший гріх при тестуванні бекенду. Говоримо про хардкод і статичні дані. ☕️
Знайдіть проблему в цьому тесті:
// ❌ Як пишуть "на швидку руку" (Антипатерн: Прив'язка до статичної БД)
test('Повинен успішно отримати профіль користувача', async ({ request }) => {
// Звертаємось до конкретного ID, який хтось колись створив руками
const response = await request.get('/api/users/42');
const user = await response.json();
expect(response.status()).toBe(200);
expect(user.email).toBe('test-qa@example.com');
});
Чому цей код тхне:
Це класична бомба уповільненої дії. На вашій локальній машині цей тест буде зеленим. Але коли ви тестуєте сучасний бекенд (наприклад, написаний на NestJS у зв'язці з PostgreSQL), сутності створюються динамічно.
Щойно цей тест потрапить у CI/CD, де база даних піднімається з нуля в Docker-контейнері, або якщо інший розробник випадково видалить юзера з ID 42 — тест впаде з помилкою 404 Not Found. Ви будете витрачати години на дебаг "зламаного" бекенду, хоча насправді бекенд працює ідеально, просто тест зав'язаний на ілюзорні дані.
✅ Як це виглядає після код-рев'ю Senior-інженера:
Тест ніколи не повинен розраховувати на те, що в базі "вже щось є". Він має сам забезпечити себе даними, отримати динамічний ідентифікатор (UUID або автоінкремент) і працювати виключно з ним.
// 🚀 Ідеально чистий код (Динамічна генерація стану)
test('Повинен успішно отримати профіль користувача', async ({ request }) => {
// 1. Arrange: Динамічно створюємо юзера з унікальним email
const uniqueEmail = `qa-test-${Date.now()}@example.com`;
const createRes = await request.post('/api/users', {
data: { email: uniqueEmail, role: 'candidate' }
});
const newUser = await createRes.json();
// 2. Act: Використовуємо динамічний ID, який щойно згенерувала БД
const response = await request.get(`/api/users/${newUser.id}`);
const fetchedUser = await response.json();
// 3. Assert: Перевіряємо результат
expect(response.status()).toBe(200);
expect(fetchedUser.email).toBe(uniqueEmail);
});
Чому це шедевр:
Цей тест абсолютно автономний і куленепробивний. Ви можете запускати його в 100 потоків паралельно, на порожній чи заповненій базі — він ніколи не перетнеться з іншими тестами, бо щоразу генерує унікальні сутності і посилається тільки на них.
Золоте правило: Якщо у ваших API-тестах є захардкоджені ID (наприклад 100500, user-123), рано чи пізно цей тест зрадить вас у пайплайні. Генеруйте дані "на льоту".
А як у вас справи з тестовими даними? 👇
🔥 — Тільки динамічна генерація, мій фреймворк сам створює все необхідне!
👀 — Грішу хардкодом... У нас є спеціальний тестовий юзер, якого ми всі боїмося видалити.
🤯 — А що робити, якщо бекенд не має ендпоінту для створення юзера?!
❤1👍1
QA Co-pilot
💩 Код з душком: "Магічні числа" в API-тестах (або Чому ваші пайплайни падають по понеділках) Привіт, екіпаж! П'ятниця — традиційний час вивітрювати "смердючий" код з репозиторіїв. Ми вже розбиралися з крихкими UI-локаторами та залежними тестами. Сьогодні…
📡 Tech Radar: Головне за тиждень (01.06 – 07.06.2026) від QA Co-pilot
Привіт, екіпаж! Перший тиждень літа позаду, і він приніс кілька потужних релізів. Цього разу фокусуємось на інструментах, які знімають з QA найбільший головний біль: генерацію тестових даних, адаптивну верстку та доступність. Зібрали для вас найважливіше без води. ☕️
📱 BrowserStack: "Layout-Intelligence" для мобільного та кросбраузерного тестування
🗄 Testcontainers Cloud "Time Machine": Миттєві клони баз даних для CI/CD
♿️ Axe-core 5.0: Динамічне тестування доступності (A11y)
Який апдейт найбільше потрібен вашому проєкту прямо зараз? 👇
🔥 — Testcontainers! Мої паралельні тести постійно ламають базу одне одному.
👀 — BrowserStack Layout: нарешті не треба шукати зламану верстку на старих айфонах.
🤯 — Axe-core: у нас якраз замовники з Європи почали вимагати доступність!
Привіт, екіпаж! Перший тиждень літа позаду, і він приніс кілька потужних релізів. Цього разу фокусуємось на інструментах, які знімають з QA найбільший головний біль: генерацію тестових даних, адаптивну верстку та доступність. Зібрали для вас найважливіше без води. ☕️
📱 BrowserStack: "Layout-Intelligence" для мобільного та кросбраузерного тестування
Скільки разів ви ловили баг, коли німецький чи український текст вилазив за межі кнопки на маленькому екрані iPhone SE? Раніше для цього треба було писати візуальні тести на 10 різних розмірів екранів.
BrowserStack викотив круту фічу на базі машинного зору: тепер їхня хмара автоматично сканує ваш додаток на 50 різних пристроях у фоні і сама шукає перекриття елементів (overlaps), обрізаний текст чи зламані флексбокси.
Як це вплине на нас: Ви більше не пишете тести на адаптивність. Платформа сама "підсвітить" пристрої, де UI розсипався, навіть якщо логіка кнопки працює ідеально.
🗄 Testcontainers Cloud "Time Machine": Миттєві клони баз даних для CI/CD
Усі знають цей біль: ви запускаєте 20 API-тестів паралельно, вони починають одночасно створювати/видаляти користувачів в одній базі даних, конфліктують і падають.
Testcontainers випустили фічу "State Snapshots". Ви піднімаєте базу (наприклад, PostgreSQL), заливаєте туди базові дані і робите "зліпок". Тепер кожен з ваших 20 паралельних тестів (воркерів) за 1 мілісекунду отримує свою власну, ідеально ізольовану копію бази даних.
Як це вплине на нас: Прощавайте, "моргаючі" API-тести через конфлікт даних. Ідеальна ізоляція (F.I.R.S.T. принцип) тепер доступна "з коробки" без хитрих скриптів очищення.
♿️ Axe-core 5.0: Динамічне тестування доступності (A11y)
Після того, як Європейський акт про доступність (EAA) набув повної сили, тестування Accessibility стало обов'язковим для всіх проєктів, орієнтованих на ЄС. Axe-core (найпопулярніший рушій перевірки a11y) отримав мажорне оновлення.
Раніше він міг перевірити лише статичний HTML (контрастність, наявність alt-тексту). Версія 5.0 вміє динамічно перехоплювати фокус клавіатури (Tab навігацію) прямо під час прогону ваших Playwright-тестів і автоматично ловити "focus traps" (коли юзер застряг у модалці).
Як це вплине на нас: Замість мануального "проклікування" форм табом, ви просто додаєте один плагін у конфіг, і ваші E2E-тести автоматично валять білд, якщо модалку не можна закрити кнопкою Esc або клавіатурою.
Який апдейт найбільше потрібен вашому проєкту прямо зараз? 👇
🔥 — Testcontainers! Мої паралельні тести постійно ламають базу одне одному.
👀 — BrowserStack Layout: нарешті не треба шукати зламану верстку на старих айфонах.
🤯 — Axe-core: у нас якраз замовники з Європи почали вимагати доступність!
🧨 Руйнівники IT-міфів: "За якість продукту відповідає QA-відділ"
Привіт, екіпаж! Сьогодні дістаємо з шафи найболючіший міф, через який тестувальники вигорають, а розробники розслабляються. Цю фразу хоча б раз у житті чув кожен з нас. ☕️
❌ Міф: "Якщо на продакшені знайшли критичний баг — винен виключно QA-інженер. Як ви могли це пропустити?! Ви ж відповідаєте за якість!"
💥 Реальність (Бум!):
Чому цей міф шкідливий:
✅ Як має бути (Здоровий підхід):
А як у вашій компанії ставляться до пропущених багів на проді? 👇
🔥 — Шукаємо причину в процесах, робимо блеймлес-постмортем.
👀 — Прилітає по шапці виключно тестувальнику...
🤯 — А що, код мають перевіряти самі розробники перед відправкою в QA?!
Привіт, екіпаж! Сьогодні дістаємо з шафи найболючіший міф, через який тестувальники вигорають, а розробники розслабляються. Цю фразу хоча б раз у житті чув кожен з нас. ☕️
❌ Міф: "Якщо на продакшені знайшли критичний баг — винен виключно QA-інженер. Як ви могли це пропустити?! Ви ж відповідаєте за якість!"
💥 Реальність (Бум!):
QA-відділ взагалі не здатний "зробити" продукт якісним. Це фізично неможливо.
Найкраща аналогія: QA — це медичний термометр. Термометр може дуже точно показати, що у пацієнта (продукту) температура 39.5°C. Але термометр не лікує хворобу. Лікує імунітет (архітектура) та лікарі (розробники). Якщо розробник написав кривий код без архітектури і покриття Unit-тестами, жоден у світі мануальник чи автоматизатор не зробить цей продукт стабільним.
Чому цей міф шкідливий:
1️⃣ Синдром "Перекидання через паркан": Розробник пише код абияк, не перевіряє навіть Happy Path і кидає тікет у статус "Ready for QA", думаючи: "Тестувальник знайде всі баги, це його робота". У підсумку QA витрачає години на дебаг елементарних помилок NullPointerException.
2️⃣ Ілюзія "Вортаря": Бізнес вважає, що тестування — це остання фаза перед релізом. Але якщо баг закладено на етапі бізнес-вимог (наприклад, аналітик забув про податки у формулі оплати), фіксити його після розробки буде в 10 разів дорожче і довше.
✅ Як має бути (Здоровий підхід):
1️⃣ Якість — це відповідальність усієї команди. Розробники відповідають за Unit-тести та код-рев'ю. Продакти — за логічні вимоги без "дірок".
2️⃣ Shift-Left Testing (Зсув вліво): Справжня робота QA починається не тоді, коли код написаний, а на етапі обговорення ідеї. Ми тестуємо вимоги, тестуємо дизайн у Figma (а що буде, якщо юзер з довгим ім'ям зайде без інтернету?), щоб запобігти появі коду з багами.
3️⃣ Головна задача QA: Не "знайти всі баги", а надати бізнесу об'єктивну інформацію про поточний стан продукту та ризики для прийняття рішення про реліз.
А як у вашій компанії ставляться до пропущених багів на проді? 👇
🔥 — Шукаємо причину в процесах, робимо блеймлес-постмортем.
👀 — Прилітає по шапці виключно тестувальнику...
🤯 — А що, код мають перевіряти самі розробники перед відправкою в QA?!
🕵️♂️ Інженерний детектив: Справа про "Подвійне списання" (або Магія Ідемпотентності)
Привіт, екіпаж! Середа — час нашої рубрики. Як ми й домовлялися: ніяких таймерів, дат чи локаторів. Сьогодні ми розслідуємо суто архітектурний злочин на рівні платіжних систем, який може коштувати вашій компанії мільйони і купу судових позовів. ☕️
Сцена злочину (Симптоми):
❌ Хибний слід:
🔍 Що сталося насправді (Відсутність Ідемпотентності):
✅ Вирок та Рішення (Підхід Архітектора):
Блокувати кнопку на UI — це правило хорошого тону для UX, але не захист бізнес-логіки.
QA повинен вимагати від бекенд-розробників реалізації Idempotency Key (Ключа ідемпотентності).
Як це працює:
Золоте правило: Ніколи не тестуйте фінансові або критичні операції (POST, PUT) без перевірки на дублювання запитів. Завжди перехоплюйте запит у DevTools (або Postman) і відправляйте його двічі-тричі. Якщо створилося кілька сутностей — це критичний баг бекенду.
Привіт, екіпаж! Середа — час нашої рубрики. Як ми й домовлялися: ніяких таймерів, дат чи локаторів. Сьогодні ми розслідуємо суто архітектурний злочин на рівні платіжних систем, який може коштувати вашій компанії мільйони і купу судових позовів. ☕️
Сцена злочину (Симптоми):
Ви тестуєте оформлення замовлення. Інтернет трохи "лагає" (наприклад, ви увімкнули Throttling "Slow 3G" у DevTools). Ви натискаєте кнопку "Оплатити". З'являється лоадер, але він крутиться нескінченно довго.
Ви, як типовий роздратований користувач, починаєте маніакально клікати на цю кнопку ще 3 рази підряд.
Врешті-решт вас перекидає на сторінку "Успіх". Ви заходите у свій банківський додаток і бачите, що гроші за одне замовлення списалися 4 рази!
❌ Хибний слід:
Джун-тестувальник біжить до фронтендера. Вони вирішують проблему "на поверхні": фронтендер додає атрибут disabled на кнопку "Оплатити" одразу після першого кліку.
Тепер кнопку фізично неможливо натиснути двічі. Тест проходить, всі плескають у долоні.
Але через тиждень з продакшену знову прилітає скарга на подвійне списання! Чому? Бо юзер натиснув кнопку один раз, у нього блимнув Wi-Fi, він злякався, натиснув F5 (оновив сторінку) і знову відправив форму. Блокування кнопки на UI його не зупинило.
🔍 Що сталося насправді (Відсутність Ідемпотентності):
Справжній детектив знає, що UI — це лише ілюзія безпеки. Серверна частина була написана так, що вона сліпо виконує кожен POST /api/pay запит, який до неї долітає.
У розподілених системах (мікросервісах) мережа ніколи не буває надійною. Запити можуть дублюватися через ретраї на рівні балансувальників (Nginx) або через дії самого юзера. Бекенд не мав жодного механізму, щоб зрозуміти: "Гей, я вже обробляв цю оплату 2 секунди тому!".
✅ Вирок та Рішення (Підхід Архітектора):
Блокувати кнопку на UI — це правило хорошого тону для UX, але не захист бізнес-логіки.
QA повинен вимагати від бекенд-розробників реалізації Idempotency Key (Ключа ідемпотентності).
Як це працює:
1️⃣ Коли користувач тільки заходить на сторінку чекауту, фронтенд або бекенд генерує унікальний UUID для цієї конкретної спроби оплати.
2️⃣ При натисканні "Оплатити" фронтенд передає цей UUID у заголовку (наприклад, Idempotency-Key: 123e4567...).
3️⃣ Якщо юзер клікне 4 рази або оновить сторінку, всі ці запити полетять з однаковим ключем.
4️⃣ База даних бачить цей ключ, успішно списує гроші за ПЕРШИМ запитом. Наступні три запити з цим же ключем вона не виконує (гроші не списує), а просто повертає закешовану відповідь 200 OK.
Золоте правило: Ніколи не тестуйте фінансові або критичні операції (POST, PUT) без перевірки на дублювання запитів. Завжди перехоплюйте запит у DevTools (або Postman) і відправляйте його двічі-тричі. Якщо створилося кілька сутностей — це критичний баг бекенду.
📝 Ультимативна Шпаргалка: HTTP-заголовки, які врятують ваш дебаг
Коли джуніори починають тестувати API (у Postman, Swagger або DevTools), вони зазвичай дивляться тільки на Body (тіло відповіді) та Status Code. Але справжні архітектурні баги ховаються у метаданих — HTTP-заголовках (Headers).
Ось ультимативний набір заголовків, які має розуміти кожен QA. ☕️
1️⃣ Пастка форматів: Content-Type vs Accept
2️⃣ Детектив мікросервісів: X-Request-ID (або X-Correlation-ID)
3️⃣ Ілюзія старих даних: Cache-Control та ETag
4️⃣ Біль крос-доменних запитів: Access-Control-Allow-Origin (CORS)
5️⃣ Управління сесіями: Authorization vs Cookie
Зберігайте цю шпаргалку. Наступного разу замість абстрактного "У мене бекенд повертає помилку", ви зможете чітко написати: "Баг: Мікросервіс платежів губить X-Correlation-ID під час редиректу". Це рівень справжнього Архітектора.
Коли джуніори починають тестувати API (у Postman, Swagger або DevTools), вони зазвичай дивляться тільки на Body (тіло відповіді) та Status Code. Але справжні архітектурні баги ховаються у метаданих — HTTP-заголовках (Headers).
Ось ультимативний набір заголовків, які має розуміти кожен QA. ☕️
1️⃣ Пастка форматів: Content-Type vs Accept
Дуже часто QA ловить 415 Unsupported Media Type або 406 Not Acceptable і не розуміє, чому валідний JSON не проходить.
🔹Content-Type: Каже серверу, у якому форматі ви ВІДПРАВЛЯЄТЕ дані (наприклад, application/json або multipart/form-data для файлів).
🔹Accept: Каже серверу, у якому форматі ви хочете ОТРИМАТИ відповідь. Якщо ви просите application/xml, а сервер вміє віддавати тільки JSON — буде помилка.
2️⃣ Детектив мікросервісів: X-Request-ID (або X-Correlation-ID)
Що це: Унікальний паспорт вашого запиту.
Як тестувати: Уявіть, що ви натиснули кнопку "Купити". Цей запит проходить через 5 різних мікросервісів (Авторизація, Склад, Платежі, Нотифікації). Десь на третьому кроці стається помилка 500. Як бекендеру знайти саме ВАШ запит у гігабайтах логів?
Правильно спроєктований фронтенд або API-шлюз генерує X-Request-ID при першому кліці і прокидає його через усі сервіси. Якщо ви бачите цей заголовок у відповіді — прикріпіть його до баг-репорту. Розробник скаже вам величезне "Дякую".
3️⃣ Ілюзія старих даних: Cache-Control та ETag
Що це: Відповідають на запитання "Чому я видалив товар, а він досі на вітрині?!"
Як тестувати: Якщо бекенд віддає заголовок Cache-Control: max-age=3600, браузер запам'ятає цю відповідь на годину і взагалі не буде робити нові запити на сервер, хоч би скільки ви тиснули F5. Якщо ви перевіряєте динамічні дані, шукайте Cache-Control: no-cache.
А ETag — це хеш-сума (версія) ресурсу. Якщо вона не змінилася, сервер поверне статус 304 Not Modified і заощадить трафік.
4️⃣ Біль крос-доменних запитів: Access-Control-Allow-Origin (CORS)
Що це: Головний біль усіх фронтендерів.
Як тестувати: Ви тестуєте API через Postman — усе працює ідеально. Фронтендер підключає це API до UI — отримує в консолі червону помилку "CORS policy blocked".
Чому? Тому що браузери забороняють сайту frontend.com робити запити на api.backend.com з міркувань безпеки, ПОКИ бекенд явно не віддасть заголовок Access-Control-Allow-Origin: https://frontend.com. Якщо API публічне, там має бути *.
5️⃣ Управління сесіями: Authorization vs Cookie
Що це: Два шляхи передачі вашого "ключа від дверей".
🔹Authorization: Bearer <token>: Сучасний стандарт (JWT-токени). Фронтенд сам бере токен і чіпляє його до кожного запиту. Ідеально для мікросервісів.
🔹Cookie: Класичний підхід. Браузер сам автоматично чіпляє їх до запитів. Але тут завжди перевіряйте наявність прапорців HttpOnly (щоб хакери не вкрали куку через XSS) та Secure (передача тільки по HTTPS).
Зберігайте цю шпаргалку. Наступного разу замість абстрактного "У мене бекенд повертає помилку", ви зможете чітко написати: "Баг: Мікросервіс платежів губить X-Correlation-ID під час редиректу". Це рівень справжнього Архітектора.
👍1🔥1
🔥 Прожарка інструментів: Postman (або Еволюція в монстра)
Привіт, екіпаж! Четвер — розпалюємо гриль. Сьогодні на решітці інструмент, який встановлено на комп'ютері кожного QA, але який останнім часом викликає більше роздратування, ніж користі. Говоримо про Postman. ☕️
🟢 Як нам це продавали колись:
"Ідеально легкий клієнт для тестування API. Вставив URL, додав JSON, натиснув Send — миттєво отримав результат. Працює швидко і не ставить зайвих питань."
🥩 Прожарка (Сувора реальність 2026 року):
⚖️ Вердикт QA Co-pilot:
На чому зараз "сидить" ваша команда? 👇
🔥 — Давно переїхав на Bruno / Insomnia, літає як ракета!
👀 — Терплю Postman, бо ліньки переносити тисячі старих запитів...
🤯 — Стоп, я можу тестувати API прямо у своєму редакторі коду?!
Привіт, екіпаж! Четвер — розпалюємо гриль. Сьогодні на решітці інструмент, який встановлено на комп'ютері кожного QA, але який останнім часом викликає більше роздратування, ніж користі. Говоримо про Postman. ☕️
🟢 Як нам це продавали колись:
"Ідеально легкий клієнт для тестування API. Вставив URL, додав JSON, натиснув Send — миттєво отримав результат. Працює швидко і не ставить зайвих питань."
🥩 Прожарка (Сувора реальність 2026 року):
1️⃣ Хмарне рабство: Вони фактично вбили офлайн-режим (Scratch Pad). Тепер, щоб просто відправити GET-запит на свій локалхост, ви маєте залогінитись, відправити свої колекції на їхні сервери і постійно відбиватися від банерів "Купіть Enterprise".
2️⃣ Апетит до оперативки: Простий HTTP-клієнт тепер "жере" стільки ж пам'яті, скільки IDE. Він перетворився на важкий комбайн із вбудованими ШІ-агентами, моніторингом, дашбордами і ще десятком фіч, які для щоденного дебагу взагалі не потрібні.
3️⃣ Версіонування: Спроба безкоштовно шерити колекції в команді через їхній Workspace — це біль. Замість зручного зберігання тестів у вашому Git-репозиторії разом із кодом (як це роблять нормальні фреймворки), ви замкнені в їхній екосистемі.
⚖️ Вердикт QA Co-pilot:
Postman став неповоротким корпоративним гігантом, який забув про своє коріння. Для швидкого мануального тестування API та написання легких скриптів інженери зараз масово переходять на опенсорсні Bruno, Hoppscotch або ж звичайні плагіни типу REST Client прямо у VS Code. Вони літають, нічого не просять і зберігають колекції у звичайних текстових файлах.
На чому зараз "сидить" ваша команда? 👇
🔥 — Давно переїхав на Bruno / Insomnia, літає як ракета!
👀 — Терплю Postman, бо ліньки переносити тисячі старих запитів...
🤯 — Стоп, я можу тестувати API прямо у своєму редакторі коду?!
💩 Код з душком: Assertions всередині Page Object (або Чому ваші хелпери не гнучкі)
Привіт, екіпаж! П'ятниця — час вивітрювати антипатерни. Сьогодні розбираємо найчастішу архітектурну помилку при побудові Page Object Model (POM), яка змушує вас дублювати код. ☕️
Знайдіть проблему в цьому класі:
Чому цей код тхне:
✅ Як це виглядає після код-рев'ю Senior-інженера:
Page Object має бути "тупим". Він відповідає ТІЛЬКИ за навігацію та дії. Усі перевірки (expect) мають жити виключно у самому тесті.
Золоте правило: Дії (click, fill) — живуть у класах Page Object. Перевірки (expect) — живуть у тестах. Ніколи не змішуйте їх.
Де у вас лежать перевірки? 👇
🔥 — Усі expect тільки в тестах, мої класи тупі і гнучкі!
👀 — Грішу... У мене половина ассертів захована десь у хелперах.
🤯 — Чекайте, а як тоді перевірити, що кнопка натиснулась?!
Привіт, екіпаж! П'ятниця — час вивітрювати антипатерни. Сьогодні розбираємо найчастішу архітектурну помилку при побудові Page Object Model (POM), яка змушує вас дублювати код. ☕️
Знайдіть проблему в цьому класі:
// ❌ Як пишуть на початку (Антипатерн "Розумна сторінка")
class LoginPage {
async login(email: string, pass: string) {
await this.page.fill('#email', email);
await this.page.fill('#pass', pass);
await this.page.click('#submit');
// ❌ Assert зашитий прямо в метод сторінки!
await expect(this.page.locator('.dashboard')).toBeVisible();
}
}
Чому цей код тхне:
Ви щойно вбили можливість перевикористати цей метод. Що, якщо завтра вам треба буде написати тест на невалідний логін?
Ви викличете метод login('bad@email', '123'), і він впаде, бо почне шукати .dashboard, якого там бути не повинно. Вам доведеться створювати метод-клон loginForNegativeTest(). Це шлях до хаосу.
✅ Як це виглядає після код-рев'ю Senior-інженера:
Page Object має бути "тупим". Він відповідає ТІЛЬКИ за навігацію та дії. Усі перевірки (expect) мають жити виключно у самому тесті.
// 🚀 Ідеально чистий код (Розділення відповідальності)
class LoginPage {
async login(email: string, pass: string) {
await this.page.fill('#email', email);
await this.page.fill('#pass', pass);
await this.page.click('#submit');
}
}
// У файлі тесту:
test('Успішний логін', async ({ page }) => {
await loginPage.login('good@email.com', 'pass');
await expect(page.locator('.dashboard')).toBeVisible(); // Assert тут!
});
test('Помилка логіну', async ({ page }) => {
await loginPage.login('bad@email.com', '123');
await expect(page.locator('.error-msg')).toHaveText('Невірний пароль'); // Assert тут!
});
Золоте правило: Дії (click, fill) — живуть у класах Page Object. Перевірки (expect) — живуть у тестах. Ніколи не змішуйте їх.
Де у вас лежать перевірки? 👇
🔥 — Усі expect тільки в тестах, мої класи тупі і гнучкі!
👀 — Грішу... У мене половина ассертів захована десь у хелперах.
🤯 — Чекайте, а як тоді перевірити, що кнопка натиснулась?!
❤1
📡 Tech Radar: Головне за тиждень (08.06 – 14.06.2026) від QA Co-pilot
Привіт, екіпаж! Червень у розпалі. Зібрали для вас свіжу порцію інструментів, які роблять життя QA простішим, а пайплайни — надійнішими. Без води, лише база за 30 секунд. ☕️
🧠 Ollama для QA: Безпечна локальна генерація даних
🕵️ Proxyman 5.0: Автоматичний детектор "Schema Drift"
⚡️ Lighthouse 14: Жорсткий ліміт на INP (Interaction to Next Paint)
Яку фічу забираєте у свій арсенал? 👇
🔥 — Локальний ШІ через Ollama, безпека понад усе!
👀 — Proxyman: пішов ловити бекендерів на гарячому.
🤯 — Lighthouse: у нас весь фронт лагає при кліках, доведеться фіксити...
Привіт, екіпаж! Червень у розпалі. Зібрали для вас свіжу порцію інструментів, які роблять життя QA простішим, а пайплайни — надійнішими. Без води, лише база за 30 секунд. ☕️
🧠 Ollama для QA: Безпечна локальна генерація даних
Використовувати ChatGPT для генерації JSON-мок чи тестових сценаріїв зручно, але служба безпеки б'є по руках за злив комерційної таємниці?
Спільнота масово переходить на Ollama — інструмент для локального запуску легких ШІ-моделей (типу Llama 3).
Як це впливає на нас: Ви піднімаєте ШІ прямо на своєму робочому ноуті або в закритому контурі CI/CD. Модель генерує ідеальні фейкові дані та парсить складні логи без жодного звернення до інтернету. Ваші NDA в безпеці.
🕵️ Proxyman 5.0: Автоматичний детектор "Schema Drift"
Тестуєте мобілки чи фронтенд? Proxyman (головний конкурент Charles) викотив кілер-фічу. Тепер він вміє автоматично порівнювати реальні API-запити з вашою OpenAPI (Swagger) документацією "на льоту".
Як це впливає на нас: Якщо бекендер мовчки змінив тип поля id з number на string, Proxyman миттєво підсвітить цей запит червоним у вашому лозі, ще до того, як додаток впаде з незрозумілою помилкою.
⚡️ Lighthouse 14: Жорсткий ліміт на INP (Interaction to Next Paint)
Google офіційно зробив INP головною метрикою швидкодії замість старого FID. Якщо раніше ми тестували тільки "швидкість завантаження", то тепер фокус на "швидкості реакції".
Як це впливає на нас: Якщо користувач натиснув на чекбокс або відкрив дропдаун, і UI "задумався" більше ніж на 200 мілісекунд (навіть якщо сторінка вже давно завантажена) — Lighthouse завалить ваш Performance-тест. Час вимірювати мікро-лаги!
Яку фічу забираєте у свій арсенал? 👇
🔥 — Локальний ШІ через Ollama, безпека понад усе!
👀 — Proxyman: пішов ловити бекендерів на гарячому.
🤯 — Lighthouse: у нас весь фронт лагає при кліках, доведеться фіксити...
🧨 Руйнівники IT-міфів: "End-to-End тести мають перевіряти бізнес-логіку бази даних"
Привіт, екіпаж! Сьогодні дістаємо з шафи міф, який змушує ваші E2E-тести працювати годинами і падати через кожну дрібницю. Ця помилка особливо актуальна для тих, хто автоматизує складні системи на сучасних стеках (як-от NestJS + PostgreSQL). ☕️
❌ Міф: "У моєму E2E-тесті користувач проходить співбесіду в 'QA Co-pilot'. В кінці я повинен написати запит до PostgreSQL, дістати його профіль і перевірити, чи правильно ORM зберіг score та history_id у таблицях."
💥 Реальність (Бум!):
End-to-End (UI) тести не повинні лазити в базу даних. Їхня мета — перевірити, чи працює система з точки зору кінцевого користувача. Користувач не має доступу до вашої PostgreSQL.
Він бачить лише те, що відображається в браузері (наприклад, графік результатів або повідомлення "Співбесіду пройдено").
✅ Як має бути (Здоровий підхід):
Золоте правило: Тестуйте систему через ті самі інтерфейси, якими користується клієнт. UI-тести — для UI. API-тести — для логіки БД. Не змішуйте їх у монстрів!
А ваші E2E-тести ходять у базу даних? 👇
🔥 — Ні, перевіряю тільки те, що бачить юзер на екрані!
👀 — Грішу... Підключаюсь до БД, щоб бути на 100% впевненим.
🤯 — Стоп, тобто якщо кнопка натиснулась, мені не треба перевіряти, куди полетіли дані?!
Привіт, екіпаж! Сьогодні дістаємо з шафи міф, який змушує ваші E2E-тести працювати годинами і падати через кожну дрібницю. Ця помилка особливо актуальна для тих, хто автоматизує складні системи на сучасних стеках (як-от NestJS + PostgreSQL). ☕️
❌ Міф: "У моєму E2E-тесті користувач проходить співбесіду в 'QA Co-pilot'. В кінці я повинен написати запит до PostgreSQL, дістати його профіль і перевірити, чи правильно ORM зберіг score та history_id у таблицях."
💥 Реальність (Бум!):
End-to-End (UI) тести не повинні лазити в базу даних. Їхня мета — перевірити, чи працює система з точки зору кінцевого користувача. Користувач не має доступу до вашої PostgreSQL.
Він бачить лише те, що відображається в браузері (наприклад, графік результатів або повідомлення "Співбесіду пройдено").
Якщо ви додаєте в E2E-тест прямі запити до БД (використовуючи Prisma чи pg), ви порушуєте межі абстракції.
🔹Подвійна робота: Перевірка правильності збереження даних у таблицях — це зона відповідальності Integration-тестів на бекенді (на рівні ваших NestJS сервісів та контролерів).
🔹Крихкість: Якщо бекендер змінить назву колонки зі score на total_points, ваш E2E-тест впаде, хоча візуально в Angular-додатку все продовжує працювати ідеально!
✅ Як має бути (Здоровий підхід):
🔹E2E (Playwright/Cypress): Користувач натискає "Завершити", чекає на редирект, бачить текст "Твій результат: 85%". Крапка. Ніяких підключень до БД.
🔹API/Integration (Бекенд): Тест викликає ендпоінт POST /api/interviews/finish, а потім перевіряє через бекенд-інфраструктуру, що дані коректно лягли в PostgreSQL.
Золоте правило: Тестуйте систему через ті самі інтерфейси, якими користується клієнт. UI-тести — для UI. API-тести — для логіки БД. Не змішуйте їх у монстрів!
А ваші E2E-тести ходять у базу даних? 👇
🔥 — Ні, перевіряю тільки те, що бачить юзер на екрані!
👀 — Грішу... Підключаюсь до БД, щоб бути на 100% впевненим.
🤯 — Стоп, тобто якщо кнопка натиснулась, мені не треба перевіряти, куди полетіли дані?!
❤1
🧠 Задача з Senior співбесіди: "Повільний бекенд і швидкі пальці"
Умови задачі:
Питання на співбесіді:
Як 100% надійно автоматизувати перевірку цього багу в E2E-тестах (Playwright/Cypress)?
❌ Відповідь рівня Junior (Хибний шлях):
✅ Відповідь рівня Senior (Підхід Архітектора):
Ми використаємо Network Interception (Мокування мережі), щоб штучно створити цей Race Condition (стан гонитви) прямо в тесті.
Як би ви відповіли на це питання? 👇
🔥 — Ізі, постійно мокаю мережу для таких кейсів!
👀 — Чесно? Ніколи не тестував Race Conditions...
🤯 — А що, можна ставити запити "на паузу" під час тесту?!
Умови задачі:
У вас є поле пошуку (Autocomplete). Коли юзер вводить текст, фронтенд відправляє запити на бекенд.
1️⃣ Юзер вводить літеру "M". Летить запит GET /search?q=M.
2️⃣ Юзер одразу дописує "A". Летить другий запит GET /search?q=MA.
3️⃣ Мережа нестабільна: другий запит (MA) відпрацював швидко (за 100 мс). А перший (M) "завис" і повернув відповідь аж через 500 мс.
Результат на UI: Фронтенд спочатку показав правильні результати для "MA", а потім їх перезаписала запізніла відповідь для "M". Користувач бачить неактуальні дані.
Питання на співбесіді:
Як 100% надійно автоматизувати перевірку цього багу в E2E-тестах (Playwright/Cypress)?
❌ Відповідь рівня Junior (Хибний шлях):
"Я просто напишу текст дуже швидко fill('MA') або поставлю sleep(500) між натисканнями клавіш і буду сподіватися, що злову цей лаг мережі".
Чому це провал: Тест буде "моргаючим" (flaky). Ви не контролюєте реальну мережу в CI/CD.
✅ Відповідь рівня Senior (Підхід Архітектора):
Ми використаємо Network Interception (Мокування мережі), щоб штучно створити цей Race Condition (стан гонитви) прямо в тесті.
Алгоритм (на прикладі Playwright):
1️⃣ Перехоплюємо запити (через page.route()).
2️⃣ Коли летить запит q=M — ми ставимо його "на паузу" і не віддаємо відповідь.
3️⃣ Коли летить запит q=MA — ми миттєво повертаємо мок-відповідь ["Macbook", "MacMini"].
4️⃣ ТІЛЬКИ ПІСЛЯ ЦЬОГО ми "відпускаємо" перший запит q=M із запізнілою відповіддю ["Mouse", "Monitor"].
5️⃣ Перевіряємо UI: на екрані має залишитись результат "Macbook" (фронтенд має ігнорувати старі запити).
Як би ви відповіли на це питання? 👇
🔥 — Ізі, постійно мокаю мережу для таких кейсів!
👀 — Чесно? Ніколи не тестував Race Conditions...
🤯 — А що, можна ставити запити "на паузу" під час тесту?!
❤1
🕵️♂️ Інженерний детектив: Справа про "Раптовий логаут" (або Гонка Refresh-токенів)
Привіт, екіпаж! Середа — час розслідувань. Сьогодні розбираємо баг, який регулярно доводить користувачів до сказу, але розробники часто закривають його з резолюцією "Не відтворюється на моїй машині". ☕️
Сцена злочину (Симптоми):
❌ Хибний слід:
🔍 Що сталося насправді (Race Condition в HTTP-інтерцепторі):
✅ Вирок та Рішення (Як це має перевіряти QA):
Архітектурно ця проблема фікситься на клієнті (наприклад, через RxJS-оператори в Angular або черги в Axios). Коли фронтенд ловить перший 401, він має "заморозити" всі інші запити, оновити токен ОДИН раз, і тільки потім випустити чергу запитів зі свіжим ключем.
Як QA миттєво зловити цей баг:
А вас часто раптово розлогінює в додатках? 👇
🔥 — Тепер зрозуміло! У нас ідеальна черга запитів, перевіряв особисто.
👀 — Чесно? Я думав, це просто бекенд перезавантажився...
🤯 — Пішов псувати свій токен у DevTools, сподіваюсь, ми це пофіксили!
Привіт, екіпаж! Середа — час розслідувань. Сьогодні розбираємо баг, який регулярно доводить користувачів до сказу, але розробники часто закривають його з резолюцією "Не відтворюється на моїй машині". ☕️
Сцена злочину (Симптоми):
Користувач відкриває ваш додаток вранці. Сторінка починає завантажуватись, але замість звичного дашборду його раптово викидає на екран логіну з повідомленням "Сесія закінчилася". Юзер дивується, адже він ставив галочку "Запам'ятати мене" на 30 днів. Він логіниться знову — і все працює ідеально.
❌ Хибний слід:
Джун-тестувальник іде дивитися конфіги бекенду і бачить, що час життя Refresh-токена дійсно 30 днів. Він намагається зловити баг руками, але не може чекати місяць.
Заводить тікет зі статусом "Плаваюча бага: злітає авторизація", який зависає в беклозі на півроку.
🔍 Що сталося насправді (Race Condition в HTTP-інтерцепторі):
Коли ви відкриваєте сучасний додаток, фронтенд зазвичай робить кілька запитів одночасно (наприклад: отримати профіль, стрічку новин, лічильник сповіщень).
Ваш швидкий Access-токен (який живе 15 хвилин) "протух" за ніч. Усі 3 паралельні запити одночасно б'ються об бекенд і отримують помилку 401 Unauthorized.
Що робить "наївний" фронтенд? Він миттєво відправляє ТРИ паралельні запити на POST /refresh, щоб оновити сесію.
Бекенд (з міркувань безпеки) обробляє перший запит, видає свіжі токени і назавжди анулює старий Refresh-токен.
Але щойно бекенд отримує другий і третій запити з тим самим старим Refresh-токеном, він розцінює це як спробу крадіжки сесії хакером! Захист спрацьовує, база даних повністю вбиває сесію, і сервер відправляє жорсткий 401. Фронтенд слухняно викидає юзера на екран логіну.
✅ Вирок та Рішення (Як це має перевіряти QA):
Архітектурно ця проблема фікситься на клієнті (наприклад, через RxJS-оператори в Angular або черги в Axios). Коли фронтенд ловить перший 401, він має "заморозити" всі інші запити, оновити токен ОДИН раз, і тільки потім випустити чергу запитів зі свіжим ключем.
Як QA миттєво зловити цей баг:
Вам не треба чекати 15 хвилин. Зайдіть у додаток, відкрийте DevTools -> Application -> LocalStorage. Знайдіть свій Access-токен і просто видаліть з нього пару літер. Далі оновіть сторінку або перейдіть на "важку" вкладку, яка робить багато запитів. Якщо вас викинуло на екран логіну — Інтерцептор не вміє ставити запити в чергу!
А вас часто раптово розлогінює в додатках? 👇
🔥 — Тепер зрозуміло! У нас ідеальна черга запитів, перевіряв особисто.
👀 — Чесно? Я думав, це просто бекенд перезавантажився...
🤯 — Пішов псувати свій токен у DevTools, сподіваюсь, ми це пофіксили!
📝 Ультимативна Шпаргалка: Test Doubles (або Перестаньте називати все "Моками")
Скільки разів на дейліках ви чули фразу: "Я тут замокАв базу даних і платіжку"? У 90% випадків інженери використовують термін "Mock" неправильно, називаючи так будь-яку підміну реального об'єкта.
Ось класифікація Test Doubles (Тестових дублерів) від Мартіна Фаулера. Збережіть, щоб сяяти на код-рев'ю та співбесідах. ☕️
1️⃣ Dummy (Лялька-манекен)
2️⃣ Stub (Заглушка)
3️⃣ Spy (Шпигун)
4️⃣ Mock (Справжній Мок)
5️⃣ Fake (Фальшивка)
Золоте правило: Якщо ви просто повертаєте статику — це Stub. Якщо перевіряєте кількість викликів — це Spy. Не називайте заглушки моками!
Зізнавайтесь, називаєте все підряд "моками"? 👇
🔥 — Тепер буду душнити на код-рев'ю і виправляти колег!
👀 — Я все життя називав це моками і буду називати далі...
🤯 — Fake та Stub — це не одне й те саме?!
Скільки разів на дейліках ви чули фразу: "Я тут замокАв базу даних і платіжку"? У 90% випадків інженери використовують термін "Mock" неправильно, називаючи так будь-яку підміну реального об'єкта.
Ось класифікація Test Doubles (Тестових дублерів) від Мартіна Фаулера. Збережіть, щоб сяяти на код-рев'ю та співбесідах. ☕️
1️⃣ Dummy (Лялька-манекен)
Що це: Об'єкти, які передаються у функцію просто для того, щоб компілятор чи TypeScript не лаявся. Вони НІКОЛИ не використовуються всередині.
Приклад: Ви тестуєте метод createUser(name, email, avatarUrl). Для тесту вам важливе тільки ім'я, тому замість avatarUrl ви передаєте null або порожній рядок. Це — Dummy.
2️⃣ Stub (Заглушка)
Що це: Тупа підміна, яка завжди повертає захардкоджену відповідь, незалежно від вхідних даних.
Приклад: Ви перехоплюєте запит GET /profile і налаштовуєте його так, щоб він завжди повертав {"role": "admin"}. Він не перевіряє, які заголовки ви йому передали — він просто віддає статику.
3️⃣ Spy (Шпигун)
Що це: Той самий Stub, але він уміє запам'ятовувати, ЩО з ним робили.
Приклад: Ви підмінили функцію відправки email. Після тесту ви запитуєте Шпигуна: "Скільки разів тебе викликали?" або "З якими аргументами до тебе зверталися?". Ідеально для перевірки сайд-ефектів (наприклад, чи відправилась аналітика після кліку).
4️⃣ Mock (Справжній Мок)
Що це: Найрозумніший дублер. У нього заздалегідь "запрограмовані" очікування (Expectations).
Приклад: Ви кажете йому: "Якщо тебе викличуть з ID=5, поверни 200 OK. Якщо з ID=99 — викинь помилку 404. А якщо тебе взагалі не викличуть — завали тест!". Мок сам керує логікою проходження тесту.
5️⃣ Fake (Фальшивка)
Що це: Робоча імплементація, яка робить те саме, що й продакшен-код, але зрізає кути для швидкості.
Приклад: Замість реальної PostgreSQL ви піднімаєте In-Memory базу (наприклад, SQLite), яка зберігає дані в оперативці. Вона реально працює, зберігає і видаляє, але на проді її використовувати не можна.
Золоте правило: Якщо ви просто повертаєте статику — це Stub. Якщо перевіряєте кількість викликів — це Spy. Не називайте заглушки моками!
Зізнавайтесь, називаєте все підряд "моками"? 👇
🔥 — Тепер буду душнити на код-рев'ю і виправляти колег!
👀 — Я все життя називав це моками і буду називати далі...
🤯 — Fake та Stub — це не одне й те саме?!
❤1🤝1
💩 Код з душком: Спільні тестові дані (або Прокляття testuser@gmail.com)
Привіт, екіпаж! П'ятниця — час вивітрювати антипатерни. Сьогодні говоримо про звичку, яка працює на локальному комп'ютері, але перетворює CI/CD пайплайн на суцільне мінне поле. ☕️
Знайдіть проблему в цьому підході:
Чому цей код тхне:
✅ Як це виглядає після код-рев'ю Senior-інженера:
Тести мають дотримуватись принципу F.I.R.S.T. (зокрема, бути Isolated/Ізольованими). Кожен тест повинен жити у своєму вакуумі і генерувати власні унікальні дані.
Золоте правило: Ніколи не хардкодьте імейли чи ID сутностей у тестах. Використовуйте патерн Data Factory / API-генерацію. Тест має сам створити собі "пісочницю", погратися в ній і (бажано) прибрати за собою.
А ваші тести б'ються за один імейл? 👇
🔥 — Ні, у нас API генерує унікальні дані для кожного прогону!
👀 — Грішу... У мене є файл test-users.json на 5 акаунтів...
🤯 — То ось чому мої паралельні тести вічно падають!
Привіт, екіпаж! П'ятниця — час вивітрювати антипатерни. Сьогодні говоримо про звичку, яка працює на локальному комп'ютері, але перетворює CI/CD пайплайн на суцільне мінне поле. ☕️
Знайдіть проблему в цьому підході:
// ❌ Антипатерн "Гуртожиток" (Shared State)
test.beforeEach(async ({ page }) => {
// Усі тести у сьюті логіняться під ОДНИМ юзером
await loginPage.login('qa-test@company.com', 'Qwerty1234');
});
test('Користувач може видалити товар з кошика', async ({ page }) => {
await cartPage.deleteItem();
await expect(page.locator('.empty-cart')).toBeVisible();
});
Чому цей код тхне:
Коли ви запускаєте ці тести по одному на своєму ноуті — все ідеально. Але щойно ви налаштовуєте паралельний запуск (наприклад, workers: 4 у Playwright), починається хаос.
Один тест намагається покласти товар у кошик, а паралельний тест ТІЄЇ Ж СЕКУНДИ натискає кнопку "Очистити кошик" (бо вони сидять під одним акаунтом!). Тести починають вбивати один одного. З'являються сотні "плаваючих" (flaky) багів.
✅ Як це виглядає після код-рев'ю Senior-інженера:
Тести мають дотримуватись принципу F.I.R.S.T. (зокрема, бути Isolated/Ізольованими). Кожен тест повинен жити у своєму вакуумі і генерувати власні унікальні дані.
// 🚀 Ідеально чистий код (Data Isolation)
test.beforeEach(async ({ page, api }) => {
// Динамічно створюємо УНІКАЛЬНОГО юзера для КОЖНОГО тесту через API
const testUser = await api.createUser();
await loginPage.login(testUser.email, testUser.password);
});
test('Користувач може видалити товар з кошика', async ({ page }) => {
// Тест працює у повній ізоляції. Ніхто інший не чіпає цей кошик.
await cartPage.deleteItem();
await expect(page.locator('.empty-cart')).toBeVisible();
});
Золоте правило: Ніколи не хардкодьте імейли чи ID сутностей у тестах. Використовуйте патерн Data Factory / API-генерацію. Тест має сам створити собі "пісочницю", погратися в ній і (бажано) прибрати за собою.
А ваші тести б'ються за один імейл? 👇
🔥 — Ні, у нас API генерує унікальні дані для кожного прогону!
👀 — Грішу... У мене є файл test-users.json на 5 акаунтів...
🤯 — То ось чому мої паралельні тести вічно падають!
📡 Tech Radar: Головне за тиждень (15.06 – 21.06.2026) від QA Co-pilot
Привіт, екіпаж! Новий тиждень — нові інструменти, які знімають рутину і дозволяють сфокусуватися на архітектурі. Сьогоднішній випуск особливо сподобається тим, хто розробляє сучасні мікросервіси та трендові Telegram-додатки. Поїхали! ☕️
📱Playwright TMA Bridge: Нативна підтримка Telegram Mini Apps
🗄 Prisma "Isolated Testing": Ізоляція баз даних з коробки
⚡️Bruno CLI 2.0: Автоматичні Markdown-звіти
Що з цього піде у ваш беклог на впровадження? 👇
🔥 — TMA Bridge! Якраз робимо апку для Телеграму, E2E-тести дуже потрібні.
👀 — Prisma з її ізоляцією — це просто мрія для нашого NestJS-бекенду.
🤯 — Bruno CLI: пішов зносити Postman і налаштовувати CI/CD!
Привіт, екіпаж! Новий тиждень — нові інструменти, які знімають рутину і дозволяють сфокусуватися на архітектурі. Сьогоднішній випуск особливо сподобається тим, хто розробляє сучасні мікросервіси та трендові Telegram-додатки. Поїхали! ☕️
📱Playwright TMA Bridge: Нативна підтримка Telegram Mini Apps
Тестування Telegram Mini Apps завжди було милицею: доводилося вручну мокати об'єкт window.Telegram.WebApp та його івенти, щоб запустити апку в звичайному браузері без клієнта Telegram.
Спільнота випустила офіційний плагін-мост. Тепер ви просто підключаєте його в playwright.config.ts, і ваші E2E-тести отримують повний контроль над "віртуальним" Telegram-оточенням (можна емілювати натискання Main Button, Back Button, зміну теми на темну/світлу та Haptic Feedback).
🗄 Prisma "Isolated Testing": Ізоляція баз даних з коробки
Для тих, хто сидить на стеку NestJS + PostgreSQL + Prisma. Організація паралельного тестування завжди впиралася в конфлікти даних. Раніше треба було писати складні скрипти для створення окремих схем під кожного воркера.
У новому апдейті Prisma додала експериментальну фічу prisma_test_environment. Вона автоматично піднімає ізольовану транзакцію або окрему схему (schema) у PostgreSQL для кожного тест-кейсу і миттєво відкочує (rollback) її після завершення.
Результат: Ваші паралельні API-тести більше ніколи не перетнуться.
⚡️Bruno CLI 2.0: Автоматичні Markdown-звіти
Ми вже "смажили" Postman за його неповороткість. Тим часом опенсорсний Bruno стрімко захоплює ринок. У новій версії їхнього CLI з'явилася нативна генерація красивих Markdown-звітів (з підтримкою Glassmorphism-дизайну у HTML-експорті).
Результат: Ви просто додаєте один прапорець у GitHub Actions, і після прогону API-тестів у ваш Pull Request автоматично публікується стильний і зрозумілий коментар зі статусом усіх ендпоінтів.
Що з цього піде у ваш беклог на впровадження? 👇
🔥 — TMA Bridge! Якраз робимо апку для Телеграму, E2E-тести дуже потрібні.
👀 — Prisma з її ізоляцією — це просто мрія для нашого NestJS-бекенду.
🤯 — Bruno CLI: пішов зносити Postman і налаштовувати CI/CD!
🤯1
⚔️ Битва підходів: Підготовка стану (UI-логін проти API-ін'єкції)
Сьогоднішня битва присвячена найчастішій дії в автотестах — авторизації. Уявіть, що у вас 100 тест-кейсів, і для кожного юзер має бути залогінений. Як ми це робимо? ☕️
🥊 Підхід 1: UI-авторизація (Як роблять новачки)
🥊 Підхід 2: API-ін'єкція стану (Рівень Архітектора)
⚖️ Вердикт QA Co-pilot:
Сьогоднішня битва присвячена найчастішій дії в автотестах — авторизації. Уявіть, що у вас 100 тест-кейсів, і для кожного юзер має бути залогінений. Як ми це робимо? ☕️
🥊 Підхід 1: UI-авторизація (Як роблять новачки)
У блоці beforeEach тест відкриває сторінку /login, знаходить поле email, вводить текст, знаходить password, вводить пароль, натискає кнопку і чекає на редирект.
Плюси: Тест на 100% імітує дії реального користувача.
Мінуси: Це катастрофічно повільно. Якщо UI-логін займає 3 секунди, на 100 тестах ви втрачаєте 5 хвилин просто на введення паролів. А якщо фронтендери змінять дизайн або додадуть капчу — впадуть усі 100 тестів одночасно.
🥊 Підхід 2: API-ін'єкція стану (Рівень Архітектора)
Ви взагалі не відкриваєте сторінку логіну. Ви робите один швидкий HTTP-запит POST /api/auth, отримуєте JWT-токен або Cookie, і напряму "впорскуєте" його в контекст браузера.
Плюси: Авторизація займає 50 мілісекунд замість 3 секунд. Тести повністю ізольовані від змін в UI екрану логіну.
Мінуси: Виникає страх "А раптом сама форма логіну зламалася, а ми це пропустили?".
⚖️ Вердикт QA Co-pilot:
Запам'ятайте золоте правило автоматизації: Тестуйте UI логіну тільки в тестах на логін.
Вам потрібен рівно ОДИН тест, який чесно проходить через UI форму авторизації (перевіряє валідацію, повідомлення про помилки тощо).
Для всіх інших 99 тестів (кошик, профіль, пошук) екран логіну — це просто перешкода. Використовуйте API-ін'єкцію (у Playwright це робиться через request.post та browserContext.addCookies()), щоб миттєво підготувати стан і тестувати саме те, що треба.
🤝1
🧨 Руйнівники IT-міфів: "Справжній E2E-тест має клікати по реальному Google Auth чи Stripe"
Привіт, екіпаж! Сьогодні розбираємо міф, через який автотести обростають "милицями", падають на CAPTCHA і блокуються сторонніми сервісами. ☕️
❌ Міф: "Ми ж пишемо End-to-End! Тому мій Playwright-тест повинен чесно відкрити вікно авторизації Google, ввести реальний логін і пароль, або відкрити справжній віджет Stripe і ввести тестову картку".
💥 Реальність (Бум!):
✅ Як має бути (Підхід Архітектора):
Золоте правило: E2E-тест гарантує, що ваші мікросервіси спілкуються між собою. Чужі мікросервіси хай тестують їхні власні QA.
А ваші тести намагаються обдурити Google чи платіжки? 👇
🔥 — Ніколи! Мокаємо сторонні сервіси або юзаємо API-токени.
👀 — Грішу... Мої тести реально вводять логін і пароль у попапі Google.
🤯 — То ось чому мої тести періодично падають з помилкою Access Denied!
Привіт, екіпаж! Сьогодні розбираємо міф, через який автотести обростають "милицями", падають на CAPTCHA і блокуються сторонніми сервісами. ☕️
❌ Міф: "Ми ж пишемо End-to-End! Тому мій Playwright-тест повинен чесно відкрити вікно авторизації Google, ввести реальний логін і пароль, або відкрити справжній віджет Stripe і ввести тестову картку".
💥 Реальність (Бум!):
Ви не працюєте в Google і не працюєте в Stripe.
Ви не повинні тестувати чужий UI.
🔹CAPTCHA вас знищить: Алгоритми безпеки Google, Facebook або платіжних систем миттєво розпізнають автоматизований браузер (headless mode). Рано чи пізно ваш тест впреться у нескінченну капчу або блокування IP-адреси CI/CD сервера.
🔹Нестабільність (Flakiness): Сторонній сервіс може проводити А/В тестування свого UI, змінити селектори або просто мати мікро-збій. Ваш тест впаде, хоча ВАШ додаток працює ідеально.
✅ Як має бути (Підхід Архітектора):
Тестуйте лише кордони свого додатку. Вас цікавить лише те, як ваша система реагує на успішну чи неуспішну відповідь від стороннього сервісу.
🔹Для авторизації (OAuth): Замість кліків по UI Google, зробіть один API-запит до вашого бекенду, щоб згенерувати тестовий JWT-токен, і покладіть його в localStorage браузера (ми розбирали це в "Битві підходів"). Або використовуйте page.route(), щоб замокати відповідь від провайдера авторизації.
🔹Для платежів: Якщо ви змушені клікати по віджету Stripe — використовуйте їхні офіційні тестові API-ключі або спеціальні інструменти CLI (Stripe CLI) для тригерингу вебхуків про успішну оплату, минаючи UI.
Золоте правило: E2E-тест гарантує, що ваші мікросервіси спілкуються між собою. Чужі мікросервіси хай тестують їхні власні QA.
А ваші тести намагаються обдурити Google чи платіжки? 👇
🔥 — Ніколи! Мокаємо сторонні сервіси або юзаємо API-токени.
👀 — Грішу... Мої тести реально вводять логін і пароль у попапі Google.
🤯 — То ось чому мої тести періодично падають з помилкою Access Denied!