expect() синтаксис

В Protractor проверка поведения приложения строится вокруг утверждений (assertions). Центральным элементом этих утверждений является функция expect(), заимствованная из Jasmine — фреймворка, который по умолчанию используется в Protractor. expect() описывает ожидаемое состояние системы и сравнивает его с фактическим результатом выполнения теста.

Синтаксически expect() представляет собой связку:

expect(фактическое_значение).matcher(ожидаемое_значение);

Эта конструкция читается декларативно и позволяет описывать тесты в терминах поведения, а не реализации.


Базовый синтаксис expect()

Минимальная форма утверждения:

expect(value).toBe(expected);

Где:

  • value — фактическое значение, полученное из приложения
  • expected — ожидаемое значение
  • toBe — matcher (сопоставитель)

В контексте Protractor value часто является результатом асинхронного вызова WebDriver:

expect(element(by.id('title')).getText()).toBe('Dashboard');

Protractor автоматически обрабатывает Promise (в версиях до 6), позволяя писать проверки без явного then().


Matcher’ы и их семантика

Matcher определяет тип сравнения. Использование корректного matcher’а критично для точности теста.

toBe() — строгое сравнение

expect(count).toBe(5);

Использует строгое сравнение (===). Подходит для примитивов и случаев, где важна точная идентичность.


toEqual() — глубокое сравнение

expect(user).toEqual({ id: 1, name: 'Admin' });

Проверяет эквивалентность структур, а не ссылок. Применяется для объектов и массивов.


toContain() — частичное совпадение

expect(message).toContain('успешно');

Работает со строками и массивами. Часто используется при проверке уведомлений и логов.


toMatch() — проверка по регулярному выражению

expect(url).toMatch(/\/login$/);

Полезен при проверке динамических строк: URL, идентификаторов, сообщений.


Отрицательные проверки с not

Любой matcher может быть инвертирован через not:

expect(errorMessage.isPresent()).not.toBe(true);

Это позволяет явно зафиксировать отсутствие элемента, значения или состояния.


Проверка булевых значений

Для читаемости используются специализированные matcher’ы:

expect(isVisible).toBe(true);
expect(isEnabled).toBe(false);

Также допустимы формы:

expect(isVisible).toBeTruthy();
expect(isHidden).toBeFalsy();

toBeTruthy() и toBeFalsy() проверяют приведение значения к boolean, а не строгое равенство.


Проверки элементов страницы

Protractor тесно интегрирован с DOM, поэтому expect() часто применяется к элементам:

const button = element(by.css('.submit'));

expect(button.isDisplayed()).toBe(true);
expect(button.isEnabled()).toBe(false);

Проверка наличия элемента:

expect(element(by.id('loader')).isPresent()).toBe(false);

Важно различать:

  • isPresent() — существует ли элемент в DOM
  • isDisplayed() — видим ли элемент пользователю

Проверка коллекций элементов

При работе с element.all() результатом является ElementArrayFinder:

const rows = element.all(by.css('.table-row'));

expect(rows.count()).toBe(10);

Проверка содержимого коллекции:

expect(rows.get(0).getText()).toContain('Admin');

Асинхронность и expect()

В классическом Protractor управление асинхронностью осуществляется через Control Flow. Поэтому expect() может принимать Promise:

expect(browser.getTitle()).toBe('Main page');

В более современных конфигурациях с async/await:

const title = await browser.getTitle();
expect(title).toBe('Main page');

Использование async/await делает поведение expect() более прозрачным и устраняет скрытую магию.


Проверки ошибок и исключений

Для проверки выбрасываемых ошибок используется форма с функцией:

expect(() => {
    throw new Error('Ошибка');
}).toThrowError('Ошибка');

В e2e-тестах применяется реже, но полезна при тестировании клиентской логики.


Кастомные matcher’ы

Jasmine позволяет расширять expect() собственными matcher’ами:

beforeEach(() => {
    jasmine.addMatchers({
        toBeEven: () => ({
            compare(actual) {
                return {
                    pass: actual % 2 === 0
                };
            }
        })
    });
});

Использование:

expect(4).toBeEven();

Кастомные matcher’ы повышают выразительность тестов и снижают дублирование логики.


Диагностика падений expect()

При несоответствии ожидания Jasmine выводит:

  • фактическое значение
  • ожидаемое значение
  • стек вызовов

Пример сообщения:

Expected 'Login' to be 'Dashboard'

Чем точнее сформулировано ожидание, тем быстрее локализуется дефект.


Практика построения читаемых утверждений

Хорошая проверка:

  • описывает одно ожидание
  • не содержит сложной логики
  • использует подходящий matcher

Плохо читаемый пример:

expect(a && b && c).toBe(true);

Предпочтительный вариант:

expect(a).toBe(true);
expect(b).toBe(true);
expect(c).toBe(true);

expect() как спецификация поведения

В тестах Protractor expect() выполняет роль спецификации: он формализует, каким должно быть поведение интерфейса в конкретный момент времени. Через корректный выбор matcher’ов, точные проверки состояний и аккуратную работу с асинхронностью формируется тестовый код, который одновременно является документацией поведения системы.