QA Interview Hub · База знань · Тести

Мережі

Мережа в роботі QA

DevTools Network, HAR, throttling і offline

Вкладка Network — головний інструмент розбору. Що в ній дивитися:

  • фільтри (Fetch/XHR, WS, Doc), пошук по тілу відповідей, Preserve log (щоб редиректи й навігація не стирали список), Disable cache;
  • стовпці Status, Protocol (h2, h3), Initiator (хто створив запит), Time;
  • Timing запиту: Queueing/Stalled (очікування слоту), DNS Lookup, Initial connection, SSL, Request sent, Waiting (TTFB), Content Download. Довгий Waiting — повільний сервер; довгі DNS/SSL — мережа чи нове з'єднання; довгий Stalled — забагато запитів на домен;
  • Для WebSocket — вкладка Messages з кадрами в обох напрямках.

HAR (HTTP Archive) — JSON-запис усієї мережевої активності. «Save all as HAR» додають до багу замість скриншота; але HAR містить cookies, токени й тіла відповідей, тому перед передаванням його очищають. У Playwright recordHar в опціях контексту записує HAR під час тесту, а page.routeFromHAR(path) відтворює його замість реальної мережі (режим update: true оновлює запис).

Повільна мережа. У DevTools є профілі Fast/Slow 4G, Offline і власні. У Playwright немає вбудованого троттлінгу: для Chromium використовують CDP:

const cdp = await context.newCDPSession(page);
await cdp.send('Network.enable');
await cdp.send('Network.emulateNetworkConditions', {
  offline: false,
  latency: 400, // мс
  downloadThroughput: (500 * 1024) / 8, // байт/с
  uploadThroughput: (250 * 1024) / 8,
});

Працює лише в Chromium. Офлайн емулюють await context.setOffline(true) (і false, щоб «повернути» мережу): так перевіряють банер «немає з'єднання», чергу відкладених дій і відновлення. Окремі запити повільнюють у page.route, додавши затримку перед route.continue(). Для реалістичнішої перевірки на рівні ОС користуються системними емуляторами (Network Link Conditioner, tc / toxiproxy).

Перехоплення й підміна запитів, проксі-інструменти

Перехоплення в самому тесті. page.route(url, handler) (або context.route, що діє на всі сторінки контексту) дозволяє три дії: route.fulfill() повернути свою відповідь, route.continue() пропустити (за потреби змінивши заголовки чи тіло), route.abort(code) обірвати з мережевою помилкою. Коди помилок для abort: 'connectionrefused', 'connectionreset', 'timedout', 'namenotresolved', 'internetdisconnected', 'failed' та інші.

// сервер недоступний: перевіряємо повідомлення про помилку
await page.route('**/api/orders', (route) => route.abort('connectionrefused'));

// сповільнення одного запиту
await page.route('**/api/report', async (route) => {
  await new Promise((r) => setTimeout(r, 5000));
  await route.continue();
});

abort моделює саме мережеві збої (fetch завершується TypeError, у Network з'являється failed), тоді як fulfill({ status: 503 }) — відповідь сервера з кодом помилки. UI зазвичай обробляє ці два випадки по-різному, тож тестують обидва. Підміна завжди прикриває справжню інтеграцію, тому моки — доповнення до кількох e2e без моків, а не заміна.

Проксі-інструменти стоять між клієнтом і сервером і працюють з будь-яким клієнтом (мобільний застосунок, десктоп), не лише з браузером Playwright:

  • Charles, Fiddler, Proxyman: GUI, перегляд і зміна трафіку, Map Local/Map Remote, throttling, breakpoints;
  • mitmproxy: той самий підхід, але зі скриптами на Python і режимом командного рядка, добре підходить для автоматизації;
  • для HTTPS їхній кореневий сертифікат доводиться додати в довірені на пристрої (на Android з певної версії застосунки не довіряють користувацьким кореням без дозволу в маніфесті, а certificate pinning такий трафік блокує повністю).

Типові сценарії: підмінити відповідь бекенда без зміни коду, відтворити 500 чи повільну відповідь на мобільному, подивитися, що саме надсилає SDK, перевірити, що застосунок не передає зайвих даних. Для захищеного (pinned) клієнта використовують тестову збірку без pinning.

Діагностика мережевих збоїв: curl, dig і класи помилок

Нестабільний тест із «мережевою» помилкою треба зводити до шару. Порядок: ім'я → з'єднання → TLS → HTTP → застосунок.

СимптомШар і типова причина
ENOTFOUND, ERR_NAME_NOT_RESOLVEDDNS: помилка в імені, немає запису, резолвер або VPN
ECONNREFUSEDTCP: порт ніхто не слухає (сервіс не стартував, не той порт, слухає лише 127.0.0.1)
Timeout без відповідіTCP/мережа: фаєрвол відкидає пакети, хост недоступний
ECONNRESET, socket hang upЗ'єднання обірвала друга сторона: падіння процесу, idle timeout, перевантаження
ERR_CERT_*, UNABLE_TO_VERIFY_LEAF_SIGNATURETLS: прострочений, самопідписаний чи неповний ланцюжок, невідповідність імені
502 Bad GatewayПроксі отримав некоректну відповідь або не зміг з'єднатися з upstream (upstream впав, перезапуск)
503 Service UnavailableСервіс недоступний чи перевантажений (немає здорових бекендів)
504 Gateway TimeoutПроксі не дочекався відповіді upstream у межах свого таймауту

Важливо: 502/503/504 приходить від проксі чи балансувальника, тож з'єднання з ним працює, а проблема за ним. Тіло відповіді (HTML nginx/CDN замість JSON) і заголовок Server/Via підказують, хто її віддав.

Інструменти.

curl -v https://example.com/health               # DNS, TLS, заголовки запиту й відповіді
curl -sS -o /dev/null -w "dns=%{time_namelookup} tcp=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n" https://example.com
curl --resolve example.com:443:203.0.113.10 https://example.com   # обійти DNS, вказати IP
dig +short example.com A                         # що каже DNS
dig @1.1.1.1 example.com                         # інший резолвер
ping example.com                                 # доступність хоста (ICMP може бути вимкнено)
traceroute example.com                           # тут: tracert на Windows; шлях і де зникають пакети
nc -vz example.com 443                           # чи відкритий порт (на Windows: Test-NetConnection)

Підхід до flaky-мережі. Знайти закономірність: час доби, конкретний раннер чи регіон, перший запит після простою (холодне з'єднання, DNS), рівно N секунд (таймаут). Додати до логів тесту URL, час, статус, x-request-id і trace/HAR; не лікувати ретраєм без розуміння причини. Для API з тестового раннера у CI варто мати keep-alive, пул з'єднань і явні таймаути клієнта.