Hooks для setup и teardown

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


Основные типы хуков

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

  1. before Выполняется один раз до всех тестов. Обычно используется для:

    • настройки глобальных переменных,
    • инициализации соединений с базой данных или API,
    • выполнения предварительных шагов для окружения тестирования.
    before: function (capabilities, specs) {
        console.log('Запуск тестового окружения');
    }
  2. after Выполняется один раз после всех тестов. Используется для:

    • закрытия соединений,
    • удаления тестовых данных,
    • генерации отчётов.
    after: function (result, capabilities, specs) {
        console.log('Завершение тестов, результат:', result);
    }
  3. beforeSuite Срабатывает перед запуском каждого тестового сьюита (describe). Позволяет:

    • подготавливать окружение для конкретного сьюита,
    • логировать старт сьюита,
    • выполнять специфические проверки или настройки.
    beforeSuite: function (suite) {
        console.log('Запуск сьюита:', suite.title);
    }
  4. afterSuite Выполняется после завершения сьюита, подходит для:

    • очистки данных, созданных в сьюите,
    • сбора метрик и логов по сьюиту.
    afterSuite: function (suite) {
        console.log('Завершение сьюита:', suite.title);
    }
  5. beforeTest Срабатывает перед каждым тестом (it). Часто используется для:

    • подготовки состояния страницы или приложения,
    • сброса кэшированных данных,
    • логирования начала теста.
    beforeTest: function (test) {
        console.log('Старт теста:', test.title);
    }
  6. afterTest Выполняется после каждого теста, позволяет:

    • делать скриншоты при падении,
    • очищать состояние приложения,
    • логировать результаты теста.
    afterTest: function(test, context, { error, result, duration, passed, retries }) {
        if (!passed) {
            browser.saveScreenshot(`./screenshots/${test.title}.png`);
        }
    }
  7. beforeCommand / afterCommand Срабатывают до и после каждой команды WebDriver. Полезны для:

    • детального логирования действий,
    • измерения времени выполнения команд,
    • отладки нестабильных шагов.
    beforeCommand: function (commandName, args) {
        console.log(`Команда ${commandName} запускается с аргументами: ${args}`);
    },
    afterCommand: function (commandName, args, result, error) {
        if (error) {
            console.error(`Ошибка в команде ${commandName}:`, error);
        }
    }
  8. onPrepare / onComplete Эти хуки выполняются до и после всей сессии тестирования.

    • onPrepare — настройка окружения, сбор зависимостей, запуск сторонних сервисов.
    • onComplete — генерация отчётов, выгрузка логов, очистка ресурсов.

Практическое использование хуков

Организация setup и teardown для стабильных тестов требует аккуратного распределения хуков:

  • Глобальные ресурсы (серверы, базы данных) создаются в onPrepare и завершаются в onComplete.
  • Инициализация состояния браузера — в before или beforeSuite.
  • Сброс состояния между тестами — в beforeTest и afterTest.
  • Логирование и диагностика — через beforeCommand и afterCommand.

Пример комплексного сценария:

exports.config = {
    specs: ['./tests/**/*.js'],
    capabilities: [{ browserName: 'chrome' }],
    before: function () {
        console.log('Инициализация тестового окружения');
    },
    beforeSuite: function (suite) {
        console.log('Подготовка сьюита:', suite.title);
    },
    beforeTest: function (test) {
        console.log('Старт теста:', test.title);
    },
    afterTest: function (test, context, { passed }) {
        if (!passed) {
            browser.saveScreenshot(`./errorShots/${test.title}.png`);
        }
    },
    afterSuite: function (suite) {
        console.log('Очистка после сьюита:', suite.title);
    },
    after: function () {
        console.log('Завершение всех тестов');
    }
};

Советы по использованию хуков

  • Минимизировать зависимости между тестами: каждый тест должен быть изолирован, а хуки обеспечивают корректный state setup и cleanup.
  • Использовать асинхронные функции при необходимости: большинство современных действий WebdriverIO возвращают промисы, поэтому хуки должны поддерживать async/await.
  • Логировать ключевые события: это упрощает диагностику падений и отладку тестов.
  • Скриншоты и сбор метрик в afterTest повышают качество отчётов и делают баг-репорты более информативными.

Асинхронные хуки

WebdriverIO полностью поддерживает асинхронные хуки:

beforeTest: async function (test) {
    await browser.url('/login');
    await $('#username').setValue('testuser');
}

Асинхронные хуки гарантируют, что следующие шаги теста не начнутся, пока не завершится setup, что особенно важно при сложных сценариях с внешними зависимостями.


Hooks в WebdriverIO предоставляют полный контроль над жизненным циклом тестирования, делая возможным создание надёжных, повторяемых и масштабируемых автоматизированных тестов. Их правильная организация позволяет существенно снизить количество нестабильных тестов и автоматизировать рутинные процессы подготовки и очистки окружения.