Skip to content
Vitest 2
Main Navigation РуководствоAPIКонфигурацияРежим браузераПродвинутый
2.1.9
1.6.1
0.34.6

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Русский

English
简体中文
繁體中文
Español
Français
Português – Brasil
Deutsch
日本語
한국어
Italiano
Polski
Türkçe
čeština
magyar

Внешний вид

Sidebar Navigation

Зачем Vitest

Начало работы

Функциональность

Рабочая область

Интерфейс командной строки

Фильтрация тестов

Репортёры

Покрытие кода

Снапшоты

Мокирование

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

Vitest UI

In-source тестирование (Тестирование в исходном коде)

Контекст теста

Тестовая среда

Расширение проверок (matchers)

Интеграции с IDE

Отладка

Сравнения с другими тестовыми фреймворками

Руководство по миграции

Распространенные ошибки

Profiling Test Performance

Улучшение производительности

Содержание страницы

Руководство по миграции ​

Миграция на Vitest 2.0 ​

Пул по умолчанию теперь forks ​

Vitest 2.0 изменяет конфигурацию pool по умолчанию на 'forks' для повышения стабильности. Полное обоснование можно найти в PR.

Если вы использовали poolOptions без указания pool, возможно, вам потребуется обновить конфигурацию:

ts
export default defineConfig({
  test: {
    poolOptions: {
      threads: {
        singleThread: true, 
      }, 
      forks: {
        singleFork: true, 
      }, 
    },
  },
});

Хуки выполняются последовательно ​

До Vitest 2.0 все хуки выполнялись параллельно. В версии 2.0 все хуки выполняются последовательно. Кроме того, хуки afterAll/afterEach выполняются в обратном порядке.

Чтобы вернуться к параллельному выполнению хуков, измените sequence.hooks на 'parallel':

ts
export default defineConfig({
  test: {
    sequence: {
      hooks: 'parallel', 
    }, 
  },
});

suite.concurrent запускает все тесты параллельно ​

Ранее, если для набора тестов указывался concurrent, параллельные тесты группировались по наборам и запускались последовательно. Теперь, следуя поведению Jest, все тесты запускаются параллельно (с учетом ограничений maxConcurrency).

coverage.ignoreEmptyLines для V8 Coverage включен по умолчанию ​

Значение по умолчанию для coverage.ignoreEmptyLines теперь true. Это важное изменение может повлиять на отчеты о покрытии кода и потребовать корректировки пороговых значений покрытия для некоторых проектов. Эта корректировка влияет только на настройку по умолчанию, когда coverage.provider равен 'v8'.

Удаление опции watchExclude ​

Vitest использует наблюдатель Vite. Исключайте файлы или каталоги, добавляя их в server.watch.ignored:

ts
export default defineConfig({
  server: {
    watch: {
      ignored: ['!node_modules/examplejs'], 
    }, 
  }, 
});

--segfault-retry удален ​

С изменениями в пуле по умолчанию эта опция больше не нужна. Если вы столкнулись с ошибками сегментации (segfault), попробуйте переключиться на пул 'forks'. Если проблема сохраняется, пожалуйста, откройте новую проблему с воспроизведением.

Пустая задача в задачах набора удалена ​

Это изменение касается расширенного API задач. Ранее, при обходе .suite, это в конечном итоге приводило к пустой внутренней задаче, которая использовалась вместо файловой задачи.

Это делает .suite необязательным; если задача определена на верхнем уровне, она не будет иметь набора. Вы можете вернуться к свойству .file, которое теперь присутствует во всех задачах (включая саму файловую задачу, поэтому будьте осторожны, чтобы не попасть в бесконечную рекурсию).

Это изменение также удаляет файл из expect.getState().currentTestName и делает expect.getState().testPath обязательным для использования.

task.meta добавлен в JSON Reporter ​

JSON-репортер теперь включает task.meta для каждого результата утверждения.

Упрощенные обобщенные типы мок-функций (например, vi.fn<T>, Mock<T>) ​

Ранее vi.fn<TArgs, TReturn> принимал два обобщенных типа: отдельно для аргументов и для возвращаемого значения. Теперь он напрямую принимает тип функции vi.fn<T> для упрощения использования.

