Lesson 4 of 26

Урок 04 — Тестирование веб-сервисов. SOAP и XML, REST и JSON

Название: Два мира веб-сервисов: SOAP и REST — когда что использовать
Описание: Разбираем два главных стандарта обмена данными между системами. Изучаем форматы XML и JSON, понимаем архитектуру SOAP и REST, учимся тестировать веб-сервисы обоих типов.
Почему это важно для QA: Большинство современных приложений используют API для общения с сервером. Понимание SOAP и REST, умение читать XML и JSON — обязательный навык для QA-инженера любого уровня.


1. Что такое веб-сервис

Веб-сервис — это программа, доступная через интернет, которая принимает запросы от других программ и возвращает данные. Она не имеет интерфейса — только «дверь» для программного обмена данными.

Приложение A ──── HTTP-запрос ──── Веб-сервис ──── HTTP-ответ ──── Приложение A
             →  "Дай курсы валют"                ← {"USD": 89.5}

Веб-сервисы бывают двух основных типов:

  • SOAP — старый, строгий, используется в банках, медицине, Enterprise
  • REST — современный, гибкий, используется в большинстве новых проектов

2. XML — формат данных для SOAP

XML (eXtensible Markup Language — расширяемый язык разметки) — это формат хранения и передачи данных с помощью тегов.

Синтаксис XML

xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<users>
  <user id="42">
    <name>Алина Иванова</name>
    <email>alina@example.com</email>
    <age>28</age>
    <isActive>true</isActive>
    <addresses>
      <address type="home">
        <city>Москва</city>
        <street>Ленина, 10</street>
      </address>
      <address type="work">
        <city>Москва</city>
        <street>Тверская, 5</street>
      </address>
    </addresses>
  </user>
</users>

Правила XML

  1. Один корневой элемент — весь документ обёрнут в один тег (<users>)
  2. Теги закрываются — каждый открывающий тег <name> имеет закрывающий </name>
  3. Вложенность — теги не перекрываются: <a><b></b></a> правильно, <a><b></a></b> нет
  4. Регистр важен<Name> и <name> — разные теги
  5. Атрибуты — дополнительные данные в открывающем теге: <user id="42">
  6. Специальные символы нужно экранировать:
СимволЗамена
<&lt;
>&gt;
&&amp;
"&quot;
'&apos;

XPath — язык запросов к XML

XPath (XML Path Language) — используется для извлечения данных из XML.

xmlxml
<!-- Документ -->
<catalog>
  <book id="1">
    <title>Тестирование веб-приложений</title>
    <price>990</price>
  </book>
  <book id="2">
    <title>Playwright для QA</title>
    <price>1290</price>
  </book>
</catalog>
/catalog/book[1]/title          →  "Тестирование веб-приложений"
/catalog/book[@id="2"]/price    →  "1290"
//title                         →  все элементы <title> в документе
/catalog/book[price>1000]/title →  "Playwright для QA"

XPath используется и для поиска элементов в HTML при тестировании через Selenium/Playwright.


3. SOAP — строгий протокол корпоративного мира

SOAP (Simple Object Access Protocol — протокол доступа к объектам) — это протокол обмена сообщениями между сервисами. Передаёт данные исключительно в формате XML.

Структура SOAP-сообщения

Каждое SOAP-сообщение — это XML-конверт с тремя частями:

xmlxml
<soap:Envelope
  xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:auth="http://example.com/auth">

  <!-- Заголовок — необязательный (метаданные, авторизация) -->
  <soap:Header>
    <auth:AuthToken>Bearer eyJhbGciOiJIUzI1NiJ9...</auth:AuthToken>
  </soap:Header>

  <!-- Тело — обязательное (сама операция) -->
  <soap:Body>
    <auth:GetUserRequest>
      <auth:UserId>42</auth:UserId>
    </auth:GetUserRequest>
  </soap:Body>

</soap:Envelope>

WSDL — «контракт» SOAP-сервиса

WSDL (Web Services Description Language) — это XML-документ, который описывает, какие операции поддерживает SOAP-сервис, какие данные принимает и что возвращает.

WSDL — как меню в ресторане:
  - Какие блюда есть (операции/методы)
  - Из чего состоит каждое блюдо (параметры запроса)
  - Что получишь в результате (параметры ответа)

WSDL-файл обычно доступен по URL: https://api.example.com/service?wsdl

Запрос и ответ SOAP — пример

Запрос: узнать баланс счёта

