Swagger и OpenAPI для тестировщика: как читать API и находить проверки
Практический Swagger/OpenAPI гайд для Manual QA: endpoints, parameters, request body, schemas, auth, responses, негативные тесты и переход к Java REST Assured.
Самая полезная привычка при тестировании API — не начинать с кнопки Try it out.
Сначала прочитай контракт.
Что endpoint обещает принять? Какие поля обязательные? Какие значения допустимы? Нужна ли авторизация? Какие ответы описаны? Что означает каждый статус? Как выглядит schema?
Если ты умеешь вытаскивать из Swagger/OpenAPI эти ответы, документация превращается в почти готовый источник тест-кейсов.
В вакансиях Manual QA Swagger регулярно встречается рядом с Postman, API и SQL. Это логично: Postman помогает отправлять запросы, а OpenAPI помогает понять, какие запросы система обещает поддерживать.
Термины часто используют как синонимы, но полезно различать.
OpenAPI Specification (OAS) — стандарт описания HTTP API в машинно-читаемом формате.
Swagger — набор инструментов вокруг OpenAPI: например Swagger UI визуализирует контракт, Swagger Editor помогает его редактировать.
Актуальная OpenAPI Specification описывает стандартный интерфейс, по которому человек или программа может понять доступные paths, operations, parameters, request bodies, responses и security без чтения исходного кода сервиса.
В ежедневной работе QA это часто выглядит просто: разработчик даёт ссылку на Swagger UI, а интерфейс визуализирует OpenAPI JSON/YAML. Для ShawarmaShop текущая спецификация — OpenAPI 3.0.1, API version 1.0.0, server https://shawarma.threadqa.ru.
- Открыть учебный стенд ShawarmaShop
Реальный интерфейс приложения для практики UI и поиска запросов в DevTools.
- Открыть Swagger UI ShawarmaShop
Контракт API, endpoints, request body, schemas и responses.
В текущем ShawarmaShop Swagger сгруппирован по tags: Orders, Authentication, Events, Payments, Recipes и Ingredients. Это удобно для чтения домена: заказы и платежи разделены, Events показывает доменные события из Kafka, а Ingredients описан как owner-only зона.
Представим endpoint:
1POST /api/v1/ordersНе нажимай Send сразу. Пройди по структуре.
1. Method и path
1POST /api/v1/ordersУже появляется первый набор вопросов:
- ▸кто может создать заказ;
- ▸можно ли отправить повтор;
- ▸что считается дублем;
- ▸что произойдёт без авторизации.
2. Parameters
Параметры могут быть:
- ▸path;
- ▸query;
- ▸header;
- ▸cookie.
Например:
1GET /api/v1/orders/{id}id — path parameter.
Проверки:
1валидный id
20
3-1
4очень большой id
5строка вместо числа
6несуществующий idЕсли есть query:
1GET /api/v1/orders
2query: status=PAID
3query: minPrice=500
4query: recipeId=42
5query: pageable (required)из трёх параметров можно получить десятки комбинаций.
3. Request body
Swagger UI обычно показывает schema и example.
Например:
1{
2 "recipeId": 42,
3 "qty": 2,
4 "payment": { "method": "CARD" }
5}QA должен выяснить:
- ▸какие поля required;
- ▸какие nullable;
- ▸тип каждого поля;
- ▸min/max;
- ▸enum;
- ▸pattern;
- ▸длина строки;
- ▸вложенные объекты;
- ▸массивы.
И сразу превратить каждое ограничение в тест.
Допустим OpenAPI описывает:
1qty:
2 type: integer
3 format: int32
4 minimum: 1Минимальный набор проверок:
11 valid minimum boundary
22 valid value
30 invalid by schema
4-1 invalid by schema
5null invalid: qty is required
6"2" wrong type
72.5 wrong type / coercion check
810000 schema не задаёт maximum — это уже отдельная business-проверкаТо есть Boundary Value Analysis буквально лежит внутри контракта.
Другой пример:
1status:
2 type: string
3 enum:
4 - PENDING
5 - PAID
6 - PREPARING
7 - DONE
8 - CANCELLEDТесты:
1PENDING
2PAID
3PREPARING
4DONE
5CANCELLED
6pending
7UNKNOWN
8""
9nullНе надо придумывать тест-дизайн отдельно от API. Спецификация уже даёт сырьё.
Поле может быть обязательным, но допускать null, либо быть необязательным, но если передано — должно соответствовать schema. Детали зависят от версии OpenAPI и описания контракта.
С точки зрения QA нужно отдельно проверить:
1поле отсутствует
2поле = null
3поле = ""
4поле имеет правильное значение
5поле имеет неправильный типЭто пять разных сценариев.
Нормальный контракт описывает несколько ответов.
Например:
1POST /api/v1/orders → 200
2POST /api/v1/auth/login → 200 / 400
3GET /api/v1/auth/me → 200 / 401
4GET /api/v1/recipes/{id} → 200 / 404
5PATCH /api/v1/recipes/{id} → 200 / 404 / 409
6GET /api/v1/recipes/{id}/reviews → 200 / 404 / 502Каждый описанный response — кандидат на тест.
Но есть ещё более интересный класс дефектов: фактический API возвращает то, чего нет в контракте.
Например Swagger обещает:
1{
2 "code": "VALIDATION_ERROR",
3 "message": "qty must be at least 1"
4}а backend возвращает:
1{
2 "timestamp": "...",
3 "error": "Bad Request",
4 "trace": "java.lang.IllegalArgumentException..."
5}Тут проблема не только в status code. Контракт и реализация разошлись, а наружу мог утечь stack trace.
В ShawarmaShop security scheme описана конкретно: bearer-jwt, HTTP Bearer JWT. Токен берётся из POST /api/v1/auth/login.
Если endpoint защищён, минимальный набор:
- ▸без credentials;
- ▸invalid credentials;
- ▸expired token;
- ▸корректный JWT;
- ▸GET /api/v1/auth/me с валидным JWT;
- ▸owner-only операции Ingredients — отдельно сверить фактическую авторизацию с документацией.
Именно последний тест часто важнее всех предыдущих.
1GET /api/v1/auth/meДля GET /api/v1/auth/me контракт явно описывает 401 без авторизации. При этом Ingredients помечены как «только OWNER» — это отдельная зона для проверки role-based access, даже если 403 не перечислен в responses каждого endpoint.
Swagger не ответит за тебя, но быстро покажет поверхность API, по которой стоит пройтись.
Swagger UI позволяет выполнить запрос прямо из документации. Это удобно для smoke-проверки.
Но у него есть ограничения как у полноценного QA workflow:
- ▸неудобно хранить большие наборы сценариев;
- ▸сложнее управлять окружениями и данными;
- ▸хуже организовывать последовательности запросов;
- ▸не всегда удобно писать assertions.
Поэтому практический процесс часто такой:
Swagger/OpenAPI → понять контракт → Postman → систематически проверить.
Отдельный гайд: Postman для тестировщика: REST API с нуля.
Postman поддерживает работу с API definitions и коллекциями, поэтому из спецификации можно получить хорошую стартовую структуру запросов.
Но не путай generated collection с готовым тестовым покрытием.
Спецификация знает:
1какие endpoint существуют
2какие поля объявлены
3какие responses описаныНо она не знает всей реальной бизнес-логики:
1можно ли отменить заказ после выхода из PENDING
2что произойдёт при повторной оплате с тем же Idempotency-Key
3как система ведёт себя при FAILED webhook от платёжного провайдера
4что происходит при недоступности partner reviews-serviceИменно здесь нужен тестировщик, а не генератор.
Что QA уже может найти в этой спецификации без единого запроса
Чтение контракта — это уже тестирование. В текущем api-docs ShawarmaShop есть несколько мест, которые стоит обсудить с backend-командой. Это именно contract findings: по одной спецификации нельзя утверждать, что runtime работает неправильно.
- ▸Top-level security задаёт bearer-jwt глобально. POST /api/v1/auth/login не переопределяет security пустым массивом, поэтому формально наследует требование JWT. Если login на runtime публичный, документацию стоит уточнить.
- ▸POST /api/v1/recipes/{id}/image называется «multipart», но requestBody в текущем JSON описан как application/json с binary file. Для настоящего multipart обычно ожидается соответствующий media type — это повод проверить Swagger UI и фактический запрос.
- ▸Описание POST /api/v1/orders/{id}/cancel говорит, что PREPARING/COMPLETED отменить нельзя, но enum OrderResponse содержит DONE, а значения COMPLETED в enum нет. Терминологию стоит синхронизировать.
- ▸CreateOrderRequest задаёт required-поля, qty minimum=1 и enum CARD/CASH, но у POST /api/v1/orders в responses описан только 200. Фактические validation errors нужно проверить и затем либо документировать, либо явно согласовать контракт.
Так выглядит зрелая работа со Swagger: не просто нажать Try it out, а проверить, что сам контракт непротиворечив, достаточно полный и совпадает с runtime.
Swagger — тоже часть продукта. Он может устареть.
Составь отдельный mini-checklist contract drift:
- ▸endpoint есть в Swagger, но возвращает 404;
- ▸endpoint работает, но отсутствует в docs;
- ▸поле renamed в backend, но не в schema;
- ▸обязательность поля не совпадает;
- ▸новый enum value не описан;
- ▸status code отличается;
- ▸example устарел;
- ▸auth scheme не соответствует реальному запросу.
На больших проектах рассинхрон docs и backend сильно замедляет и QA, и frontend, и интеграторов.
Допустим есть:
1POST /api/v1/ordersSchema:
1{
2 "recipeId": 42,
3 "qty": 2,
4 "payment": { "method": "CARD" }
5}Описано:
1recipeId required, int64
2qty required, int32, minimum=1
3payment required
4payment.method required, enum CARD | CASH
5успешный response: 200 + OrderResponse
6status нового заказа: PENDING
7отдельные 4xx для invalid CreateOrderRequest в этой спецификации не перечисленыТестовый набор:
Positive
- ▸существующий recipeId + qty=1 + CARD;
- ▸существующий recipeId + qty=2 + CASH;
- ▸сверить recipe, qty, totalPrice и payment в OrderResponse.
Validation
- ▸qty=0;
- ▸qty=-1;
- ▸qty="two";
- ▸recipeId отсутствует;
- ▸qty отсутствует;
- ▸payment отсутствует;
- ▸payment.method=CRYPTO;
- ▸пустой body.
Resource
- ▸recipeId не существует;
- ▸недостаточный остаток ингредиентов — проверить фактическое бизнес-поведение, если сценарий доступен.
Auth
- ▸без token;
- ▸invalid token;
- ▸expired token.
Contract
- ▸response соответствует schema;
- ▸тип id правильный;
- ▸status входит в допустимый набор;
- ▸лишние sensitive поля не возвращаются.
Из одного endpoint уже получился нормальный regression subset. И здесь есть полезная находка именно для QA: schema подробно задаёт required/minimum/enum, но invalid responses для POST /api/v1/orders в текущем OpenAPI не перечислены. Это не повод выдумывать 400/422 — это повод проверить фактическое поведение и завести вопрос на уточнение контракта.
Лучший endpoint для проверки идемпотентности: оплата заказа
В спецификации есть редкая и очень полезная для обучения деталь: POST /api/v1/orders/{id}/pay требует header Idempotency-Key. Описание прямо фиксирует требование: повторный POST с тем же ключом возвращает уже созданный платёж без повторного вызова провайдера. В реальной БД ShawarmaShop это требование поддержано на persistence-слое: payments.idempotency_key — UNIQUE NOT NULL. Поэтому сильная QA-проверка может доказать идемпотентность одновременно через API и SQL.
1POST /api/v1/orders/7812/pay
2Authorization: Bearer <token>
3Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
4Content-Type: application/json
5
6{ "method": "CARD" }- ▸вызвать pay с новым Idempotency-Key;
- ▸повторить тот же request с тем же ключом;
- ▸сравнить payment.id и txnId;
- ▸проверить GET /api/v1/orders/{id}/payments — лишний платёж появиться не должен; при доступе к БД дополнительно проверить COUNT(*) в payments по тому же idempotency_key;
- ▸повторить с другим ключом и зафиксировать фактическое бизнес-поведение.
Swagger показывает структуру, но без понимания HTTP можно механически нажимать кнопки и не понимать результат.
Нужно знать:
- ▸чем POST отличается от PATCH и почему PUT отсутствует в текущем контракте;
- ▸что означают 400/401/404/409/502 в конкретных операциях;
- ▸что делает Authorization header;
- ▸почему browser request может отличаться от Postman.
Поэтому держи рядом HTTP для тестировщика.
Очень сильное упражнение:
- ▸1. открой Swagger;
- ▸2. найди endpoint создания заказа;
- ▸3. выпиши method и schema;
- ▸4. открой приложение;
- ▸5. DevTools → Network;
- ▸6. создай заказ через UI;
- ▸7. сравни реальный request со Swagger.
Проверяй:
- ▸тот ли endpoint;
- ▸тот ли method;
- ▸передаются ли обязательные поля;
- ▸не отправляет ли frontend лишние данные;
- ▸совпадают ли типы;
- ▸соответствует ли response schema.
Ты буквально тестируешь сразу frontend ↔ contract ↔ backend.
Теперь главный переход.
Из OpenAPI мы узнали:
1POST /api/v1/orders
2Content-Type: application/json
3body: CreateOrderRequest
4response: 200 + OrderResponse
5new order status: PENDINGВ Java это естественно превращается в модели и тест:
1CreateOrderRequest request = new CreateOrderRequest(
2 42L, 2, new PaymentChoice("CARD")
3);
4
5OrderResponse response = given()
6 .header("Authorization", "Bearer " + token)
7 .contentType(ContentType.JSON)
8 .body(request)
9.when()
10 .post("/api/v1/orders")
11.then()
12 .statusCode(200)
13 .extract()
14 .as(OrderResponse.class);
15
16assertThat(response.status()).isEqualTo("PENDING");
17assertThat(response.qty()).isEqualTo(2);Manual QA уже сделал самую важную часть: разобрал endpoint, придумал позитивные и негативные сценарии и понял ожидаемый контракт.
Automation добавляет:
- ▸Java models;
- ▸reusable API clients;
- ▸assertions;
- ▸data generation;
- ▸массовый запуск;
- ▸reports;
- ▸CI/CD.
В Java QA Automation ThreadQA Swagger и HTTP используются как база для REST Assured, а дальше тесты связываются с PostgreSQL, Kafka, WireMock и ShawarmaShop. То есть знакомая manual-проверка становится инженерным тестовым фреймворком постепенно, а не одним прыжком.
При первом знакомстве с сервисом проверь:
- ▸все paths;
- ▸methods;
- ▸path/query/header params;
- ▸required fields;
- ▸типы;
- ▸nullable;
- ▸min/max;
- ▸string length/pattern;
- ▸enums;
- ▸request examples;
- ▸response schemas;
- ▸status codes;
- ▸auth scheme;
- ▸deprecated operations;
- ▸расхождения Swagger vs реальное API.
Если endpoint сложный, этот список легко превращается в тестовую модель.
- ▸HTTP для тестировщика
- ▸Postman для тестировщика
- ▸Chrome DevTools для тестировщика
- ▸SQL для тестировщика
- ▸Java QA Automation ThreadQA
FAQ
Swagger и OpenAPI — одно и то же?
OpenAPI — спецификация описания HTTP API. Swagger — экосистема инструментов вокруг неё. В разговорной речи «Swagger» часто означает Swagger UI с OpenAPI-документацией.
Можно ли тестировать API только в Swagger?
Для быстрых проверок — да. Для системного regression удобнее использовать Postman или кодовые автотесты.
Что тестировщик должен смотреть в Swagger первым?
Method/path, параметры, required fields, request schema, responses и security. Это сразу даёт основу набора тестов.
OpenAPI заменяет тест-кейсы?
Нет. Спецификация описывает контракт, но не знает всей бизнес-логики, пользовательских состояний и интеграционных рисков.
Нужно ли знать YAML?
На старте достаточно читать Swagger UI. Затем полезно научиться понимать базовую OpenAPI YAML/JSON структуру — paths, schemas, required, enum, responses.