Что такое Listeners в TestNG и для чего они используются?

Ответ

TestNG Listeners — это механизм, основанный на интерфейсах, который позволяет перехватывать и обрабатывать различные события жизненного цикла выполнения тестов. С их помощью можно встраивать пользовательскую логику на ключевых этапах.

Основные встроенные интерфейсы-слушатели:

  • ITestListener — обрабатывает события на уровне тестовых методов (@Test).
  • ISuiteListener — обрабатывает события на уровне сьютов (<suite> в XML).
  • IReporter — позволяет генерировать кастомные отчёты на основе результатов прогона.
  • IAnnotationTransformer — позволяет динамически изменять аннотации тестов.

Типичные сценарии использования Listeners:

  1. Логирование: Запись детальной информации о начале, завершении, успехе или падении каждого теста.
  2. Создание скриншотов: Автоматическое снятие скриншота при падении теста для упрощения отладки.
  3. Расширенная отчётность: Отправка результатов в внешние системы (Slack, email) или формирование HTML-отчёта особого формата.
  4. Управление состоянием: Инициализация и очистка ресурсов (БД, соединения) перед набором тестов или после.

Практический пример: ITestListener для логирования и скриншотов:

import org.testng.ITestListener;
import org.testng.ITestResult;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;

public class CustomTestListener implements ITestListener {

    @Override
    public void onTestStart(ITestResult result) {
        System.out.println("Запуск теста: " + result.getName());
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        System.out.println("Тест УСПЕШЕН: " + result.getName());
    }

    @Override
    public void onTestFailure(ITestResult result) {
        System.out.println("Тест ПРОВАЛЕН: " + result.getName());
        // Делаем скриншот, если тест использует WebDriver
        Object webDriver = result.getTestContext().getAttribute("webDriver");
        if (webDriver instanceof TakesScreenshot) {
            File screenshot = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
            try {
                FileUtils.copyFile(screenshot, new File("screenshots/" + result.getName() + ".png"));
            } catch (Exception e) { /* обработка ошибки */ }
        }
    }
}

Подключение Listener-а:

// Способ 1: Аннотация в тестовом классе
@Listeners(CustomTestListener.class)
public class LoginTests { ... }

// Способ 2: Указание в файле testng.xml (глобально для всех тестов)
<suite>
    <listeners>
        <listener class-name="com.example.CustomTestListener" />
    </listeners>
    <test> ... </test>
</suite>

Listeners — мощный инструмент для расширения стандартных возможностей TestNG и интеграции фреймворка в процесс CI/CD.

Ответ 18+ 🔞

Да ты посмотри, какие штуки бывают! TestNG Listeners — это, блядь, как такие шпионские интерфейсы, которые подслушивают, что твои тесты творят, и позволяют влезть в их святая святых. Всё основано на интерфейсах, ёпта! Можно ловить события и впендюривать свою логику в самые ответственные моменты.

Основные стукачи, которые идут в комплекте:

  • ITestListener — этот, сука, следит за каждым тестовым методом (за теми, что с @Test). Родился, жил, сдох — всё в протокол.
  • ISuiteListener — а этот пасёт целые сьюты (это те самые <suite> в XML). Повыше рангом, блядь.
  • IReporter — о, а этот художник! Может из результатов нарисовать кастомный отчёт, какой душа пожелает.
  • IAnnotationTransformer — хитрая жопа! Позволяет на лету, блядь, подменять аннотации у тестов. Волшебник, ёпта.

И где это, блядь, применить-то?

  1. Логирование: Чтобы не гадать, что там тест делал. Писать в лог: начался, кончился, обосрался или нет.
  2. Скриншоты при падении: Вот тест пизданулся — хвать, и скриншот ему в морду! Чтобы не рыться в потрохах, а сразу видеть, где срач.
  3. Отчёты нестандартные: Шлёшь результаты куда подальше — в слак, на почту. Или делаешь отчёт такой красивый, что дизайнеры плачут.
  4. Управление бардаком: Перед всеми тестами базу поднять, а после — похоронить. Чтобы ресурсы не висели, как сопли.

Смотри, как это выглядит вживую. Вот ITestListener для логирования и скриншотов:

import org.testng.ITestListener;
import org.testng.ITestResult;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;

public class CustomTestListener implements ITestListener {

    @Override
    public void onTestStart(ITestResult result) {
        System.out.println("Запуск теста: " + result.getName());
    }

    @Override
    public void onTestSuccess(ITestResult result) {
        System.out.println("Тест УСПЕШЕН: " + result.getName());
    }

    @Override
    public void onTestFailure(ITestResult result) {
        System.out.println("Тест ПРОВАЛЕН: " + result.getName());
        // Делаем скриншот, если тест использует WebDriver
        Object webDriver = result.getTestContext().getAttribute("webDriver");
        if (webDriver instanceof TakesScreenshot) {
            File screenshot = ((TakesScreenshot) webDriver).getScreenshotAs(OutputType.FILE);
            try {
                FileUtils.copyFile(screenshot, new File("screenshots/" + result.getName() + ".png"));
            } catch (Exception e) { /* обработка ошибки */ }
        }
    }
}

А вот как этого шпиона к делу приставить:

// Способ 1: Пришить аннотацией прямо к тестовому классу
@Listeners(CustomTestListener.class)
public class LoginTests { ... }

// Способ 2: Прописать в священном файле testng.xml (чтоб на всех действовало, блядь)
<suite>
    <listeners>
        <listener class-name="com.example.CustomTestListener" />
    </listeners>
    <test> ... </test>
</suite>

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