xmlxml
POST https://api.bank.com/soap/AccountService HTTP/1.1
Content-Type: text/xml; charset=utf-8
SOAPAction: "getBalance"

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:bank="http://bank.com/api">
  <soap:Body>
    <bank:GetBalanceRequest>
      <bank:AccountId>ACC-001234</bank:AccountId>
      <bank:Currency>RUB</bank:Currency>
    </bank:GetBalanceRequest>
  </soap:Body>
</soap:Envelope>

Ответ:

xmlxml
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:bank="http://bank.com/api">
  <soap:Body>
    <bank:GetBalanceResponse>
      <bank:AccountId>ACC-001234</bank:AccountId>
      <bank:Balance>150000.00</bank:Balance>
      <bank:Currency>RUB</bank:Currency>
      <bank:LastUpdated>2024-01-15T10:30:00Z</bank:LastUpdated>
    </bank:GetBalanceResponse>
  </soap:Body>
</soap:Envelope>

SOAP Fault — ошибка в SOAP

В отличие от REST, SOAP всегда возвращает HTTP 200 OK, даже при ошибке. Информация об ошибке находится в теле ответа:

xmlxml
<soap:Body>
  <soap:Fault>
    <faultcode>soap:Client</faultcode>
    <faultstring>Account not found: ACC-999999</faultstring>
    <detail>
      <errorCode>ACCOUNT_NOT_FOUND</errorCode>
    </detail>
  </soap:Fault>
</soap:Body>

Важно для QA: при тестировании SOAP нельзя ориентироваться только на HTTP-код ответа — всегда нужно парсить XML тела.

Где применяется SOAP

  • Банки и финансовые системы
  • Государственные порталы (Госуслуги, налоговые API)
  • Медицинские системы
  • SAP, 1С, другие Enterprise-системы
  • Любые системы с жёсткими требованиями к контракту

4. JSON — формат данных для REST

JSON (JavaScript Object Notation) — лёгкий текстовый формат обмена данными. Читается людьми, хорошо обрабатывается машинами.

Типы данных в JSON

jsonjson
{
  "string": "Привет, мир",
  "number": 42,
  "decimal": 3.14,
  "boolean": true,
  "null_value": null,
  "array": [1, 2, 3, "текст"],
  "object": {
    "key": "value"
  }
}

Реальный пример JSON-объекта

jsonjson
{
  "id": 42,
  "name": "Алина Иванова",
  "email": "alina@example.com",
  "age": 28,
  "isActive": true,
  "roles": ["user", "moderator"],
  "address": {
    "city": "Москва",
    "street": "Ленина, 10",
    "zipCode": "101000"
  },
  "createdAt": "2024-01-15T10:30:00Z",
  "deletedAt": null
}

Правила JSON

  1. Строки — только в двойных кавычках ("name", не 'name')
  2. Числа — без кавычек: 42, 3.14, -5
  3. Булевые — строчными буквами: true, false
  4. null — строчными буквами: null
  5. Массив — в квадратных скобках: [1, 2, 3]
  6. Объект — в фигурных скобках: {"key": "value"}
  7. Запятая — после каждого элемента, кроме последнего
  8. Нет комментариев — JSON не поддерживает комментарии

JSON vs XML — сравнение

Одни и те же данные в двух форматах:

xmlxml
<!-- XML: 398 символов -->
<?xml version="1.0" encoding="UTF-8"?>
<user>
  <id>42</id>
  <name>Алина Иванова</name>
  <email>alina@example.com</email>
  <roles>
    <role>user</role>
    <role>moderator</role>
  </roles>
</user>
jsonjson
// JSON: 109 символов
{
  "id": 42,
  "name": "Алина Иванова",
  "email": "alina@example.com",
  "roles": ["user", "moderator"]
}
КритерийXMLJSON
ЧитаемостьСредняяВысокая
РазмерБольшеМеньше
Поддержка в браузерахНужна библиотекаВстроена в JavaScript
АтрибутыДаНет
КомментарииДаНет
Схема данныхXSD, DTDJSON Schema
ИспользованиеSOAP, EnterpriseREST, большинство API

5. REST — архитектура современных API

REST (Representational State Transfer — передача состояния представления) — это не протокол, а архитектурный стиль. Набор принципов, которым должен следовать API.

Шесть принципов REST

1. Клиент-серверная архитектура

Клиент и сервер независимы. Клиент не знает, как хранятся данные. Сервер не знает, как данные отображаются.

