Фокусировка на тестах: fit() и fdescribe()

В процессе разработки и отладки автотестов нередко возникает необходимость запускать не весь набор спецификаций, а только отдельные тесты или группы тестов. Protractor, как и Jasmine, предоставляет для этого встроенный механизм фокусировки, основанный на функциях fit() и fdescribe(). Эти инструменты позволяют временно ограничить область выполнения тестов без изменения конфигурации раннера и структуры проекта.


Принцип работы fit() и fdescribe()

Protractor использует Jasmine как тестовый фреймворк по умолчанию, поэтому механика фокусировки полностью повторяет поведение Jasmine.

  • fit() — фокусирует один конкретный тест (it)
  • fdescribe() — фокусирует группу тестов (describe) и все вложенные в неё спецификации

При наличии хотя бы одного fit() или fdescribe() все остальные тесты игнорируются, независимо от их расположения в проекте.


fit() — фокусировка на одном тесте

fit() является аналогом it(), но с приоритетом выполнения.

describe('Авторизация пользователя', () => {

  it('не пускает с неверным паролем', async () => {
    // обычный тест
  });

  fit('успешно входит с корректными данными', async () => {
    await browser.get('/login');
    await element(by.id('username')).sendKeys('admin');
    await element(by.id('password')).sendKeys('admin123');
    await element(by.buttonText('Войти')).click();

    expect(await browser.getCurrentUrl()).toContain('/dashboard');
  });

  it('блокирует пользователя после 3 ошибок', async () => {
    // тест не будет выполнен
  });
});

В этом примере будет выполнен только один тест, помеченный fit(). Все остальные it() игнорируются, даже если они находятся в других файлах спецификаций.

Ключевые особенности:

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

fdescribe() — фокусировка на группе тестов

fdescribe() применяется, когда требуется выполнить целый блок связанных тестов.

fdescribe('Форма регистрации', () => {

  it('отображает обязательные поля', async () => {
    // тест
  });

  it('показывает ошибку при пустом email', async () => {
    // тест
  });

  it('успешно регистрирует пользователя', async () => {
    // тест
  });

});

describe('Форма входа', () => {
  it('не будет выполнен', async () => {
    // игнорируется
  });
});

Все тесты внутри fdescribe() будут выполнены, а остальные describe() — пропущены.

Важно:

  • фокусировка действует на уровень выше, чем fit();
  • вложенные describe() внутри fdescribe() также выполняются;
  • можно использовать для локальной разработки модуля или фичи.

Приоритеты при множественной фокусировке

Если в проекте присутствуют одновременно fit() и fdescribe(), Jasmine применяет следующий порядок:

  1. Выполняются все fdescribe()
  2. Внутри них — все fit() и обычные it()
  3. Обычные describe() и it() вне фокусированных блоков полностью игнорируются

Пример:

fdescribe('Основной сценарий', () => {

  fit('критический тест', async () => {
    // выполнится
  });

  it('второстепенный тест', async () => {
    // выполнится
  });
});

fit('одиночный тест вне блока', async () => {
  // тоже выполнится
});

it('обычный тест', async () => {
  // не выполнится
});

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


Поведение в Protractor Runner

При запуске через protractor.conf.js механизм фокусировки:

  • не требует дополнительных флагов;
  • работает одинаково в режиме directConnect и при запуске через Selenium Server;
  • не зависит от параметров specs или suites.

Protractor просто передаёт управление Jasmine, который фильтрует тесты на этапе построения spec tree.


Отличие от xdescribe() и xit()

Фокусировка и исключение тестов — разные концепции.

Функция Назначение
fit() выполнить только этот тест
fdescribe() выполнить только этот блок
xit() временно отключить тест
xdescribe() отключить группу тестов

fit() и fdescribe() — инструменты активной фокусировки, тогда как x* — инструменты пассивного отключения.


Типичные ошибки при использовании фокусировки

Забытый fit() в коммите

Наиболее распространённая проблема — случайное попадание fit() или fdescribe() в репозиторий. В CI это приводит к:

  • ложноположительным результатам;
  • выполнению 1–2 тестов вместо сотен;
  • пропуску регрессионного набора.

Непредсказуемое поведение при множестве fdescribe()

Несколько fdescribe() в разных файлах могут создать иллюзию частичного запуска, хотя на самом деле выполняется только их совокупность.


Практика контроля фокусированных тестов

В реальных проектах часто применяются дополнительные меры:

  • линтеры, запрещающие fit() и fdescribe() (eslint-plugin-jasmine);
  • pre-commit хуки;
  • отдельные npm-скрипты для локальной отладки;
  • grep-проверки в CI.

Пример правила ESLint:

"jasmine/no-focused-tests": "error"

Когда использование оправдано

fit() и fdescribe() полезны:

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

В стабильной ветке и CI они недопустимы и должны отсутствовать полностью.


Совместимость и будущее

Несмотря на то что Protractor объявлен устаревшим, механизм фокусировки остаётся актуальным:

  • полностью совместим с Jasmine 2.x и 3.x;
  • аналогичен поведению в Karma и standalone Jasmine;
  • концептуально повторяется в других фреймворках (only() в Mocha, test.only() в Jest).

Понимание работы fit() и fdescribe() позволяет эффективно управлять объёмом выполняемых тестов и ускорять процесс разработки без вмешательства в инфраструктуру тестового запуска.