Обработка исключений в тестах

В e2e-тестировании на Protractor исключения возникают регулярно: элементы не находятся, ожидания истекают, Angular не стабилизируется, браузер теряет сессию. Без осознанной обработки таких ситуаций тесты становятся нестабильными, а отчёты — малоинформативными. Грамотно выстроенная система обработки исключений позволяет отличать реальные дефекты от инфраструктурных сбоев, управлять поведением тестов и повышать доверие к результатам прогонов.


Типы исключений в Protractor

Исключения WebDriver (WebDriverJS) Возникают на уровне Selenium:

  • NoSuchElementError
  • TimeoutError
  • StaleElementReferenceError
  • ElementNotInteractableError

Исключения Protractor Связаны с Angular-спецификой:

  • ошибки синхронизации Angular
  • проблемы с waitForAngular
  • сбои в browser.wait

Логические ошибки теста Возникают в пользовательском коде:

  • некорректные ожидания
  • ошибки асинхронности
  • ошибки в кастомных хелперах

Асинхронная природа исключений

Protractor работает поверх Promise API. Исключения не выбрасываются синхронно, а передаются через цепочки промисов. Это принципиально влияет на способы перехвата ошибок.

Неверный подход:

try {
  element(by.id('save')).click();
} catch (e) {
  // не сработает
}

Корректная обработка:

element(by.id('save')).click().catch(err => {
  // обработка ошибки
});

При использовании async/await обработка становится более читаемой:

try {
  await element(by.id('save')).click();
} catch (err) {
  // обработка ошибки
}

Обработка исключений на уровне теста

Перехват ошибок внутри it

Позволяет:

  • логировать дополнительные данные
  • делать скриншоты
  • выполнять альтернативные сценарии

Пример:

it('должен сохранить форму', async () => {
  try {
    await saveForm();
    await expectSuccessMessage();
  } catch (err) {
    await browser.takeScreenshot();
    throw err;
  }
});

Ключевой момент — повторное выбрасывание исключения, иначе тест будет помечен как успешный.


Глобальная обработка исключений

Использование process.on

Позволяет перехватывать необработанные ошибки:

process.on('unhandledRejection', reason => {
  console.error('Unhandled Promise:', reason);
});

Применяется для:

  • централизованного логирования
  • диагностики нестабильных падений
  • интеграции с системами отчётности

Обработка ошибок ожиданий (browser.wait)

Ожидания — один из самых частых источников исключений.

Пример с кастомным сообщением:

await browser.wait(
  EC.visibilityOf(element(by.css('.alert'))),
  5000,
  'Сообщение не появилось'
);

Преимущества:

  • понятные отчёты
  • быстрая диагностика причин падения
  • отсутствие «немых» таймаутов

Управление ожидаемыми исключениями

Иногда падение — корректное поведение системы. В таких случаях исключение должно быть частью сценария.

Пример проверки отсутствия элемента:

const isPresent = await element(by.id('modal')).isPresent();
expect(isPresent).toBe(false);

Альтернативный вариант с перехватом:

try {
  await element(by.id('modal')).getText();
  fail('Модальное окно не должно существовать');
} catch (err) {
  expect(err.name).toBe('NoSuchElementError');
}

Исключения и хуки (beforeEach, afterEach)

Ошибки в хуках особенно критичны — они могут прервать целый набор тестов.

afterEach и гарантированное выполнение

Для операций очистки:

afterEach(async () => {
  try {
    await logout();
  } catch (err) {
    console.warn('Ошибка при выходе:', err);
  }
});

Здесь исключение намеренно не пробрасывается, чтобы не маскировать основную причину падения теста.


Интеграция обработки исключений с отчётами

Обработка исключений часто дополняется:

  • созданием скриншотов
  • сохранением HTML-снапшотов
  • логированием состояния браузера

Пример:

catch (err) {
  const screenshot = await browser.takeScreenshot();
  saveScreenshot(screenshot);
  throw err;
}

Это особенно важно при использовании Allure, ReportPortal или собственных репортинговых решений.


Особенности Angular-синхронизации и исключения

Ошибки Angular часто выглядят как таймауты ожидания стабильности.

Управление:

browser.waitForAngularEnabled(false);

Применяется для:

  • гибридных приложений
  • страниц без Angular
  • внешних редиректов

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


Стратегии повышения устойчивости тестов

Минимизация перехвата Исключения обрабатываются только там, где это оправдано логикой сценария.

Явные ожидания вместо неявных Чёткие условия уменьшают количество таймаутов.

Осмысленные сообщения об ошибках Каждое выброшенное исключение должно объяснять причину сбоя.

Единый подход к логированию Все исключения обрабатываются по одинаковым правилам.


Частые ошибки при работе с исключениями

  • подавление ошибок без повторного выбрасывания
  • попытки ловить асинхронные ошибки синхронным try/catch
  • использование browser.sleep для обхода исключений
  • игнорирование ошибок в хуках
  • отсутствие контекста в сообщениях об ошибках

Результат корректной обработки исключений

Грамотно выстроенная обработка исключений в Protractor:

  • делает тесты предсказуемыми
  • упрощает анализ падений
  • снижает флейковость
  • повышает ценность автоматизации как инструмента контроля качества

Исключения перестают быть источником хаоса и становятся управляемым механизмом диагностики и контроля поведения системы.