2. Stateless (без состояния)

Каждый запрос содержит всю необходимую информацию. Сервер не хранит состояние клиента между запросами.

Плохо (stateful):
  Запрос 1: "Я пользователь #42"
  Запрос 2: "Дай мне мои заказы" (сервер помнит, что ты пользователь #42)

Хорошо (stateless):
  Запрос 1: GET /orders  + заголовок Authorization: Bearer token_для_user_42
  Каждый запрос самодостаточен

3. Кэшируемость

Ответы сервера должны явно указывать, можно ли их кэшировать.

4. Единый интерфейс

Все ресурсы идентифицируются через URL. Действия выражаются через HTTP-методы.

5. Многоуровневая система

Клиент не знает, напрямую ли он общается с сервером или через посредников (балансировщик, кэш, CDN).

6. Code on Demand (необязательно)

Сервер может отправлять исполняемый код клиенту (например, JavaScript).

Ресурсы и URL в REST

REST строится вокруг понятия ресурс — это любая сущность данных.

Хорошие RESTful URL (ресурсо-ориентированные):

GET    /users              →  список пользователей
GET    /users/42           →  пользователь #42
POST   /users              →  создать пользователя
PUT    /users/42           →  заменить пользователя #42
PATCH  /users/42           →  обновить поля пользователя #42
DELETE /users/42           →  удалить пользователя #42

GET    /users/42/orders    →  заказы пользователя #42
GET    /users/42/orders/7  →  заказ #7 пользователя #42
Плохие URL (не RESTful):

GET  /getUser?id=42       →  глагол в URL — неправильно
POST /createUser          →  глагол в URL — неправильно
POST /users/42/delete     →  глагол в URL — неправильно
GET  /UsersList           →  camelCase — неправильно, нет единообразия

Полный пример REST API

Сценарий: система управления книгами

# Получить все книги
GET /api/v1/books
→ 200 OK
← [
    {"id": 1, "title": "Тестирование ПО", "author": "Савин"},
    {"id": 2, "title": "Playwright Guide", "author": "Playwright Team"}
  ]

# Получить книгу по ID
GET /api/v1/books/1
→ 200 OK
← {"id": 1, "title": "Тестирование ПО", "author": "Савин", "year": 2022}

# Создать книгу
POST /api/v1/books
Content-Type: application/json
{"title": "REST API Testing", "author": "Smith", "year": 2024}
→ 201 Created
← {"id": 3, "title": "REST API Testing", "author": "Smith", "year": 2024}

# Обновить книгу
PATCH /api/v1/books/3
Content-Type: application/json
{"year": 2025}
→ 200 OK
← {"id": 3, "title": "REST API Testing", "author": "Smith", "year": 2025}

# Удалить книгу
DELETE /api/v1/books/3
→ 204 No Content

6. SOAP vs REST — ключевые отличия

КритерийSOAPREST
ТипПротоколАрхитектурный стиль
Формат данныхТолько XMLJSON, XML, любой
ТранспортHTTP, SMTP, другиеТолько HTTP
КэшированиеСложноВстроено в HTTP
БезопасностьWS-SecurityHTTPS + токены
ОшибкиВсегда 200 + Fault в XMLHTTP-коды (4xx, 5xx)
СложностьВысокаяНизкая
ПроизводительностьНиже (XML тяжелее)Выше (JSON легче)
КонтрактСтрогий WSDLОпциональный OpenAPI
ПрименениеБанки, Enterprise, legacyМобильные, веб, SaaS

Когда SOAP — правильный выбор

  • Жёсткий контракт важнее гибкости
  • Транзакции (ACID) между системами
  • Сложная безопасность (WS-Security)
  • Интеграция с legacy Enterprise-системами

Когда REST — правильный выбор

  • Новые проекты и стартапы
  • Мобильные приложения
  • Публичные API (для сторонних разработчиков)
  • Микросервисная архитектура

7. OpenAPI / Swagger — документация REST API

OpenAPI (раньше называлась Swagger) — стандарт описания REST API в формате YAML или JSON.

yamlyaml
openapi: 3.0.0
info:
  title: Users API
  version: 1.0.0

paths:
  /users/{id}:
    get:
      summary: Получить пользователя по ID
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Пользователь найден
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          description: Пользователь не найден

components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        email:
          type: string
          format: email

Swagger UI генерирует интерактивную документацию из этого файла — прямо в браузере можно выполнять запросы к API.

Что QA делает со Swagger:

  • Изучает список всех эндпоинтов
  • Узнаёт, какие параметры обязательны
  • Понимает структуру ответов
  • Тестирует прямо из браузера
  • Сравнивает реальное поведение с документацией

8. JSON Schema — валидация структуры ответа

JSON Schema описывает ожидаемую структуру JSON-ответа. QA использует её для автоматической проверки ответов API.

jsonjson
{
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "required": ["id", "name", "email"],
  "properties": {
    "id": {
      "type": "integer",
      "minimum": 1
    },
    "name": {
      "type": "string",
      "minLength": 2,
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "format": "email"
    },
    "age": {
      "type": "integer",
      "minimum": 0,
      "maximum": 150
    },
    "isActive": {
      "type": "boolean"
    }
  }
}

В Postman можно написать тест на соответствие схеме:

javascriptjavascript
pm.test("Структура ответа соответствует схеме", function () {
  const schema = {
    type: "object",
    required: ["id", "name", "email"],
    properties: {
      id:    { type: "number" },
      name:  { type: "string" },
      email: { type: "string" }
    }
  };
  pm.response.to.have.jsonSchema(schema);
});

9. Чеклист тестирования REST API

Позитивные сценарии (Happy Path)

  • GET возвращает корректный список с правильной структурой
  • GET по ID возвращает корректный объект
  • POST создаёт объект и возвращает 201 с телом нового объекта
  • PUT полностью заменяет объект
  • PATCH обновляет только переданные поля
  • DELETE удаляет объект и возвращает 204
  • GET после DELETE возвращает 404

Негативные сценарии

  • GET по несуществующему ID → 404
  • POST с обязательным пустым полем → 400/422
  • POST с дублирующимся уникальным полем → 409
  • DELETE чужого ресурса → 403 или 404
  • Запрос без токена авторизации → 401
  • Запрос с просроченным токеном → 401
  • Запрос с некорректным JSON → 400

Граничные значения

  • Максимально длинная строка в поле
  • Пустая строка там, где она недопустима
  • Отрицательные числа, если поле позитивное
  • Дата в неверном формате
  • Очень большие числа (overflow)
  • null в обязательном поле

Структура ответа

  • Все обязательные поля присутствуют
  • Типы данных соответствуют документации
  • Даты в правильном формате (ISO 8601)
  • Числа не преобразованы в строки

Итоги урока

ТемаКлючевые моменты
XMLТеговый формат. Строго, многословно. XPath для навигации
JSONЛёгкий формат. Читаемо, компактно. Встроен в JS
SOAPПротокол. XML. Строгий WSDL. Всегда 200 OK
RESTАрхитектурный стиль. Обычно JSON. HTTP-коды. OpenAPI
WSDLКонтракт SOAP-сервиса (список методов и их параметров)
OpenAPIДокументация REST API (Swagger UI)
JSON SchemaВалидация структуры JSON-ответа

Практические задания

  1. Чтение XML: Найди любой публичный XML-сервис (например, RSS-ленту любого новостного сайта — обычно /rss или /feed). Открой URL в браузере. Разбери структуру: какие теги есть, вложенность, атрибуты.

  2. Чтение JSON: Открой в браузере https://jsonplaceholder.typicode.com/users. Разбери структуру ответа: типы данных каждого поля, вложенные объекты, массивы.

  3. SOAP Fault: В SoapUI создай запрос к любому публичному SOAP-сервису с намеренно неверными данными. Изучи структуру Fault-ответа. Как ты напишешь проверку на этот Fault в тест-кейсе?

  4. REST vs SOAP дизайн: Представь систему интернет-банка. Перечисли 5 операций (просмотр баланса, перевод, история операций и т.д.) и предложи их реализацию в виде: а) REST-эндпоинтов (метод + URL), б) SOAP-операций (название метода). Что будет проще тестировать и почему?

  5. JSON Schema: Напиши JSON Schema для следующего объекта: заказ в интернет-магазине с полями: id, status (pending/processing/delivered/cancelled), items (массив товаров), totalPrice, createdAt. Убедись, что схема описывает типы, обязательные поля и допустимые значения статуса.

  6. Swagger UI: Открой https://petstore.swagger.io. Изучи документацию. Выполни несколько запросов прямо из Swagger UI. Напиши тест-кейс для операции создания питомца (POST /pet): позитивный сценарий и 3 негативных.


Следующий урок: Урок 05 — Тестирование API с Postman и SoapUI. GET vs POST