ts
import { type Mock, vi } from 'vitest';

const add = (x: number, y: number): number => x + y;

// using vi.fn<T>
const mockAdd = vi.fn<Parameters<typeof add>, ReturnType<typeof add>>(); 
const mockAdd = vi.fn<typeof add>(); 

// using Mock<T>
const mockAdd: Mock<Parameters<typeof add>, ReturnType<typeof add>> = vi.fn(); 
const mockAdd: Mock<typeof add> = vi.fn(); 

Доступ к разрешенным mock.results ​

Ранее Vitest автоматически разрешал промисы, возвращаемые функцией, и их значения записывались в mock.results. Теперь есть отдельное свойство mock.settledResults, которое заполняется только тогда, когда возвращенный Promise разрешен или отклонен.

ts
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();

const result = fn.mock.results[0]; // 'result'
const result = fn.mock.results[0]; // 'Promise<result>'

const settledResult = fn.mock.settledResults[0]; // 'result'

С этим изменением мы также вводим новые матчеры toHaveResolved*, аналогичные toHaveReturned, чтобы упростить миграцию, если вы использовали toHaveReturned раньше:

ts
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();

expect(fn).toHaveReturned('result'); 
expect(fn).toHaveResolved('result'); 

Режим браузера ​

Режим браузера Vitest претерпел множество изменений во время бета-цикла. Вы можете прочитать о нашей философии в отношении режима браузера на странице обсуждения GitHub.

Большинство изменений были связаны с добавлением новых функций, но также присутствовали и небольшие обратно несовместимые изменения:

  • Провайдер none был переименован в preview #5842
  • Провайдер preview теперь является провайдером по умолчанию #5842
  • indexScripts переименован в orchestratorScripts #5842

Удалены устаревшие опции ​

Некоторые устаревшие параметры были удалены:

  • Команда vitest typecheck - вместо нее используйте vitest --typecheck
  • Переменные окружения VITEST_JUNIT_CLASSNAME и VITEST_JUNIT_SUITE_NAME (вместо них используйте опции репортера)
  • Проверка покрытия c8 (вместо нее используйте coverage-v8)
  • Экспорт SnapshotEnvironment из vitest - импортируйте его из vitest/snapshot
  • SpyInstance удален в пользу MockInstance

Миграция на Vitest 1.0 ​

Минимальные требования ​

Vitest 1.0 требует Vite 5.0 и Node.js 18 или выше.

