Сравнение значений в Protractor опирается на матчеры фреймворка
Jasmine. Ключевыми для повседневных проверок являются
toBe() и toEqual(). Несмотря на внешнюю
схожесть, они решают принципиально разные задачи и по-разному
интерпретируют «равенство».
toBe() использует оператор строгого равенства
===. Проверка проходит только в том случае, если
сравниваемые значения идентичны на уровне JavaScript-движка.
Для примитивов (number, string,
boolean, null, undefined)
результат обычно интуитивно понятен:
expect(5).toBe(5);
expect('login').toBe('login');
expect(true).toBe(true);
Любое различие в типе или значении приводит к падению теста:
expect(5).toBe('5'); // false
Для ссылочных типов toBe() сравнивает ссылки, а не
содержимое:
const a = { role: 'admin' };
const b = { role: 'admin' };
expect(a).toBe(b); // false
Даже при полном совпадении структуры и значений объекты считаются разными, если они находятся в разных областях памяти.
Единственный случай, когда сравнение проходит:
const user = { id: 1 };
expect(user).toBe(user); // true
NaN никогда не равен самому себе:
expect(NaN).toBe(NaN); // falseФункции сравниваются по ссылке:
const fn = () => {};
expect(fn).toBe(fn); // truetoEqual() —
глубокое структурное сравнениеtoEqual() выполняет рекурсивное сравнение значений. Для
сложных структур анализируется содержимое, а не ссылка.
const actual = { name: 'Alice', age: 30 };
const expected = { name: 'Alice', age: 30 };
expect(actual).toEqual(expected); // true
Порядок свойств не имеет значения:
expect(
{ a: 1, b: 2 }
).toEqual(
{ b: 2, a: 1 }
);
Массивы сравниваются поэлементно и с учётом порядка:
expect([1, 2, 3]).toEqual([1, 2, 3]); // true
expect([1, 2, 3]).toEqual([3, 2, 1]); // false
toEqual() корректно обрабатывает вложенные объекты и
массивы:
expect({
user: {
roles: ['admin', 'editor']
}
}).toEqual({
user: {
roles: ['admin', 'editor']
}
});
Date сравниваются по значению времени:
expect(new Date(2025, 0, 1)).toEqual(new Date(2025, 0, 1));Регулярные выражения сравниваются по шаблону и флагам.
NaN считается равным NaN:
expect(NaN).toEqual(NaN); // trueВ Protractor часто сравниваются значения, полученные из браузера: текст элементов, атрибуты, результаты вычислений в Angular-приложении.
const title = element(by.css('h1')).getText();
expect(title).toBe('Dashboard');
При использовании async/await:
const title = await element(by.css('h1')).getText();
expect(title).toEqual('Dashboard');
Для строк и чисел разницы между toBe() и
toEqual() здесь не будет, но для возвращаемых структур
(например, JSON из browser.executeScript) выбор матчера
становится критичным.
toBe() для объектовexpect(response).toBe({
status: 'ok'
});
Тест всегда будет падать, даже если объект идентичен по содержимому.
Корректный вариант:
expect(response).toEqual({
status: 'ok'
});
toEqual() для примитивовexpect(isLoggedIn).toEqual(true);
Работает корректно, но логически менее точно отражает намерение. Для
строгих логических проверок предпочтительнее toBe().
Выбор между toBe() и toEqual() влияет не
только на результат, но и на смысл теста:
toBe() подчёркивает идентичность и строгостьtoEqual() подчёркивает соответствие структуры и
данныхВ хорошо написанных тестах матчер отражает ожидаемую природу сравнения, а не просто «чтобы тест прошёл».
| Критерий | toBe() | toEqual() |
|---|---|---|
| Основа сравнения | === |
Глубокое сравнение |
| Примитивы | Да | Да |
| Объекты | По ссылке | По структуре |
| Массивы | По ссылке | Поэлементно |
| NaN | Не равен | Равен |
| Назначение | Строгая идентичность | Эквивалентность данных |
Грамотное различение этих матчеров — обязательная основа надёжных e2e-тестов в Protractor и Jasmine.