HTTP(s)
+ 10 years in E-commerce
+ 9 years as a QA engineer
ISTQB Certified Tester
Manual/Automation QA engineer
QA lead & exScrum master
CLIENT
SERVER
HTTP REQUEST
HTTP RESPONSE
REQUEST LINE
Method URL HTTP v
HEADERS
empty line
BODY
(опційно)
POST /wow-server/greetings HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: text; charset=utf-8
Content-Length: length
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
hi server!
STATUS LINE
HEADERS
empty line
BODY
(опційно)
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2023 12:28:53 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
Content-Length: 88
Content-Type: text/html
Connection: Closed
<html>
<body>
<h1>Hello, Dear!</h1>
</body>
</html>
GET питає
POST створює
PUT замінює
DELETE видаляє
HTTP RESPONSE
STATUS LINE
HEADERS
empty line
BODY
(опційно)
1xx - Інформаційні:
Ці статуси повідомляють про те, що запит був прийнятий та обробляється.
2xx - Успішно:
Ці статуси позначають успішне завершення запиту.
200 OK: Запит був успішно оброблений.
201 Created: Ресурс успішно створений.
204 No Content: Успішний запит, але відповідь не містить додаткових даних.
3xx - Перенаправлення:
Ці статуси позначають, що для завершення запиту клієнту потрібно зробити додаткові кроки.
301 Moved Permanently: Ресурс переміщений на іншу адресу постійно.
302 Found: Ресурс переміщений на іншу адресу тимчасово.
304 Not Modified: Запитуваний ресурс не змінився з моменту останнього запиту.
4xx - Помилки клієнта:
Ці статуси позначають помилки, які сталися через неправильні запити з боку клієнта.
400 Bad Request: Помилковий або некоректний запит.
401 Unauthorized: Необхідна аутентифікація для доступу до ресурсу.
403 Forbidden: Клієнт має валідний токен аутентифікації, але не має доступу до ресурсу.
404 Not Found: Ресурс не знайдений.
5xx - Помилки сервера:
Ці статуси позначають помилки, які виникли на боці сервера під час обробки запиту.
500 Internal Server Error: Внутрішня помилка сервера.
502 Bad Gateway: Сервер виступає як шлюз або проксі, і одержав неправильну відповідь від вищестоячого сервера.
503 Service Unavailable: Сервер тимчасово не може обробити запит через перевантаження або обслуговування.
Статус коди - це невід'ємна частина ваших тестів
RESTful API (Representational State Transfer API) - це тип архітектури програмного забезпечення для взаємодії між комп'ютерними системами через мережу. Термін "RESTful" походить від фрази "Representational State Transfer", яка вказує на спосіб обміну та управління станом ресурсів.
Representational State Transfer (REST) - це архітектура програмного забезпечення, яка встановлює умови щодо того, як має працювати API.
🤖 Клієнт надсилає запит на сервер. Клієнт дотримується документації API для форматування запиту таким чином, щоб його зрозумів сервер.
🪓 Сервер аутентифікує клієнта і підтверджує, що у клієнта є право робити цей запит.
🔧 Сервер отримує запит і обробляє його внутрішньо.
💌 Сервер повертає відповідь клієнту. Відповідь містить інформацію, яка повідомляє клієнту, чи був запит успішним. Відповідь також включає будь-яку інформацію, яку клієнт запитав.
Принципи:
🤖👽Наявність клієнта і сервера.
😶🌫️ Принцип stateless.
👥 Єдині інтерфейси (Uniform interface) для ресурсів.
👨👧👦 Layered-архітектура.
👜 Можливості кешування відповіді сервера.
Tools:
Документація:
👉 чи документація для API актуальна та повна. Вона повинна надавати вичерпну інформацію про доступні ресурси, методи, параметри та приклади використання.
👉 чи відповідають схемі GraphQL дані, які повертає сервер
Методи HTTP:
👉 чи правильно використовуються методи HTTP (GET, POST, PUT, DELETE) відповідно до RESTful принципів
Обробка Помилок (Error Handling):
👉 як API повертає помилки. Впевніться, що відповіді про помилки містять коректні HTTP статус-коди та інформацію про помилку.
Коректність Запитів:
👉 валідацію параметрів, обробку некоректних URL, обробку неправильного формату даних тощо
👉 тестуємо різні комбінації параметрів та змінних в запитах. Як API обробляє фільтрацію, сортування та пагінацію.
👉 перевіряємо чи механізми аутентифікації та авторизації працюють належним чином. Тестуйте сценарії, коли користувачі мають чи не мають прав для виконання певних операцій.
Корисно знати:
🍓 HTTP(s)
🍓 JSON, XML
🍓 Postman UI
GraphQL - це мова запитів для API, яка дозволяє отримувати та надсилати тільки ту інформацію, яка вам потрібна.
GraphQL є абстракцією над різними протоколами передачі даних, такими як HTTP, WebSocket та іншими. GraphQL може використовувати будь-який протокол, який дозволяє взаємодіяти з сервером.
Найчастіше GraphQL використовується з HTTP. Клієнти формують запити у вигляді HTTP POST запитів на специфічний URL, де цей URL вказує на GraphQL-схему на сервері. Запит містить GraphQL запит у тілі запиту.
{
hero {
name
height
mass
}
}
{
"hero": {
"name": "Luke Skywalker",
"height": 1.72,
"mass": 77
}
}
Tools:
Коректність даних(Data Accuracy):
👉 чи відповідають результати виконання GraphQL-запитів очікуваним значенням.
👉 чи відповідають схемі GraphQL дані, які повертає сервер
Mutation Subscription Testing:
👉 мутації (запити, які модифікують дані на сервері) та як вони впливають на стан системи
👉 якщо API підтримує підписки (subscriptions) для реального часу, переконайтеся, що вони працюють коректно.
Кешування:
👉 перевірка як GraphQL взаємодіє з системою кешування та перевірте, чи відповідає кеш очікуванням
Корисно знати:
🍓 GraphQL documentation
🍓 GraphQL schema
🍓 Queries and Mutations
🍓 Postman UI
gRPC (Google Remote Procedure Call*) — це сучасний високопродуктивний фреймворк віддалених викликів процедур. Він дозволяє додаткам працювати на різних машинах або в різних процесах і спілкуватися один з одним так, ніби вони є частинами одного додатку.
Основні особливості gRPC:
🤖 Використання HTTP/2 — gRPC працює на базі протоколу HTTP/2, який забезпечує двонаправлену потокову передачу, мультиплексування та ефективне управління з'єднаннями.
🤖 Протоколи на основі Protobuf — дані в gRPC передаються в форматі Protocol Buffers (Protobuf), що дозволяє ефективно серіалізувати й десеріалізувати повідомлення.
🤖 Підтримка різних мов програмування — gRPC підтримує багато мов програмування, таких як C++, Java, Python, Go, та інші.
🤖 Підтримка двонаправленого стримінгу — gRPC дозволяє здійснювати одночасну передачу даних у дві сторони.
Remote Procedure Call (RPC) — це метод, який дозволяє комп'ютерним програмам викликати функції або процедури, що виконуються на іншому комп'ютері, як ніби ці функції знаходяться локально. Простіше кажучи, з RPC програми можуть викликати функції на віддаленому сервері так само, як локальні функції, без необхідності турбуватися про деталі комунікації через мережу.
Як це працює:
Клієнт викликає функцію: клієнт викликає функцію на віддаленому сервері так само, як і локальну. Наприклад, клієнт може викликати метод addNumbers(3, 5
), щоб додати два числа на сервері.
Запит передається через мережу: цей виклик перетворюється на повідомлення, яке містить ім'я функції, параметри і, можливо, іншу інформацію, необхідну для її виконання. Це повідомлення відправляється через мережу до сервера.
Сервер виконує функцію: сервер отримує це повідомлення, викликає відповідну функцію з переданими параметрами (у цьому випадку — addNumbers(3, 5)), виконує її і отримує результат.
Результат повертається клієнту: сервер формує відповідь з результатом і відправляє її назад клієнту.
Клієнт отримує результат: клієнт отримує відповідь і продовжує працювати з отриманим результатом (наприклад, сума чисел 3 і 5 — це 8).
👻 Формат повідомлень (Message Format)
Стрімінг і додаткові функції gRPC
gRPC підтримує різні типи взаємодії між клієнтом і сервером, включаючи не тільки класичний підхід "запит-відповідь", але й стрімінг, де дані передаються постійним потоком. Ось роз'яснення цих функцій:
1. Unary RPC (Одноразовий виклик)
Це найпростіший тип виклику, коли клієнт відправляє один запит і отримує одну відповідь.
Приклад: клієнт викликає метод SayHello і отримує відповідь "Привіт!".
Підходить для: стандартних викликів, де потрібно лише одне повідомлення для виконання операції.
2. Server Streaming RPC (Стрімінг з сервера)
Клієнт відправляє один запит, а сервер відповідає потоком даних. Клієнт отримує кілька відповідей протягом певного часу.
Приклад: клієнт запитує історію замовлень, і сервер надсилає потоком всі замовлення по черзі.
Підходить для: великих обсягів даних або випадків, коли сервер поступово отримує результати.
3. Client Streaming RPC (Стрімінг з клієнта)
клієнт передає дані потоком (кілька запитів), а сервер надсилає одну відповідь після отримання всіх запитів.
Приклад: клієнт надсилає великий файл, розбитий на частини, і сервер повертає результат, коли всі частини файлу отримані.
Як це працює?
Клієнт відправляє потік запитів.
Сервер чекає, поки всі запити будуть отримані.
Після отримання всіх даних сервер формує відповідь і повертає її клієнту.
Підходить для: коли клієнт поступово надсилає багато даних.
4. Bidirectional Streaming RPC (Двосторонній стрімінг)
І клієнт, і сервер можуть надсилати дані потоком одночасно. Це двостороння комунікація, де обидві сторони можуть відправляти й отримувати повідомлення у будь-який час.
Приклад: Клієнт і сервер ведуть постійну сесію обміну даними в режимі реального часу, наприклад, для голосового або відеочату.
Клієнт і сервер одночасно надсилають та отримують дані.
Вони можуть передавати повідомлення незалежно один від одного, без необхідності чекати, коли інша сторона завершить відправку.
Підходить для: сценаріїв, де потрібно постійний обмін даними в режимі реального часу
1. Тестування встановлення з'єднання
2. Тестування обміну повідомленнями
Що перевірити:
👉 Коректність відправлення та отримання повідомлень.
👉 Чи відповідає сервер на повідомлення клієнта.
👉 Чи підтримується правильний формат даних (наприклад, текст або бінарні дані).
3. Тестування помилок протоколу: Переконатися, що сервер коректно обробляє неправильні або непідтримувані повідомлення.
Що перевірити:
👉 Відправка некоректних фреймів (наприклад, неправильний формат).
👉 Як сервер реагує на некоректні або надто великі повідомлення.
4. Тестування закриття з'єднання - чекнути, що WebSocket-з'єднання закривається коректно.
Що перевірити:
👉 Закриття з'єднання з ініціативи клієнта та сервера.
👉 Чи надсилаються правильні коди закриття.
👉 Чи не залишається з'єднання відкритим після закриття.
5. Тестування навантаження (Load Testing) - k6, Gatling
6. Тестування безпеки
Що перевірити:
👉 чи з'єднання працює через wss:// (WebSocket Secure).
👉 Чи правильно працює автентифікація та авторизація при WebSocket-з'єднаннях.
gRPC status codes: https://grpc.io/docs/guides/status-codes/
це комунікаційний протокол, який забезпечує двосторонній обмін даними через одне, тривале TCP-з'єднання*. На відміну від HTTP, який працює за моделлю "запит-відповідь", WebSocket дозволяє постійний двосторонній обмін повідомленнями між клієнтом (наприклад, веб-браузером) та сервером.
Основні характеристики WebSocket:
🤖 Двостороннє спілкування: клієнт і сервер можуть незалежно спілкуватися, без необхідності постійно встановлювати нові з'єднання.
🤖 Менше навантаження: менші витрати порівняно з традиційними HTTP-запитами.
🤖 Використання для реального часу: ідеально підходить для додатків, які потребують швидкого та постійного обміну даними.
* TCP-з'єднання — це комунікаційний механізм в мережах, що базується на протоколі передачі даних TCP (Transmission Control Protocol).
HTTP базується на TCP. Коли ви відкриваєте вебсайт, HTTP використовує TCP для передачі даних між вашим комп'ютером (клієнтом) і сервером.
Основні моменти:
Встановлення з'єднання: HTTP використовує TCP для надійного встановлення з'єднання. Клієнт і сервер створюють TCP-з'єднання перед тим, як почати обмін даними.
Передача даних: HTTP передає веб-сторінки, зображення, відео та інші ресурси через TCP. TCP гарантує, що всі ці дані прийдуть без помилок і в правильному порядку.
Закриття з'єднання: після того, як всі дані передані, TCP закриває з'єднання.
Отже, TCP забезпечує стабільність і надійність, тоді як HTTP визначає правила для обміну інформацією, наприклад, що саме передається та як це виглядає.
image source
Перший крок — це HTTP-запит від клієнта до сервера для встановлення WebSocket-з'єднання. Це виглядає як звичайний HTTP-запит з додатковими заголовками.
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
GET /chat HTTP/1.1: Клієнт намагається підключитися до ресурсу /chat.
Upgrade: websocket: Цей заголовок специфічний для запитів WebSocket. Він повідомляє серверу, що клієнт хоче перейти з протоколу HTTP на протокол WebSocket.
Connection: Upgrade: Вказує, що з'єднання повинно бути оновлене.
Sec-WebSocket-Key: Унікальний ключ, який клієнт відправляє для аутентифікації з'єднання. Сервер використовує цей ключ для створення відповідного ключа для відповіді.
Sec-WebSocket-Version: Вказує версію WebSocket-протоколу (в більшості випадків це версія 13).
Перший крок — це HTTP-запит від клієнта до сервера для встановлення WebSocket-з'єднання. Це виглядає як звичайний HTTP-запит з додатковими заголовками.
image source
Якщо сервер підтримує WebSocket і погоджується на з'єднання, він відповідає зі спеціальними заголовками, підтверджуючи перехід на WebSocket-протокол.
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
HTTP/1.1 101 Switching Protocols: Це код відповіді, який вказує, що сервер погоджується на зміну протоколу.
Upgrade: websocket: Сервер підтверджує, що з'єднання буде переведено на WebSocket.
Connection: Upgrade: Вказує, що з'єднання оновлене.
Sec-WebSocket-Accept: Сервер генерує відповідний ключ на основі ключа клієнта (Sec-WebSocket-Key) для підтвердження безпеки.
image source
Після успішного встановлення з'єднання, починається двостороння передача даних у вигляді фреймів (frames). Дані кодуються у форматі WebSocket frame, який може бути текстовим або бінарним.
Client: Hello, server!
Дані передаються у форматі фреймів WebSocket, що забезпечує мінімальні накладні витрати, оскільки не потрібно відкривати нові запити для кожного обміну даними, як у HTTP.
WebSocket підтримує два основні типи даних для передачі повідомлень:
Текстові повідомлення (Text Frames) — це повідомлення у вигляді рядків тексту, зазвичай у форматі UTF-8. Цей тип підходить для передачі текстових даних, таких як JSON або інші текстові формати.
Бінарні повідомлення (Binary Frames) — це повідомлення, які можуть містити будь-які бінарні дані, такі як зображення, аудіо, відео або серіалізовані дані.
Server: Hello, client!
Серіалізовані дані — це спосіб перетворення складних об'єктів або структур даних у формат, придатний для передачі через мережу або збереження у файл. Серіалізація дозволяє представити ці дані у вигляді послідовності байтів (бінарний формат) або тексту (наприклад, JSON, XML), яку потім можна відправити або зберегти.
Серіалізація — це процес перетворення об'єкта або структури даних (наприклад, масиву, об'єкта класу, словника) в послідовність байтів або символів, щоб її можна було:
- Передати через мережу.
- Зберегти у файлі або базі даних.
- Відправити в повідомленні (наприклад, через WebSocket або gRPC).
Фрейм складається з кількох частин:
FIN (1 біт): Це прапорець, який вказує, чи є цей фрейм останнім у повідомленні. Якщо встановлений у 1, це означає, що фрейм є останнім, і повідомлення завершено. Якщо 0 — будуть ще фрейми для цього повідомлення.
Opcode (4 біти): Вказує тип даних, які передаються:
0x0 — продовження попереднього фрейму.
0x1 — текстовий фрейм (корисне навантаження в форматі UTF-8).
0x2 — бінарний фрейм (дані в бінарному форматі).
0x8 — фрейм для закриття з'єднання.
0x9 — ping (для перевірки зв'язку).
0xA — pong (відповідь на ping).
Mask (1 біт): Цей біт вказує, чи масковане корисне навантаження (payload). У запитах від клієнта завжди встановлений у 1 (дані мають бути масковані). Для відповідей сервера він зазвичай 0.
Payload length: Це довжина корисного навантаження. Якщо довжина даних менша за 126 байтів, то ця частина займатиме 7 біт. Якщо довжина більше, то використовуються додаткові біти для представлення повної довжини.
Masking key (32 біти): Якщо Mask біт встановлений в 1, цей ключ використовується для маскування (шифрування) корисних даних. Маскування є обов'язковим для даних, які надсилає клієнт, щоб запобігти певним атакам на мережевому рівні.
Payload (змінна довжина): Це основні дані, які передаються (текст або бінарні дані).
image source
Будь-яка зі сторін (клієнт або сервер) може закрити WebSocket-з'єднання. Це робиться шляхом відправлення спеціального фрейму закриття.
Frame Type: Close
Code: 1000 (Normal closure)
Код 1000
означає "нормальне закриття", що вказує, що з'єднання завершилося без помилок. Після відправлення цього фрейму обидві сторони більше не можуть передавати дані.
Інші коди закриття: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
1. Тестування встановлення з'єднання
2. Тестування обміну повідомленнями
Що перевірити:
👉 Коректність відправлення та отримання повідомлень.
👉 Чи відповідає сервер на повідомлення клієнта.
👉 Чи підтримується правильний формат даних (наприклад, текст або бінарні дані).
3. Тестування помилок протоколу: Переконатися, що сервер коректно обробляє неправильні або непідтримувані повідомлення.
Що перевірити:
👉 Відправка некоректних фреймів (наприклад, неправильний формат).
👉 Як сервер реагує на некоректні або надто великі повідомлення.
4. Тестування закриття з'єднання - чекнути, що WebSocket-з'єднання закривається коректно.
Що перевірити:
👉 Закриття з'єднання з ініціативи клієнта та сервера.
👉 Чи надсилаються правильні коди закриття.
👉 Чи не залишається з'єднання відкритим після закриття.
5. Тестування навантаження (Load Testing) - k6, Gatling
6. Тестування безпеки
Що перевірити:
👉 чи з'єднання працює через wss:// (WebSocket Secure).
👉 Чи правильно працює автентифікація та авторизація при WebSocket-з'єднаннях.