Руководство по миграции
Миграция с Vitest 0.34.6
Минимальные требования
Vitest 1.0 требует Vite 5.0 и Node.js 18 или выше.
Для всех подпакетов @vitest/*
требуется Vitest версии 1.0.
Обновление снимков (Snapshots) #3961
Экранирование кавычек в снимках больше не производится, и все снимки теперь используют обратные кавычки (`) даже для однострочных строк.
- Кавычки больше не экранируются:
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
Object {
- \\"foo\\": \\"bar\\",
+ "foo": "bar",
}
`)
- Однострочные снимки теперь используют обратные кавычки "`" вместо ':
- 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
.
Стандартизация пулов (Pools) #4172
Для упрощения настройки runner были удалены некоторые опции конфигурации. Если вы используете --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
{
scripts: {
- "test": "vitest --no-threads"
// For identical behaviour:
+ "test": "vitest --pool forks --poolOptions.forks.singleFork"
// Or multi parallel forks:
+ "test": "vitest --pool forks"
}
}
{
scripts: {
- "test": "vitest --experimental-vm-threads"
+ "test": "vitest --pool vmThreads"
}
}
{
scripts: {
- "test": "vitest --isolate false"
+ "test": "vitest --poolOptions.threads.isolate false"
}
}
{
scripts: {
- "test": "vitest --no-threads --isolate false"
+ "test": "vitest --pool forks --poolOptions.forks.isolate false"
}
}
Изменения в покрытии кода (Coverage) #4265, #4442
Опция coverage.all
теперь включена по умолчанию. Это означает, что все файлы проекта, соответствующие шаблону coverage.include
, будут обработаны, даже если они не выполняются в тестах.
Изменилась структура API порогов покрытия кода. Теперь можно указывать пороги для отдельных файлов, используя glob-шаблоны.
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,
+ }
}
}
})
Типы Mock #4400
Некоторые типы были удалены в пользу стиля "Mock", используемого в Jest.
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'
WARNING
SpyInstance
объявлен устаревшим и будет удален в следующем основном выпуске. Используйте MockInstance
вместо него.
Таймеры (Timer mocks) #3925
vi.useFakeTimers()
больше не имитирует автоматически process.nextTick
. Вы можете имитировать process.nextTick
, явно указав его с помощью vi.useFakeTimers({ toFake: ['nextTick'] })
.
Однако имитация process.nextTick
невозможна при использовании --pool=forks
. Используйте другую опцию --pool
, если вам требуется имитация process.nextTick
.
Миграция с Jest
Vitest был разработан с API, совместимым с Jest, чтобы максимально упростить миграцию. Несмотря на это, вы все равно можете столкнуться со следующими различиями:
Глобальные переменные по умолчанию (Globals as a Default)
Jest имеет свой API глобальных переменных, включенный по умолчанию, в отличие от Vitest. Вы можете либо включить глобальные переменные через настройку конфигурации globals
, либо обновить свой код для использования импортов из модуля vitest
.
Если вы решите оставить глобальные переменные отключенными, имейте в виду, что общие библиотеки, такие как testing-library
, не будут автоматически запускать DOM cleanup.
Модульные Mock (Module Mocks)
В Jest при имитации модуля возвращаемое значение аргумента factory
становится экспортом по умолчанию. В Vitest аргумент factory
должен возвращать объект, в котором каждый экспорт определен явно. Например, следующий jest.mock
должен быть обновлен следующим образом:
jest.mock('./some-path', () => 'hello');
vi.mock('./some-path', () => ({
default: 'hello',
}));
Для получения более подробной информации обратитесь к разделу API vi.mock
.
Поведение автоматического Mock (Auto-Mocking Behaviour)
В отличие от Jest, имитированные модули в <root>/__mocks__
не загружаются, если не вызван vi.mock()
. Если вам нужно, чтобы они были имитированы в каждом тесте, как в Jest, вы можете имитировать их внутри setupFiles
.
Импорт оригинала имитированного пакета (Importing the Original of a Mocked Package)
Если вы частично имитируете пакет, вы могли использовать функцию Jest requireActual
. В Vitest вам следует заменить эти вызовы на vi.importActual
.
const { cloneDeep } = jest.requireActual('lodash/cloneDeep');
const { cloneDeep } = await vi.importActual('lodash/cloneDeep');
Расширение Mock на внешние библиотеки (Extends mocking to external libraries)
В Jest имитация модуля по умолчанию распространяется на другие внешние библиотеки, использующие тот же модуль. В Vitest вам нужно явно указать, какую стороннюю библиотеку вы хотите имитировать, добавив ее в server.deps.inline
, чтобы внешняя библиотека стала частью вашего исходного кода.
server.deps.inline: ["lib-name"]
Доступ к возвращаемым значениям имитированного Promise (Accessing the Return Values of a Mocked Promise)
Jest и Vitest хранят результаты вызовов mock в массиве mock.results
(../api/mock#mock-results), где свойство value
содержит возвращаемое значение каждого вызова. Однако, при имитации или шпионаже promise (например, с помощью mockResolvedValue
), в Jest свойство value
будет promise, а в Vitest оно содержит результат выполнения promise.
await expect(spy.mock.results[0].value).resolves.toBe(123);
expect(spy.mock.results[0].value).toBe(123);
Переменные окружения (Envs)
Как и Jest, Vitest устанавливает NODE_ENV
в test
, если он ранее не был установлен. Vitest также имеет аналог для JEST_WORKER_ID
, называемый VITEST_POOL_ID
(всегда меньше или равен maxThreads
). Если вы используете JEST_WORKER_ID
, переименуйте его в VITEST_POOL_ID
. Vitest также предоставляет VITEST_WORKER_ID
, который является уникальным идентификатором работающего worker. Это число не зависит от maxThreads
и увеличивается с каждым созданным worker.
Замена свойства (Replace property)
Если вы хотите изменить объект, используя replaceProperty API в Jest, вы можете использовать vi.stubEnv
или vi.spyOn
для достижения того же результата в Vitest.
Callback Done
В Vitest v0.10.0 стиль объявления тестов с использованием callback объявлен устаревшим. Вы можете переписать их для использования функций async
/await
или использовать Promise для имитации стиля callback.
it('should work', (done) => { // [!code --]
it('should work', () => new Promise(done => { // [!code ++]
// ...
done()
}) // [!code --]
})) // [!code ++]
Хуки (Hooks)
Хуки beforeAll
/beforeEach
могут возвращать teardown function в Vitest. Вам может потребоваться изменить объявления хуков, если они возвращают значения, отличные от undefined
или null
:
beforeEach(() => setActivePinia(createTestingPinia()));
beforeEach(() => {
setActivePinia(createTestingPinia());
});
В Jest хуки вызываются последовательно (один за другим). По умолчанию Vitest запускает хуки параллельно. Чтобы использовать поведение Jest, обновите опцию sequence.hooks
:
export default defineConfig({
test: {
sequence: {
hooks: 'list',
},
},
});
Типы (Types)
Vitest не имеет эквивалента пространству имен jest
, поэтому вам нужно будет импортировать типы непосредственно из vitest
:
let fn: jest.Mock<string, [string]>;
import type { Mock } from 'vitest';
let fn: Mock<[string], string>;
Кроме того, Vitest имеет тип Args
в качестве первого аргумента вместо Returns
, как вы можете видеть в diff.
Таймеры (Timers)
Vitest не поддерживает устаревшие таймеры Jest.
Тайм-аут (Timeout)
Если вы использовали jest.setTimeout
, вам нужно будет перейти на vi.setConfig
:
jest.setTimeout(5_000);
vi.setConfig({ testTimeout: 5_000 });
Vue Snapshots
Это не специфическая для Jest функция, но если вы ранее использовали Jest с предустановкой vue-cli, вам нужно будет установить пакет jest-serializer-vue
и использовать его внутри setupFiles:
vite.config.js
import { defineConfig } from 'vite';
export default defineConfig({
test: {
setupFiles: ['./tests/unit/setup.js'],
},
});
tests/unit/setup.js
import vueSnapshotSerializer from 'jest-serializer-vue';
expect.addSnapshotSerializer(vueSnapshotSerializer);
В противном случае в ваших снимках будет много экранированных кавычек "
.