Опишите ваш опыт интеграционного тестирования на одном из проектов.

Ответ

На предыдущем проекте (e-commerce платформа на микросервисах) отвечал за автоматизацию интеграционного тестирования API и взаимодействия с внешними системами.

Решаемые задачи и стек:

  • Тестирование REST API микросервисов: Полный цикл CRUD-операций для ключевых доменов (заказы, платежи, каталог) с использованием RestAssured (Java) и TestNG. Валидация статус-кодов, тел ответов, заголовков и схем JSON.
  • Интеграция с внешним платежным шлюзом: Использовал WireMock для мокирования ответов шлюза (успех, ошибка, таймаут), что позволило тестировать наши сценарии в изоляции и покрыть негативные кейсы.
  • Работа в CI/CD: Тесты были интегрированы в Jenkins пайплайн и запускались на каждом мерж-реквесте в dev-окружении. Отчеты публиковались в Allure, где была видна детальная информация по каждому шагу и интеграционной точке.

Пример теста создания заказа с проверкой интеграции:

@Test
public void createOrder_ShouldDeductInventoryAndCreatePaymentRecord() {
    // 1. Подготовка: резервируем товар на складе через API инвентаризации
    reserveItem("item_123", 2);

    // 2. Действие: создаем заказ
    OrderRequest orderRequest = new OrderRequest("user_456", "item_123", 2);
    Response orderResponse = given()
            .spec(apiSpec)
            .body(orderRequest)
            .post("/api/orders");

    // 3. Проверка: заказ создан
    assertEquals(201, orderResponse.getStatusCode());
    String orderId = orderResponse.jsonPath().getString("id");

    // 4. Проверка интеграции: статус платежа обновлен
    Response paymentResponse = given(apiSpec).get("/api/payments/order/" + orderId);
    assertEquals("PROCESSING", paymentResponse.jsonPath().getString("status"));

    // 5. Проверка интеграции: остаток на складе уменьшился
    Response stockResponse = given(apiSpec).get("/api/inventory/item_123");
    assertTrue(stockResponse.jsonPath().getInt("quantity") < INITIAL_STOCK);
}

Дополнительно проводил нагрузочное тестирование критичных интеграционных эндпоинтов (например, POST /orders) с помощью JMeter, чтобы оценить устойчивость системы к пиковым нагрузкам.

Ответ 18+ 🔞

Э, слушай, вот история моей жизни на том прошлом проекте, где мы этот интернет-магазин на микросервисах пилили. Отвечал я там за такую весёлую хуйню — за то, чтобы все эти сервисы между собой не просто так общались, а делали это правильно, без косяков. Короче, за автоматизацию интеграционного тестирования ихних API и всех этих внешних шлюзов.

Чем конкретно мозг выносил и на чём:

  • Тестирование REST API этих самых микросервисов: Полный цикл — создал, прочитал, обновил, удалил. Всё, что касается заказов, платежей и каталога. Делал это на RestAssured (Java) и TestNG. Проверял, чтобы статус-коды были те, что надо, ответы не левые, заголовки на месте и схемы JSON не ебнулись.
  • Интеграция с внешним платежным шлюзом: А вот это, блядь, отдельная песня. Чтобы не зависеть от реальной конторы, которая может в любой момент сказать «иди нахуй» или просто лежать, использовал WireMock. Я ему — «сделай вид, что ты платёжка и ответь успехом», а он — «окей». Или «ответь ошибкой». Или «вообще молчи, как сука, три минуты». Это позволило оттестировать наши сценарии в изоляции и покрыть все эти ебнутые негативные кейсы, когда всё идёт по пизде.
  • Встройка в CI/CD: Чтобы это всё не просто так на моей машине крутилось, запилил запуск в Jenkins пайплайн. На каждый мерж-реквест в dev-окружении эта банда тестов поднималась и начинала всё ебашить. А потом отчёты летели в Allure, где можно было разложить по полочкам, на каком именно шаге и с какой интеграционной точкой случился пиздец.

Вот, смотри, как примерно выглядел один из тестов на создание заказа, где надо было проверить, что всё между сервисами сцепилось:

@Test
public void createOrder_ShouldDeductInventoryAndCreatePaymentRecord() {
    // 1. Подготовка: резервируем товар на складе через API инвентаризации
    reserveItem("item_123", 2);

    // 2. Действие: создаем заказ
    OrderRequest orderRequest = new OrderRequest("user_456", "item_123", 2);
    Response orderResponse = given()
            .spec(apiSpec)
            .body(orderRequest)
            .post("/api/orders");

    // 3. Проверка: заказ создан
    assertEquals(201, orderResponse.getStatusCode());
    String orderId = orderResponse.jsonPath().getString("id");

    // 4. Проверка интеграции: статус платежа обновлен
    Response paymentResponse = given(apiSpec).get("/api/payments/order/" + orderId);
    assertEquals("PROCESSING", paymentResponse.jsonPath().getString("status"));

    // 5. Проверка интеграции: остаток на складе уменьшился
    Response stockResponse = given(apiSpec).get("/api/inventory/item_123");
    assertTrue(stockResponse.jsonPath().getInt("quantity") < INITIAL_STOCK);
}

А ещё, представляешь, я этим самым критичным эндпоинтам, вроде POST /orders, устраивал ёбаный стресс через JMeter. Надо же было понять, выдержит ли система, когда на неё налетит овердохуища народу в час пик, или она сольётся, как хитрая жопа, на первом же тысячном запросе.