Что такое контрактное тестирование и какой у вас опыт с ним?

«Что такое контрактное тестирование и какой у вас опыт с ним?» — вопрос из категории API тестирование, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Контрактное тестирование — это метод проверки взаимодействия между двумя независимыми системами (например, микросервисами) на соответствие заранее определённому «контракту». Контракт описывает ожидаемые форматы запросов и ответов (схемы данных, статус-коды, заголовки).

Мой опыт включает:

  • Использование Pact для тестирования взаимодействия между consumer (клиент) и provider (сервис).
  • Написание тестов на стороне consumer для генерации контракта (pact-файла).
  • Верификацию контракта на стороне provider для гарантии обратной совместимости.
  • Интеграцию проверки контрактов в CI/CD пайплайн для раннего обнаружения breaking changes.

Пример контрактного теста на JavaScript (Pact):

const { Pact } = require('@pact-foundation/pact');

describe('User Service API Contract', () => {
  const provider = new Pact({
    consumer: 'UserFrontend',
    provider: 'UserService',
    port: 1234
  });

  before(() => provider.setup());
  after(() => provider.finalize());

  it('должен возвращать пользователя по ID', async () => {
    // 1. Определяем ожидаемое взаимодействие (контракт)
    await provider.addInteraction({
      state: 'user with id 1 exists',
      uponReceiving: 'a request to get user by id',
      withRequest: {
        method: 'GET',
        path: '/api/users/1'
      },
      willRespondWith: {
        status: 200,
        headers: { 'Content-Type': 'application/json' },
        body: { id: 1, name: 'John Doe' }
      }
    });
    // 2. Выполняем реальный запрос consumer к mock-провайдеру Pact
    // 3. Pact сверяет запрос/ответ с контрактом и генерирует pact-файл
  });
});

Ключевые преимущества:

  • Раннее обнаружение проблем: Breaking changes выявляются до деплоя в прод.
  • Независимость команд: Consumer и provider могут разрабатываться и тестироваться независимо.
  • Надёжность интеграций: Гарантия, что сервисы понимают данные друг друга.