Для всех подпакетов @vitest/* требуется Vitest версии 1.0.

Обновление снимков #3961 ​

Кавычки в снимках больше не экранируются, и все снимки используют обратные кавычки (`) даже для однострочных значений.

  1. Кавычки больше не экранируются:
diff
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
  Object {
-    \\"foo\\": \\"bar\\",
+    "foo": "bar",
  }
`)
  1. Однострочные снимки теперь используют кавычки "`" вместо ':
diff
- expect('some string').toMatchInlineSnapshot('"some string"')
+ expect('some string').toMatchInlineSnapshot(`"some string"`)

Также были изменения в пакете @vitest/snapshot. Если вы не используете его напрямую, вам ничего не нужно менять.

  • Вам больше не нужно расширять SnapshotClient только для переопределения метода equalityCheck: просто передайте его как isEqual при инициализации экземпляра.
  • client.setTest был переименован в client.startCurrentRun
  • client.resetCurrent был переименован в client.finishCurrentRun

Пулы стандартизированы #4172 ​

Мы удалили множество параметров конфигурации, чтобы упростить настройку тестового фреймворка под ваши нужды. Пожалуйста, ознакомьтесь с примерами миграции, если вы полагаетесь на --threads или другие связанные флаги.

  • --threads теперь --pool=threads
  • --no-threads теперь --pool=forks
  • --single-thread теперь --poolOptions.threads.singleThread
  • --experimental-vm-threads теперь --pool=vmThreads
  • --experimental-vm-worker-memory-limit теперь --poolOptions.vmThreads.memoryLimit
  • --isolate теперь --poolOptions.<pool-name>.isolate и browser.isolate
  • test.maxThreads теперь test.poolOptions.<pool-name>.maxThreads
  • test.minThreads теперь test.poolOptions.<pool-name>.minThreads
  • test.useAtomics теперь test.poolOptions.<pool-name>.useAtomics
  • test.poolMatchGlobs.child_process теперь test.poolMatchGlobs.forks
  • test.poolMatchGlobs.experimentalVmThreads теперь test.poolMatchGlobs.vmThreads
diff
{
  scripts: {
-    "test": "vitest --no-threads"
     // For identical behaviour:
+    "test": "vitest --pool forks --poolOptions.forks.singleFork"
     // Or multi parallel forks:
+    "test": "vitest --pool forks"

  }
}
diff
{
  scripts: {
-    "test": "vitest --experimental-vm-threads"
+    "test": "vitest --pool vmThreads"
  }
}
diff
{
  scripts: {
-    "test": "vitest --isolate false"
+    "test": "vitest --poolOptions.threads.isolate false"
  }
}
diff
{
  scripts: {
-    "test": "vitest --no-threads --isolate false"
+    "test": "vitest --pool forks --poolOptions.forks.isolate false"
  }
}

Изменения в покрытии #4265, #4442 ​

Опция coverage.all теперь включена по умолчанию. Это означает, что все файлы проекта, соответствующие шаблону coverage.include, будут обработаны, даже если они не были выполнены.

Форма API пороговых значений покрытия была изменена, и теперь она поддерживает указание пороговых значений для конкретных файлов с использованием шаблонов glob:

diff
export default defineConfig({
  test: {
    coverage: {
-      perFile: true,
-      thresholdAutoUpdate: true,
-      100: true,
-      lines: 100,
-      functions: 100,
-      branches: 100,
-      statements: 100,
+      thresholds: {
+        perFile: true,
+        autoUpdate: true,
+        100: true,
+        lines: 100,
+        functions: 100,
+        branches: 100,
+        statements: 100,
+      }
    }
  }
})

Типы моков #4400 ​

Несколько типов были удалены в пользу именования "Mock", соответствующего стилю Jest.

diff
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'

WARNING

SpyInstance устарел в пользу MockInstance и будет удален в следующем основном выпуске.

Моки таймеров #3925 ​

vi.useFakeTimers() больше не мокает автоматически process.nextTick. По-прежнему можно мокать process.nextTick, явно указав его с помощью vi.useFakeTimers({ toFake: ['nextTick'] }).

Однако мокинг process.nextTick невозможен при использовании --pool=forks. Используйте другую опцию --pool, если вам нужен мокинг process.nextTick.

Миграция с Jest ​

Vitest был разработан с API, совместимым с Jest, чтобы максимально упростить миграцию с Jest. Несмотря на эти усилия, вы все равно можете столкнуться со следующими различиями:

Глобальные объекты по умолчанию ​

Jest по умолчанию включает свой глобальный API. Vitest не включает их по умолчанию. Вы можете либо включить глобальные переменные через настройку конфигурации globals, либо обновить свой код для использования импортов из модуля vitest.

Если вы решите оставить глобальные переменные отключенными, имейте в виду, что популярные библиотеки, такие как testing-library, не будут выполнять автоматическую очистку DOM.

Моки модулей ​

При создании мока модуля в Jest возвращаемое значение фабричной функции является экспортом по умолчанию. В Vitest фабричная функция должна возвращать объект, в котором явно определен каждый экспорт. Например, следующий jest.mock должен быть обновлен следующим образом:

ts
jest.mock('./some-path', () => 'hello'); 
vi.mock('./some-path', () => ({
  default: 'hello', 
})); 

Для получения более подробной информации, пожалуйста, обратитесь к разделу API vi.mock.

Поведение автоматического мокирования ​

В отличие от Jest, мок-модули в <root>/__mocks__ не загружаются, если не вызван vi.mock(). Если вам нужно, чтобы они были мокированы в каждом тесте, как в Jest, вы можете мокировать их внутри setupFiles.

Импорт оригинальной версии мокированного пакета ​

Если вы выполняете частичное мокирование пакета, возможно, ранее вы использовали функцию Jest requireActual. В Vitest вам следует заменить эти вызовы на vi.importActual.

ts
const { cloneDeep } = jest.requireActual('lodash/cloneDeep'); 
const { cloneDeep } = await vi.importActual('lodash/cloneDeep'); 

Расширение мокирования на внешние библиотеки ​

В отличие от Jest, который делает это по умолчанию, при мокировании модуля и необходимости распространить это мокирование на другие внешние библиотеки, использующие тот же модуль, вам следует явно указать, какую стороннюю библиотеку вы хотите мокировать. Для этого используйте server.deps.inline, чтобы внешняя библиотека обрабатывалась как часть вашего исходного кода.

server.deps.inline: ["lib-name"]

expect.getState().currentTestName ​

Имена test в Vitest объединяются символом > для лучшего различения тестов от наборов, тогда как Jest использует пробел ().

diff
- `${describeTitle} ${testTitle}`
+ `${describeTitle} > ${testTitle}`

Переменные окружения ​

Как и Jest, Vitest устанавливает NODE_ENV в test, если он не был установлен ранее. Vitest также имеет аналог JEST_WORKER_ID, который называется VITEST_POOL_ID (всегда меньше или равен maxThreads). Если вы используете JEST_WORKER_ID, не забудьте переименовать его. Vitest также предоставляет VITEST_WORKER_ID, который является уникальным идентификатором запущенного рабочего процесса. Это число не зависит от maxThreads и увеличивается с каждым созданным рабочим процессом.

Свойство replace ​

Если вы хотите изменить объект, в Jest вы бы использовали API replaceProperty. В Vitest для этой цели можно использовать vi.stubEnv или vi.spyOn.

Колбэк Done ​

Начиная с Vitest v0.10.0, стиль объявления тестов с использованием функций обратного вызова устарел. Вы можете переписать их, используя функции async/await, или использовать Promise для эмуляции поведения функций обратного вызова.

it('should work', (done) => {  // [!code --]
it('should work', () => new Promise(done => { // [!code ++]
  // ...
  done()
}) // [!code --]
})) // [!code ++]

Хуки ​

Хуки beforeAll/beforeEach могут возвращать функцию завершения в Vitest. Из-за этого вам может потребоваться переписать ваши хуки, если они возвращают что-либо, кроме undefined или null:

ts
beforeEach(() => setActivePinia(createTestingPinia())); 
beforeEach(() => {
  setActivePinia(createTestingPinia());
}); 

В Jest хуки вызываются последовательно. По умолчанию Vitest запускает хуки параллельно. Чтобы использовать поведение Jest, обновите опцию sequence.hooks:

ts
export default defineConfig({
  test: {
    sequence: {
      hooks: 'list', 
    }, 
  },
});

Типы ​

Vitest не имеет эквивалента глобального объекта jest, поэтому вам нужно будет импортировать типы непосредственно из vitest:

ts
let fn: jest.Mock<(name: string) => number>; 
import type { Mock } from 'vitest'; 
let fn: Mock<(name: string) => number>; 

Таймеры ​

Vitest не поддерживает устаревший механизм таймеров Jest.

Таймаут ​

Если вы использовали jest.setTimeout, вам нужно будет перейти на vi.setConfig:

ts
jest.setTimeout(5_000); 
vi.setConfig({ testTimeout: 5_000 }); 

Снимки Vue ​

Это не специфичная для Jest функция, но если вы ранее использовали Jest с пресетом vue-cli, вам потребуется установить пакет jest-serializer-vue и использовать его в setupFiles:

js
import { defineConfig } from 'vite';

export default defineConfig({
  test: {
    setupFiles: ['./tests/unit/setup.js'],
  },
});
js
import vueSnapshotSerializer from 'jest-serializer-vue';

expect.addSnapshotSerializer(vueSnapshotSerializer);

В противном случае ваши снимки будут содержать много экранированных символов ".

Pager
Предыдущая страницаСравнения с другими тестовыми фреймворками
Следующая страницаРаспространенные ошибки

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors

https://v2.vitest.dev/guide/migration

Выпущено на условиях лицензии MIT.

Авторские права (c) 2024 Mithril Contributors