before() и after() глобальные хуки

В Protractor, как и в других фреймворках на основе Jasmine или Mocha, глобальные хуки before() и after() используются для выполнения действий до начала всех тестов и после их завершения. Эти хуки позволяют настроить окружение тестирования и корректно завершать работу с ресурсами, обеспечивая чистоту и предсказуемость тестового прогонa.


before()

Хук before() выполняется один раз перед всеми тестами в спецификации. Его основная задача — подготовка состояния, необходимого для тестов. Например, это может быть:

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

Пример использования before() в Protractor:

describe('Тестирование авторизации', function() {

  before(async function() {
    // Настройка браузера перед всеми тестами
    await browser.waitForAngularEnabled(false);
    await browser.get('https://example.com/login');
  });

  it('должен показать форму логина', async function() {
    const loginForm = element(by.css('.login-form'));
    expect(await loginForm.isPresent()).toBe(true);
  });

});

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

  • before() выполняется только один раз на уровне describe(), в котором он объявлен.
  • Можно использовать асинхронные функции (async/await) для работы с промисами, что особенно важно в Protractor из-за асинхронной природы работы с браузером.
  • Все ошибки в before() приводят к отмене выполнения тестов, поскольку подготовка среды не завершилась успешно.

after()

Хук after() выполняется один раз после всех тестов в спецификации. Он служит для очистки и завершения работы:

  • закрытие браузера или вкладки;
  • очистка данных, созданных в процессе тестов;
  • логирование или сохранение отчетов о тестировании.

Пример использования after():

describe('Тестирование авторизации', function() {

  before(async function() {
    await browser.get('https://example.com/login');
  });

  it('должен показать форму логина', async function() {
    const loginForm = element(by.css('.login-form'));
    expect(await loginForm.isPresent()).toBe(true);
  });

  after(async function() {
    // Очистка после всех тестов
    await browser.manage().deleteAllCookies();
  });

});

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

  • after() выполняется один раз, даже если некоторые тесты завершились с ошибкой.
  • Позволяет поддерживать чистое состояние между запусками тестов, что предотвращает влияние тестов друг на друга.
  • Можно использовать асинхронные операции для завершения работы с браузером и внешними ресурсами.

Отличие от beforeEach() и afterEach()

  • beforeEach() и afterEach() выполняются перед и после каждого теста, соответственно.
  • before() и after() выполняются один раз на весь блок describe().
  • Использование глобальных хуков экономит время при подготовке и завершении ресурсов, если эти операции не требуют повторения перед каждым тестом.

Практические рекомендации

  1. Инициализация браузера и страниц: Использовать before() для открытия стартовой страницы приложения или выполнения авторизации один раз перед всеми тестами.
  2. Очистка ресурсов: after() идеально подходит для удаления сессий, cookies или временных данных.
  3. Асинхронные операции: Всегда использовать async/await для работы с браузером, так как большинство методов Protractor возвращают промисы.
  4. Изоляция тестов: Не помещать специфические проверки в before() или after(). Эти хуки предназначены только для подготовки и очистки среды.
  5. Обработка ошибок: Любая ошибка в before() прерывает выполнение тестов, поэтому важно логировать и корректно обрабатывать исключения.

Совместное использование

Хуки before() и after() можно комбинировать с beforeEach() и afterEach() для создания иерархической структуры подготовки и очистки. Например:

describe('Работа с пользователями', function() {

  before(async function() {
    await browser.get('https://example.com');
  });

  beforeEach(async function() {
    await element(by.css('#new-user')).click();
  });

  it('должен создать нового пользователя', async function() {
    const userForm = element(by.css('.user-form'));
    expect(await userForm.isPresent()).toBe(true);
  });

  afterEach(async function() {
    await element(by.css('#cancel')).click();
  });

  after(async function() {
    await browser.manage().deleteAllCookies();
  });

});

В этом примере before() открывает стартовую страницу один раз, а beforeEach() выполняет действия перед каждым тестом, обеспечивая чистое состояние формы. Аналогично, afterEach() и after() обеспечивают последовательное очищение данных.