Rate limiting API

Rate limiting — ограничение частоты запросов к API или веб-сервису за единицу времени. В контексте тестирования веб-приложений с Puppeteer знание и управление лимитами запросов критично для корректной проверки поведения приложения под нагрузкой, эмуляции реальных условий и предотвращения блокировки со стороны сервера. Puppeteer предоставляет возможности для контроля скорости запросов, их последовательности и обработки ошибок при превышении лимитов.


Настройка запросов и имитация ограничений

Puppeteer позволяет перехватывать сетевые запросы через метод page.setRequestInterception(true). Это ключевой инструмент при тестировании API с лимитами.

const puppeteer = require(&

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.setRequestInterception(true);

  page.on('request', request => {
    // Пример: блокировка ненужных ресурсов
    if (request.resourceType() === 'image') {
      request.abort();
    } else {
      request.continue();
    }
  });

  await page.goto('https://example.com');
  await browser.close();
})();

Ключевые моменты:

  • request.resourceType() позволяет фильтровать типы ресурсов, что снижает нагрузку на тестируемый сервер.
  • Можно внедрять задержки между запросами, чтобы имитировать ограничения по скорости.

Имитация rate limiting через задержки

Для эмуляции лимитов можно использовать функцию sleep или асинхронные задержки между вызовами API:

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function fetchWithRateLimit(page, urls, delay) {
  for (const url of urls) {
    await page.goto(url);
    await sleep(delay); // задержка между запросами
  }
}

Примечания:

  • Задержка помогает проверить корректность обработки сервера при поступлении запросов с ограниченной частотой.
  • Реальные API часто возвращают HTTP-код 429 Too Many Requests. Эту ситуацию необходимо обрабатывать.

Обработка ошибок при превышении лимитов

При работе с API важно отслеживать ответы сервера на превышение лимитов:

page.on('response', async response => {
  if (response.status() === 429) {
    console.warn(`Лимит превышен: ${response.url()}`);
    // Реализация стратегии повторного запроса
  }
});

Стратегии обработки:

  1. Exponential backoff — повторный запрос с экспоненциальной задержкой.
  2. Fixed delay retry — фиксированная пауза перед повторным вызовом.
  3. Abort and log — прекращение теста с фиксацией события.

Параллельные запросы и throttling

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

const urls = ['https://example.com/api/1', 'https://example.com/api/2'];

await Promise.all(
  urls.map((url, index) =>
    sleep(index * 500).then(() => page.goto(url))
  )
);

Особенности:

  • Promise.all позволяет запускать несколько запросов одновременно, но с интервалом между ними.
  • Такая схема помогает тестировать реакцию сервера на одновременные запросы без риска мгновенного блокирования.

Логирование и мониторинг лимитов

Для полноценного тестирования необходимо отслеживать скорость запросов и ответы сервера:

page.on('request', request => {
  console.log(`Запрос: ${request.url()}`);
});

page.on('response', async response => {
  console.log(`Ответ: ${response.url()} - ${response.status()}`);
});

Советы:

  • Ведение детального лога помогает выявить узкие места в API и неправильно настроенные лимиты.
  • Можно сохранять статистику по времени отклика и количеству 429 ошибок для последующего анализа.

Интеграция с API тестированием

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

  • Использовать контроль частоты запросов для избежания блокировки.
  • Проверять обработку ошибок и повторных попыток.
  • Вести детальный лог всех запросов и ответов для последующего анализа.

Практические сценарии

  1. Тестирование формы с ограничением количества запросов на отправку: Эмулировать несколько быстрых попыток отправки и проверить реакцию сервера (ошибка 429 или тайм-аут).

  2. Проверка throttle на API: Перехватывать сетевые запросы, добавлять задержку и фиксировать время отклика.

  3. Стресс-тестирование: Использовать несколько страниц Puppeteer, чтобы имитировать одновременные запросы и убедиться, что сервер корректно обрабатывает превышение лимита.


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