QA Interview Hub · База знань · Тести
Логи й observability
Логи в автоматизації
Консоль браузера й помилки сторінки в Playwright
E2E-тест може пройти зелено, поки в консолі браузера летять необроблені винятки або 500-ті на фонових запитах. Playwright дозволяє слухати ці події:
page.on('console', msg => …) — виклики console.*; msg.type() повертає 'error', 'warning', 'log' тощо, msg.text() — текст;
page.on('pageerror', err => …) — необроблені винятки на сторінці;
page.on('requestfailed', req => …) — мережеві збої; page.on('response', …) — відповіді (можна відфільтрувати status() >= 500).
Найзручніше загорнути це в авто-фікстуру, щоб правило діяло на всі тести:
import { test as base, expect } from '@playwright/test';
export const test = base.extend<{ browserErrors: string[] }>({
browserErrors: [
async ({ page }, use) => {
const errors: string[] = [];
page.on('pageerror', (e) => errors.push(e.message));
page.on('console', (m) => {
if (m.type() === 'error') errors.push(m.text());
});
await use(errors);
expect(errors, 'unexpected browser errors').toEqual([]);
},
{ auto: true },
],
});
Нюанси:
- підписку роблять до навігації, інакше ранні помилки пропадуть;
- потрібен список дозволених винятків (allowlist) для відомого шуму сторонніх скриптів (аналітика, віджети) — інакше тести стануть червоними через те, що команда не контролює; але allowlist має бути вузьким і з коментарем;
- якщо тест навмисно викликає помилку (негативний сценарій), він очікує її явно, а не вимикає перевірку;
- помилки конкретного ресурсу (наприклад, 404 на favicon) бувають шумом; фільтрують за URL, а не вимикають усе.
Так фронтенд-регресії ловляться відразу, без окремого тесту «чи немає помилок у консолі».
Серверні логи в CI, перевірка логів у тестах і логування самого тесту
Серверні логи як артефакт CI. Коли e2e падає в CI, одного скріншота мало: потрібні й логи застосунку за той самий час. Підхід: запускати сервіси так, щоб їхній вивід зберігався (docker compose logs --no-color --timestamps > server.log або файл, на який налаштовано логер), а наприкінці джоби завантажити його як артефакт — з умовою, що виконується й після падіння:
- name: Collect service logs
if: ${{ !cancelled() }}
run: docker compose logs --no-color --timestamps > server.log
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: server-logs
path: server.log
retention-days: 7
Щоб зіставити тест із записами, кожен запит тесту несе свій traceparent / X-Request-Id, а його значення додають у звіт (testInfo.annotations.push або testInfo.attach('server-log', { body, contentType: 'text/plain' })).
Перевірка логів у тесті. Інколи потрібно впевнитись, що подія залогована (аудит, безпека, «секрет не потрапив у лог»). Це доречно, коли:
- лог — частина вимоги (аудит дій, compliance), а не випадковий текст;
- шукаємо за структурованими полями й унікальним id, а не за підрядком повідомлення;
- очікування з
expect.poll/toPass, бо логи доходять до сховка із затримкою.
Крихко, коли тест перевіряє точне формулювання повідомлення, порядок рядків чи DEBUG-логи: будь-який рефакторинг ламає тест, хоча поведінка не змінилась. Те, що важливо для бізнесу, краще виставляти як подію чи метрику з контрактом.
Логування в самому тесті. Кроки робіть через test.step('…', async () => …) — вони потрапляють у звіт і trace. Дані для діагностики (відповідь API, відповідний уривок лога) додавайте як testInfo.attach. Не залишайте console.log по всьому коду: він засмічує вивід, а в паралельних воркерах рядки перемішуються.
Секрети й PII у логах, шум і retention
Логи читає багато людей і живуть вони довго, тому те, що туди потрапило, витікає. Не можна логувати: паролі, токени (access/refresh, API keys), повні номери карток, CVV, повні тіла запитів автентифікації, а також персональні дані (email, телефон, адреса, документи) — вони підпадають під GDPR та інші регуляції.
Що роблять:
- Маскування/редагування на рівні логера чи в OTel Collector:
Authorization: Bearer ***, картка → **** 4242, email → хеш чи частковий вигляд;
- логувати ідентифікатор користувача (внутрішній id), а не email чи ім’я;
- allowlist полів для запитів/відповідей замість «логуємо все, потім видаляємо»;
- вимкнений DEBUG на проді та контроль доступу до логів.
Роль QA: перевірити (вручну чи автотестом), що після логіну, оплати, скидання пароля чутливі значення не з’являються у логах і в тілі помилок; у CI-логах секрети маскуються (GitHub Actions маскує значення secrets, але не похідні від них, наприклад, закодовані у base64); тестові дані не містять реальних персональних даних.
Шум. Якщо ERROR щодня сотні й ніхто не дивиться, реальну проблему не помітять. Ознаки: очікувані винятки логуються як ERROR (наприклад, «користувача не знайдено» при невірному логіні); один і той самий запис тисячі разів на секунду; health-check спамить INFO. Рішення: правильні рівні, дедуплікація, семплінг, винесення помилок у трекер із групуванням.
Retention. Логи зберігають обмежений час (діб, тижнів) — через вартість і вимоги приватності; аудит-логи можуть мати довший строк. Для QA це означає: артефакти й логи зі збійного прогону слід вичитати чи зберегти, поки вони не зникли; у баг-репорт вкладайте уривок, а не посилання на запис, який видалиться.