Ответ
В моей практике написание тестов на интеграцию с внешними сервисами — это совместная ответственность разработчиков и QA-автоматизаторов, но с четким разделением.
1. Разработчики пишут интеграционные тесты на уровне кода. Цель — проверить корректность взаимодействия нашего приложения с API внешнего сервиса (формат запроса/ответа, обработка ошибок). Мы используем моки и стабы для изоляции тестов от реального сервиса.
Пример на PHP с PHPUnit и Mockery:
// Тест для сервиса, работающего с платежным шлюзом
public function testPaymentServiceHandlesApiError(): void
{
// 1. Создаем мок HTTP-клиента (например, Guzzle)
$httpClientMock = Mockery::mock(Client::class);
// 2. Настраиваем его на возврат ошибки 500
$httpClientMock->shouldReceive('request')
->once()
->andThrow(new RequestException('Server Error', new Request('POST', 'test')));
// 3. Инжектим мок в наш сервис
$paymentService = new PaymentService($httpClientMock);
// 4. Проверяем, что сервис корректно обрабатывает исключение
$this->expectException(PaymentGatewayException::class);
$paymentService->charge(100, 'token_123');
}
2. QA-автоматизаторы пишут E2E-тесты. Цель — проверить полный пользовательский сценарий, который затрагивает внешний сервис. Для этого они используют тестовые (sandbox) окружения внешних API и инструменты вроде Selenium, Cypress или Codeception.
Важное правило: Никогда не пишем интеграционные тесты, которые делают вызовы на продакшен-сервисы. Всегда используем staging-окружение, sandbox-ключи или, как в примере выше, полное мокирование.