CI, Vitest и чек-лист

Завершающий урок: автоматический запуск тестов в CI, обзор Vitest и итоговый чек-лист курса.

CI (Continuous Integration) автоматически запускает тесты при каждом пуше, не давая сломанному коду попасть в основную ветку.

Тесты в CI

Ценность тестов раскрывается, когда они запускаются автоматически у каждого изменения. Самый частый вариант — GitHub Actions: workflow ставит зависимости и запускает jest.

name: tests
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx jest --coverage

Если хоть один тест падает, Jest вернёт ненулевой код выхода — и шаг, а с ним вся сборка, станет красным. Pull request с красными тестами не пускают в main. В CI обычно используют npm ci (точная установка по lock-файлу) и часто добавляют --ci к Jest, чтобы он не создавал новые снапшоты молча.

Другие раннеры: Vitest

Vitest — современный тест-раннер, особенно популярный в проектах на Vite (Vue, современный фронтенд). Его API почти совпадает с Jest (describe, it, expect, моки), поэтому знания переносятся напрямую.

ОсобенностьJestVitest
APIdescribe/it/expectпочти такой же
ESM и TypeScriptчерез настройкуиз коробки
Скоростьвысокаячасто выше на Vite-проектах
Зрелость/экосистемаочень большаябыстро растёт

Существуют и другие (Mocha + Chai, node:test), но Jest и Vitest сегодня закрывают большинство задач. Освоив Jest, вы легко перейдёте на Vitest при необходимости.

Закрепим: код выхода решает всё — на чистом JS

Покажем, как CI «понимает», прошли ли тесты: по числу провалов.

const results = [true, true, false, true]; // true = passed
const failed = results.filter(r => !r).length;

console.log('Всего тестов:', results.length);
console.log('Провалено:', failed);
const exitCode = failed === 0 ? 0 : 1;
console.log('Код выхода:', exitCode);
console.log('Сборка в CI:', exitCode === 0 ? 'ЗЕЛЁНАЯ' : 'КРАСНАЯ');

Вывод:

Всего тестов: 4
Провалено: 1
Код выхода: 1
Сборка в CI: КРАСНАЯ

Ровно так и работает CI: Jest возвращает 0 при успехе и 1 при провале, а система сборки красит статус по этому коду.

Итоговый чек-лист по курсу

  • Тесты лежат рядом с кодом (*.test.js), запускаются npm test.
  • Правильные матчеры: toBe для примитивов, toEqual для объектов.
  • Структура: describe + AAA, понятные имена, один тест — одно поведение.
  • Изоляция: beforeEach, без общего состояния, моки вместо сети/времени.
  • Асинхронность всегда дожидается (await/resolves).
  • Покрыты граничные случаи; тесты быстрые, детерминированные, самопроверяемые.
  • Покрытие измеряется, но не превращается в самоцель.
  • Тесты гоняются в CI на каждом пуше.

Итог

  • CI запускает Jest на каждом изменении; красные тесты блокируют merge.
  • В CI: npm ci + npx jest --coverage --ci.
  • Vitest — близкий по API современный раннер; знания Jest переносятся.
  • Держите в голове чек-лист — и тесты будут приносить пользу, а не боль.
Проверьте себя
1. Как CI понимает, что тесты провалились?
AЧитает комментарии в коде
BJest возвращает ненулевой код выхода, и сборка становится красной
CСчитает количество файлов
DОтправляет email
2. Что верно про Vitest?
AЭто база данных
BЭто современный тест-раннер с API, почти совпадающим с Jest, знания переносятся
CОн несовместим с describe/it/expect
DОн заменяет GitHub Actions
3. Почему в CI обычно используют npm ci вместо npm install?
Anpm ci быстрее запускает тесты
Bnpm ci ставит точные версии по lock-файлу, давая воспроизводимую сборку
Cnpm ci создаёт снапшоты
DЭто единственная команда, понятная Jest
Поддержать проект