Skip to content

Тестирование

Chef запускает тесты в реальном браузере через Playwright. Поддерживаются два вида тестов: unit-тесты (Mocha + Chai) и E2E-тесты (Playwright Test API).

Подготовка

Инициализируйте тестовое окружение:

bash
chef init tests

Команда создаёт два файла в корне проекта:

ФайлОписание
playwright.config.tsКонфиг Playwright для запуска unit и E2E тестов в браузере
.env.testУчётные данные для автоматической аутентификации при тестировании

Заполните учётные данные вашей локальной установки Bitrix:

env
BASE_URL=http://localhost
LOGIN=admin
PASSWORD=your_password
ПеременнаяОписание
BASE_URLURL локальной установки Bitrix
LOGINЛогин тестового пользователя
PASSWORDПароль тестового пользователя

WARNING

Не коммитьте .env.test в систему контроля версий — файл содержит конфиденциальные данные.

Установите браузеры Playwright:

bash
npx playwright install

Типы для IDE

mocha, chai и их типы включены в Chef и используются при запуске chef test. Для работы автодополнения в IDE установите типы локально:

bash
npm install --save-dev @types/mocha @types/chai @playwright/test

Запуск тестов

bash
# Все тесты расширения
chef test vendor.my-extension

# Только unit-тесты
chef test unit vendor.my-extension

# Только e2e-тесты
chef test e2e vendor.my-extension

# Конкретный файл
chef test unit vendor.my-extension ./utils.test.ts

# Тесты по паттерну
chef test vendor.* --grep "should render"

# Watch-режим — перезапуск при изменениях
chef test vendor.my-extension -w

Отладка

bash
# Открыть браузер с DevTools
chef test vendor.my-extension --debug

# С видимым окном браузера
chef test vendor.my-extension --headed

# В конкретном браузере
chef test vendor.my-extension --project chromium

В режиме --debug включаются source maps и открываются DevTools — можно ставить breakpoints прямо в исходном TypeScript-коде.

Массовый запуск

chef test без аргументов или с glob-паттерном (im.v2.**) проходит по всем подходящим расширениям. Расширения без тестов пропускаются молча — в выводе появляются только те, у которых есть тесты или какие-то проблемы.

Браузерный консольный вывод по умолчанию скрыт, чтобы не замусоривать массовый отчёт. Если нужно — добавь --console:

bash
chef test im.v2.** --console

Статусы задач

Рядом с расширением chef показывает причину неудачи прямо в строке задачи:

СтатусЧто значит
✓ Unit testsВсе тесты прошли
✗ Unit tests (3 failed)Часть тестов упала, число — сколько
✗ Unit tests (build failed)Не собрался тестовый бандл (Rollup)
✗ Unit tests (crashed before any tests ran)Упало до первого it — обычно ошибка в setup
⚠ Unit tests (no tests collected)Файлы есть, но Mocha не нашёл it (пустой describe, .skip)
— Unit tests (no test files)В директории test/unit/ (или test/) нет *.test.{ts,js}
— E2E tests (no test files)То же для e2e

Сводка в конце

После прогона chef печатает агрегированный отчёт:

  • Failed Tests (N) — все упавшие тесты со стек-трейсами и code frame, сгруппированные по расширениям.
  • Errors (N) — ошибки сборки и runtime-крэши, по одной строке на причину.
  • Issues — список расширений с количеством ошибок/предупреждений.
  • Extensions / Tests / Time — общие цифры: сколько расширений и тестов прошло/упало, сколько заняло.

Советы

Изоляция тестов

Каждый тест должен быть независимым. Используйте beforeEach/afterEach для настройки и очистки:

ts
describe('TodoList', () => {
  let list: TodoList;

  beforeEach(() => {
    list = new TodoList();
  });

  afterEach(() => {
    list.destroy();
  });

  it('should add item', () => {
    list.add('Buy milk');
    assert.equal(list.getCount(), 1);
  });

  it('should start empty', () => {
    assert.equal(list.getCount(), 0);
  });
});

Организация тестов

Группируйте тесты по функциональности:

ts
describe('UserService', () => {
  describe('create', () => {
    it('should create user with valid data', () => { /* ... */ });
    it('should throw on duplicate email', () => { /* ... */ });
  });

  describe('update', () => {
    it('should update user name', () => { /* ... */ });
    it('should not allow empty name', () => { /* ... */ });
  });

  describe('delete', () => {
    it('should soft delete user', () => { /* ... */ });
  });
});

Распространяется под лицензией MIT.