Skip to content

Это руководство демонстрирует, как использовать опцию concurrentTestGlob для выборочного запуска тестов параллельно на основе шаблонов имён файлов.

Структура проекта

sh
my-project/
├── bunfig.toml
├── tests/
   ├── unit/
   ├── math.test.ts          # Последовательно
   └── utils.test.ts         # Последовательно
   └── integration/
       ├── concurrent-api.test.ts     # Параллельно
       └── concurrent-database.test.ts # Параллельно

Конфигурация

Настройте ваш bunfig.toml для запуска файлов тестов с префиксом "concurrent-" параллельно:

toml
[test]
# Запускать все файлы тестов с префиксом "concurrent-" параллельно
concurrentTestGlob = "**/concurrent-*.test.ts"

Файлы тестов

Модульный тест (Последовательно)

Последовательные тесты хороши для тестов, которые разделяют состояние или имеют определённые требования к порядку:

ts
import { test, expect } from "bun:test";

// Эти тесты запускаются последовательно по умолчанию
let sharedState = 0;

test("сложение", () => {
  sharedState = 5 + 3;
  expect(sharedState).toBe(8);
});

test("использует предыдущее состояние", () => {
  // Этот тест зависит от состояния предыдущего теста
  expect(sharedState).toBe(8);
});

Интеграционный тест (Параллельно)

Тесты в файлах, соответствующих шаблону глоба, автоматически запускаются параллельно:

ts
import { test, expect } from "bun:test";

// Эти тесты автоматически запускаются параллельно благодаря имени файла, соответствующему шаблону глоба.
// Использование test() эквивалентно test.concurrent(), когда файл соответствует concurrentTestGlob.
// Каждый тест независим и может выполняться параллельно.

test("получить данные пользователя", async () => {
  const response = await fetch("/api/user/1");
  expect(response.ok).toBe(true);
});

// также можно использовать test.concurrent() для явного указания параллельности
test.concurrent("получить посты", async () => {
  const response = await fetch("/api/posts");
  expect(response.ok).toBe(true);
});

// также можно использовать test.serial() для явного указания последовательности
test.serial("получить комментарии", async () => {
  const response = await fetch("/api/comments");
  expect(response.ok).toBe(true);
});

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

bash
# Запустить все тесты - файлы concurrent-*.test.ts будут запущены параллельно
bun test

# Переопределение: Принудительно запустить ВСЕ тесты параллельно
# Примечание: Это переопределяет bunfig.toml и запускает все тесты параллельно, независимо от глоба
bun test --concurrent

# Запустить только модульные тесты (последовательно)
bun test tests/unit

# Запустить только интеграционные тесты (параллельно благодаря шаблону глоба)
bun test tests/integration

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

  1. Постепенная миграция: Мигрируйте на параллельные тесты файл за файлом переименовывая их
  2. Чёткая организация: Именование файлов указывает режим выполнения
  3. Производительность: Интеграционные тесты выполняются быстрее параллельно
  4. Безопасность: Модульные тесты остаются последовательными там, где это необходимо
  5. Гибкость: Легко изменить режим выполнения переименовав файлы

Стратегия миграции

Для миграции существующих тестов на параллельное выполнение:

  1. Начните с независимых интеграционных тестов — Обычно они не разделяют состояние
  2. Переименуйте файлы для соответствия шаблону глоба: mv api.test.ts concurrent-api.test.ts
  3. Убедитесь, что тесты всё ещё проходят — Запустите bun test для проверки отсутствия состояний гонки
  4. Следите за проблемами общего состояния — Ищите нестабильные тесты или неожиданные сбои
  5. Продолжайте постепенно мигрировать стабильные тесты — Не торопите миграцию

Советы

  • Используйте описательные префиксы: concurrent-, parallel-, async-
  • Держите связанные последовательные тесты вместе в одном каталоге
  • Документируйте, почему определённые тесты должны оставаться последовательными с комментариями
  • Используйте test.concurrent() для детального контроля в последовательных файлах (Примечание: В файлах, соответствующих concurrentTestGlob, обычный test() уже запускается параллельно)

Несколько шаблонов

Вы можете указать несколько шаблонов для различных категорий тестов:

toml
[test]
concurrentTestGlob = [
  "**/integration/*.test.ts",
  "**/e2e/*.test.ts",
  "**/concurrent-*.test.ts"
]

Эта конфигурация будет запускать тесты параллельно, если они соответствуют любому из этих шаблонов:

  • Все тесты в каталогах integration/
  • Все тесты в каталогах e2e/
  • Все тесты с префиксом concurrent- в любом месте проекта

Bun от www.bunjs.com.cn