Шпаргалка: Тестирование GraphQL

Интерактивное руководство по GraphQL для QA инженеров на основе реальных примеров.

Что такое GraphQL и чем он отличается от REST?

GraphQL — это язык запросов для API и среда выполнения для обработки этих запросов. Главное отличие от REST — клиент получает ровно те данные, которые запросил, и ничего лишнего. Всегда используется один endpoint (например, /graphql) и метод POST.

  • REST: "Дай мне всю информацию о пользователе, я сам выберу, что нужно". (Часто приводит к получению избыточных данных).
  • GraphQL: "Дай мне только имя и email пользователя с ID 5". (Точно, гибко и эффективно).

REST vs GraphQL: Наглядное сравнение

Задача: Получить имя персонажа и названия эпизодов, в которых он появлялся.

REST API

// 1. Получаем персонажа
GET /api/character/1

// 2. Получаем эпизод 1
GET /api/episode/1

// 3. Получаем эпизод 2
GET /api/episode/2
... и так далее

GraphQL

// Один запрос для всех данных
POST /graphql

{
  character(id: 1) {
    name
    episode {
      name
    }
  }
}

Основные операции: Query, Mutation, Subscription

Query (Запрос)

Используется для чтения данных. Аналог GET-запроса в REST. Наведите на элементы кода, чтобы узнать больше.

query GetCharacter {
  character(id: 1) {
    name status origin {
      name
    }
  }
}

Mutation (Мутация)

Используется для изменения данных (создание, обновление, удаление). Аналог POST, PUT, DELETE в REST.

mutation UpdateCharacterStatus {
  updateCharacter(input: { id: 1, status: "Dead" }) {
    # Возвращаем обновленные данные id status
  }
}

Subscription (Подписка)

Позволяет получать обновления данных в реальном времени через WebSockets. Клиент подписывается на событие и получает данные каждый раз, когда оно происходит на сервере.

Инструменты и Схема

Схема (Schema)

Это "контракт" между клиентом и сервером. В схеме строго описаны все доступные типы данных, запросы и мутации. Она — единственный источник правды о возможностях API.

Интроспекция (Introspection)

Это механизм, позволяющий "спросить" у GraphQL-сервера о его собственной схеме. Именно благодаря интроспекции инструменты вроде Postman могут автоматически строить документацию и давать подсказки при написании запросов.

Работа с GraphQL в Postman

Postman — один из ключевых инструментов для тестирования GraphQL. Он позволяет не только отправлять запросы, но и работать со схемой, переменными и автодополнением.

POST https://rickandmortyapi.com/graphql
Body Tests Headers
GraphQL
query GetCharacterById($charId: ID!) {
  character(id: $charId) {
    name
  }
}
{
  "charId": 1
}
// Пример теста для GraphQL
pm.test("Response has data for character", function () {
    const responseJson = pm.response.json();
    pm.expect(responseJson.data.character).to.not.be.null;
    pm.expect(responseJson.data.character.name).to.eql("Rick Sanchez");
});
// GraphQL всегда использует Content-Type application/json
Content-Type: application/json
Accept: */*
... (другие заголовки)

Стратегии тестирования GraphQL

Тестирование GraphQL имеет свою специфику по сравнению с REST. Вот ключевые моменты, на которые стоит обратить внимание.

Позитивные сценарии

  • Проверка запроса с минимальным и максимальным количеством полей.
  • Тестирование запросов с разными валидными аргументами (фильтрация, пагинация).
  • Проверка вложенных запросов (когда один объект ссылается на другой).
  • Тестирование мутаций на создание, обновление и удаление данных.

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

  • Запрос несуществующего поля (должна быть ошибка "Cannot query field...").
  • Передача неверного типа данных в аргумент (например, строка вместо числа).
  • Попытка выполнить мутацию без необходимых прав доступа (проверка авторизации).
  • Отправка синтаксически неверного запроса.

Специфические проверки

  • Проверка схемы: Убедитесь, что обязательные поля помечены как non-nullable (!), и сервер действительно не позволяет создавать/обновлять сущности без них.
  • Глубина запросов: Попробуйте отправить слишком глубокий запрос (объект в объекте в объекте...), чтобы проверить, есть ли на сервере защита от таких ресурсоемких операций.

Практический пример: собираем запрос

Давайте соберем запрос для получения информации о Рике Санчезе (id: 1) из "Рика и Морти". Отметьте галочками поля, которые вы хотите получить.

Доступные поля для `character`

Ваш запрос:

Симулированный ответ: