Создание кастомных репортеров

Playwright предоставляет несколько встроенных репортеров для вывода информации о выполнении тестов, таких как стандартный, JUnit и HTML репортеры. Однако, в некоторых случаях требуется особая логика отчётов или их интеграция с внешними системами, такими как CI/CD пайплайны или мониторинг. Для этого Playwright поддерживает создание кастомных репортеров. Кастомные репортеры позволяют гибко настраивать вывод тестовых результатов, интегрировать тестовые данные с различными сервисами и отображать дополнительные метаданные.

Структура кастомного репортера

Кастомный репортер в Playwright реализуется через интерфейс Reporter. Для этого необходимо создать класс, который будет реализовывать методы, предусмотренные этим интерфейсом.

Ключевыми методами, которые нужно реализовать, являются:

  • onBegin(config, suite) — вызывается в начале выполнения тестов. Здесь можно, например, инициализировать внешние соединения или логирование.
  • onEnd(result) — вызывается по завершению тестов. В данном методе удобно подвести итоги выполнения всех тестов.
  • onTestBegin(test) — вызывается перед каждым тестом.
  • onTestEnd(test, result) — вызывается после выполнения каждого теста, предоставляя его результат.
  • onStepBegin(test, step) — используется для работы с шагами внутри теста.
  • onStepEnd(test, step) — вызывается после завершения каждого шага теста.

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

class MyCustomReporter {
  onBegin(config, suite) {
    console.log('Тестирование начато');
  }

  onEnd(result) {
    console.log(`Тестирование завершено. Количество пройденных тестов: ${result.successful}`);
  }

  onTestBegin(test) {
    console.log(`Тест "${test.title}" начал выполнение`);
  }

  onTestEnd(test, result) {
    if (result.status === 'passed') {
      console.log(`Тест "${test.title}" прошел успешно`);
    } else {
      console.log(`Тест "${test.title}" не прошел`);
    }
  }
}

Интеграция с конфигурацией Playwright

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

Пример добавления кастомного репортера в конфигурацию:

// playwright.config.js
module.exports = {
  reporter: [
    ['./MyCustomReporter', {}],  // Указываем путь к кастомному репортеру
    ['dot'], // Также можно использовать встроенный репортер
  ],
};

Вывод дополнительной информации

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

  • Логи отладки
  • Время выполнения тестов
  • Технические детали шагов, если тесты связаны с сложными процессами

Для этого можно воспользоваться методом onTestEnd, в котором доступна информация о каждом тесте, включая его статус, продолжительность и ошибки. В случае сложных шагов или действий, можно добавить дополнительные записи в вывод через console.log() или интеграции с внешними логирующими сервисами.

Пример вывода дополнительной информации о времени выполнения:

class MyCustomReporter {
  onTestEnd(test, result) {
    const duration = result.duration;
    console.log(`Тест "${test.title}" завершился. Статус: ${result.status}, Время: ${duration}ms`);
  }
}

Использование кастомных репортеров для CI/CD

Часто требуется интеграция кастомного репортера с системами CI/CD для получения уведомлений о статусе тестов, их автоматического отображения в отчётах и последующего анализа. В этом случае можно настроить репортер таким образом, чтобы он отправлял данные о выполнении тестов в стороннюю систему.

Для интеграции с внешними сервисами обычно используются HTTP-запросы или отправка отчетов в файлы, которые затем анализируются системой CI.

Пример отправки отчёта через HTTP:

const axios = require('axios');

class CIReporter {
  onEnd(result) {
    axios.post('https://my-ci-system.com/report', {
      passed: result.successful,
      failed: result.failed,
      skipped: result.skipped,
    })
    .then(() => console.log('Отчет отправлен в CI систему'))
    .catch((err) => console.error('Ошибка отправки отчета:', err));
  }
}

Статистика и метрики

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

Можно, например, собрать статистику по времени выполнения тестов:

class PerformanceReporter {
  constructor() {
    this.testTimes = [];
  }

  onTestEnd(test, result) {
    this.testTimes.push(result.duration);
    console.log(`Тест "${test.title}" занял ${result.duration}ms`);
  }

  onEnd(result) {
    const avgTime = this.testTimes.reduce((a, b) => a + b, 0) / this.testTimes.length;
    console.log(`Среднее время выполнения тестов: ${avgTime}ms`);
  }
}

Отчёты в формате JSON

Часто бывает удобно выводить отчёты в формате JSON для дальнейшего анализа или интеграции с другими инструментами. Кастомный репортер легко может генерировать такие отчёты.

Пример создания отчёта в формате JSON:

const fs = require('fs');

class JSONReporter {
  constructor() {
    this.results = [];
  }

  onTestEnd(test, result) {
    this.results.push({
      title: test.title,
      status: result.status,
      duration: result.duration,
    });
  }

  onEnd() {
    fs.writeFileSync('test-results.json', JSON.stringify(this.results, null, 2));
    console.log('Результаты сохранены в файл test-results.json');
  }
}

Поддержка многопоточности

Playwright поддерживает многозадачность, а значит, тесты могут выполняться параллельно. При создании кастомного репортера важно учитывать, что данные о тестах могут поступать асинхронно. Для корректной работы с многозадачностью необходимо правильно синхронизировать вывод данных и учитывать параллельное выполнение тестов.

Решения включают использование очередей или асинхронных методов для обработки данных по завершении всех тестов.

Пример синхронизации при многозадачности:

class AsyncReporter {
  constructor() {
    this.results = [];
  }

  async onTestEnd(test, result) {
    this.results.push({
      title: test.title,
      status: result.status,
      duration: result.duration,
    });

    if (this.results.length === 10) {
      await this.saveResults();
    }
  }

  async saveResults() {
    await fs.promises.writeFile('async-results.json', JSON.stringify(this.results, null, 2));
    console.log('Результаты сохранены асинхронно');
  }
}

Создание кастомных репортеров в Playwright предоставляет разработчикам мощные инструменты для детализированного контроля над процессом тестирования, вывода информации и интеграции с внешними системами. Важно правильно спроектировать репортер с учётом всех особенностей многозадачности и асинхронного характера работы тестов.