it() тестовые случаи

В Protractor каждый тестовый сценарий оформляется с помощью функции it(). Она описывает одну отдельную проверку или действие, которое должно выполняться в браузере. Общий синтаксис выглядит следующим образом:

it('описание теста', function() {
    // тело теста
});
  • Описание теста ('описание теста') должно быть информативным и кратким, чтобы при запуске тестов в отчётах было легко понять, что проверяется.
  • Функция (function() { ... }) содержит последовательность действий и проверок. Она может быть синхронной или асинхронной.

Protractor построен на основе Jasmine, поэтому it() тесно интегрирован с её функционалом.


Асинхронные тесты и использование async/await

В современных версиях Protractor для работы с асинхронными операциями рекомендуется использовать async/await. Это делает код читаемым и последовательным. Пример:

it('должен открыть главную страницу и проверить заголовок', async function() {
    await browser.get('https://example.com');
    const title = await browser.getTitle();
    expect(title).toEqual('Example Domain');
});

Ключевые моменты:

  • Любые операции с браузером, элементами страницы или ожидания должны выполняться с await.
  • Функция в it() обязательно должна быть объявлена как async, иначе await вызовет ошибку.
  • Асинхронность обеспечивает корректное выполнение шагов теста без коллизий и гонок данных.

Вложенные it() и организация тестов

В Protractor не рекомендуется вкладывать один it() в другой. Каждый it() должен быть независимым тестовым случаем. Для группировки используются блоки describe().

Пример правильной организации:

describe('Тесты главной страницы', function() {
    it('должен открыть страницу и проверить заголовок', async function() {
        await browser.get('https://example.com');
        expect(await browser.getTitle()).toEqual('Example Domain');
    });

    it('должен содержать ссылку Learn More', async function() {
        const link = element(by.css('a'));
        expect(await link.getText()).toContain('More');
    });
});

Каждый it() не зависит от других тестов, что позволяет запускать их параллельно и получать точные отчёты о каждом случае.


Использование expect() внутри it()

Основная цель it() — выполнение проверок состояния приложения. Проверки выполняются через Jasmine-методы, например:

  • expect(actual).toEqual(expected) — сравнение на равенство.
  • expect(actual).toContain(substring) — проверка наличия подстроки.
  • expect(actual).toBeTruthy() / expect(actual).toBeFalsy() — проверка на истинность/ложность.

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

it('должен проверить форму входа', async function() {
    await browser.get('https://example.com/login');
    const username = element(by.id('username'));
    const password = element(by.id('password'));
    const submitButton = element(by.css('button[type="submit"]'));

    await username.sendKeys('admin');
    await password.sendKeys('12345');
    await submitButton.click();

    const successMessage = element(by.css('.success'));
    expect(await successMessage.isDisplayed()).toBe(true);
});

Использование временных ожиданий и ExpectedConditions

Для динамических элементов и AJAX-запросов важно применять ожидания (browser.wait) с ExpectedConditions:

const EC = protractor.ExpectedConditions;

it('должен дождаться появления элемента', async function() {
    const button = element(by.id('loadButton'));
    await button.click();

    const loadedElement = element(by.id('loaded'));
    await browser.wait(EC.visibilityOf(loadedElement), 5000, 'Элемент не появился за 5 секунд');
    expect(await loadedElement.isDisplayed()).toBe(true);
});

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

  • browser.wait принимает условие, таймаут и сообщение об ошибке.
  • Это позволяет тесту не зависать, а корректно завершаться с ошибкой, если элемент не появляется.

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

Для сокращения повторяющегося кода полезно создавать вспомогательные функции, вызываемые внутри it().

async function login(username, password) {
    await element(by.id('username')).sendKeys(username);
    await element(by.id('password')).sendKeys(password);
    await element(by.css('button[type="submit"]')).click();
}

it('должен авторизоваться как администратор', async function() {
    await browser.get('https://example.com/login');
    await login('admin', '12345');
    expect(await element(by.css('.admin-panel')).isDisplayed()).toBe(true);
});

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

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

Метки и динамическое выполнение it()

В Jasmine можно использовать xit() для временного пропуска теста, либо динамически создавать тесты через массив данных:

const users = [
    {name: 'admin', pass: '12345'},
    {name: 'user', pass: 'abcde'}
];

users.forEach(user => {
    it(`должен авторизоваться как ${user.name}`, async function() {
        await browser.get('https://example.com/login');
        await login(user.name, user.pass);
        expect(await element(by.css('.dashboard')).isDisplayed()).toBe(true);
    });
});

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


Важные рекомендации по it()

  • Каждый it() должен быть коротким и проверять одну конкретную вещь.
  • Избегать зависимостей между тестами.
  • Использовать асинхронные функции для последовательного выполнения шагов.
  • Всегда применять ожидания для динамических элементов, чтобы избежать нестабильности тестов.
  • Группировать тесты в describe(), но оставлять it() как атомарные единицы.

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