Идентификация flaky тестов

Flaky тесты — это тесты, которые иногда проходят, а иногда падают без изменений в коде приложения. Они создают ложное ощущение нестабильности системы и снижают доверие к автоматизированному тестированию. В Cypress их выявление и устранение требует системного подхода, включающего анализ поведения тестов, логирования и мониторинга.


Причины возникновения flaky тестов

  1. Асинхронность и тайминги Cypress работает в асинхронной среде, и многие ошибки появляются из-за несинхронизированного ожидания элементов. Например, попытка взаимодействовать с элементом до его полной загрузки приводит к случайным падениям.

  2. Состояние приложения Flaky тесты часто зависят от состояния, оставленного предыдущими тестами. Если тесты не изолированы, данные в базе, cookies или localStorage могут изменять результат.

  3. Сетевые запросы и внешние зависимости Тестирование компонентов, которые зависят от API или внешних сервисов, приводит к нестабильности при медленных или нестабильных ответах. Cypress позволяет подменять запросы через cy.intercept, что уменьшает влияние внешних факторов.

  4. Случайные данные и генерация тестовых данных Использование случайных данных без контроля может приводить к непредсказуемым результатам. Например, случайная генерация email может создавать конфликты в базе данных.

  5. Проблемы с окружением Различия между локальной и CI средой, браузерами или версиями Cypress могут влиять на прохождение тестов. Некоторые тесты корректно работают локально, но падают в CI из-за скорости выполнения или ресурсов сервера.


Методы выявления flaky тестов

  1. Повторное прогонение тестов

    • Используется --retries в Cypress для повторного запуска теста при падении:

      // cypress.config.js
      e2e: {
        retries: {
          runMode: 2,
          openMode: 0
        }
      }
    • Тест, который проходит при повторных попытках, считается потенциально flaky.

  2. Логирование и трассировка

    • Cypress позволяет записывать логи через cy.log и cy.task.
    • Сохранение скриншотов и видео каждой попытки помогает анализировать, в какой момент тест ломается.
  3. Сравнительный анализ результатов

    • Запуск тестов в разных браузерах или на разных средах выявляет зависимость от платформы.
    • Сравнение логов прошлых запусков позволяет определить повторяющиеся ошибки.
  4. Инструменты анализа

    • Использование плагинов для CI, таких как cypress-dashboard, позволяет видеть историю прохождения тестов и выявлять паттерны падений.
    • Метрики стабильности тестов помогают определить, какие тесты требуют изоляции или доработки.

Стратегии уменьшения flaky тестов

  1. Синхронизация с элементами

    • Всегда использовать встроенные ожидания Cypress, например cy.get(selector).should('be.visible') или cy.contains('текст').click().
    • Избегать явных cy.wait(time), заменяя их на ожидание условий.
  2. Изоляция тестов

    • Каждый тест должен работать с чистым состоянием: сброс cookies, localStorage и базы данных.
    • Использование beforeEach и afterEach для подготовки и очистки данных.
  3. Стабилизация сетевых запросов

    • Подменять внешние API через cy.intercept с заранее подготовленными ответами.
    • Для динамических данных использовать фиктивные ответы или мок-серверы.
  4. Контроль тестовых данных

    • Предварительно создавать фиксированные тестовые данные, которые гарантированно существуют.
    • Использовать уникальные идентификаторы при необходимости генерации новых объектов.
  5. Мониторинг и аналитика

    • Постоянно отслеживать flaky тесты на CI и добавлять их в отдельный отчет.
    • Создание метрик стабильности позволяет приоритизировать исправление тестов с высокой вероятностью падения.

Примеры идентификации flaky тестов

Повторный запуск одного и того же теста:

describe('Пример flaky теста', () => {
  it('иногда падает', { retries: 2 }, () => {
    cy.visit('/страница');
    cy.get('.кнопка').click();
    cy.get('.результат').should('contain.text', 'Ожидаемый текст');
  });
});
  • Если тест падает при первой попытке, но проходит при повторной, это указывает на проблемный участок кода или нестабильное состояние приложения.

Логирование проблемного элемента:

cy.get('.результат').then($el => {
  if (!$el.is(':visible')) {
    cy.task('log', 'Элемент не виден');
  }
});
  • Запись таких событий помогает точно определить причину падения.

Метрики и показатели

  1. Процент повторных падений

    • Вычисляется как количество неудачных прогонов перед успешным завершением.
  2. Среднее количество попыток до успеха

    • Помогает оценить стабильность теста.
  3. Частота падений в разных окружениях

    • Выявляет зависимость от браузеров или серверных условий.

Рекомендации по интеграции с CI/CD

  • Включение Cypress Dashboard для хранения истории запусков.
  • Настройка отдельного пайплайна для flaky тестов с детальным логированием.
  • Автоматическая генерация отчетов с указанием тестов, которые часто падают, и их повторных прогонов.

Эти подходы позволяют систематически выявлять, классифицировать и минимизировать влияние flaky тестов на общий процесс автоматизированного тестирования.