Průvodce migrací
Migrace na Vitest 2.0
Výchozí pool je forks
Vitest 2.0 mění výchozí konfiguraci pro pool
na 'forks'
pro lepší stabilitu. Podrobnější zdůvodnění naleznete v PR.
Pokud jste dříve používali poolOptions
bez specifikace pool
, možná budete muset aktualizovat svou konfiguraci:
export default defineConfig({
test: {
poolOptions: {
threads: {
singleThread: true,
},
forks: {
singleFork: true,
},
},
},
});
Hooky běží v zásobníku
Před Vitest 2.0 běžely všechny hooky paralelně. Ve verzi 2.0 běží všechny hooky sériově. Navíc hooky afterAll
/afterEach
běží v obráceném pořadí.
Pro návrat k paralelnímu spouštění hooků změňte sequence.hooks
na 'parallel'
:
export default defineConfig({
test: {
sequence: {
hooks: 'parallel',
},
},
});
suite.concurrent
spouští všechny testy souběžně
Dříve, specifikace concurrent
na sadě testů seskupovala souběžné testy podle sad a spouštěla je sekvenčně. Nyní, podle chování Jestu, se všechny testy spouštějí souběžně (s omezením maxConcurrency
).
coverage.ignoreEmptyLines
pro V8 Coverage je ve výchozím nastavení povoleno
Výchozí hodnota coverage.ignoreEmptyLines
je nyní true
. Tato významná změna může ovlivnit zprávy o pokrytí kódu, což vyžaduje úpravy prahových hodnot pokrytí pro některé projekty. Tato úprava ovlivňuje pouze výchozí nastavení, když je coverage.provider
'v8'
.
Odstranění možnosti watchExclude
Vitest používá sledovač Vite. Vylučte soubory nebo adresáře přidáním do server.watch.ignored
:
export default defineConfig({
server: {
watch: {
ignored: ['!node_modules/examplejs'],
},
},
});
--segfault-retry
odstraněno
Se změnami výchozího fondu již tato možnost není potřeba. Pokud se setkáte s chybami segfault, zkuste přepnout na fond 'forks'
. Pokud problém přetrvává, otevřete prosím nový problém s reprodukcí.
Prázdný úkol v rámci sady byl odstraněn
Toto je změna v pokročilém task API. Dříve by procházení .suite
nakonec vedlo k prázdné interní sadě, která byla použita místo úkolu souboru.
Díky tomu je .suite
volitelný; pokud je úkol definován na nejvyšší úrovni, nebude mít sadu. Můžete se vrátit k vlastnosti .file
, která je nyní přítomna u všech úkolů (včetně samotného úkolu souboru, takže buďte opatrní, abyste nespadli do nekonečné rekurze).
Tato změna také odstraňuje soubor z expect.getState().currentTestName
a činí expect.getState().testPath
povinným.
task.meta
je přidáno do JSON reportéru
JSON reportér nyní zobrazuje task.meta
pro každý výsledek tvrzení.
Zjednodušené generické typy mockovacích funkcí (např. vi.fn<T>
, Mock<T>
)
Dříve vi.fn<TArgs, TReturn>
akceptovalo dva generické typy odděleně pro argumenty a návratovou hodnotu. Nyní je to zjednodušeno na přímé přijetí typu funkce vi.fn<T>
pro zjednodušení použití.
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();
Přístup k vyhodnoceným mock.results
Dříve Vitest vyhodnocoval hodnoty mock.results
, pokud funkce vrátila Promise. Nyní existuje samostatná vlastnost mock.settledResults
, která se vyplní pouze tehdy, když je vrácená Promise vyřešena nebo zamítnuta.
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'
S touto změnou také zavádíme nové matchery toHaveResolved*
podobné toHaveReturned
, pro usnadnění migrace, pokud jste dříve používali toHaveReturned
:
const fn = vi.fn().mockResolvedValueOnce('result');
await fn();
expect(fn).toHaveReturned('result');
expect(fn).toHaveResolved('result');
Režim prohlížeče
Režim prohlížeče Vitest prošel během beta cyklu mnoha změnami. O naší filozofii ohledně režimu prohlížeče si můžete přečíst na diskuzní stránce GitHubu.
Většina změn byla doplňková, ale došlo k několika malým změnám způsobujícím nekompatibilitu:
- Poskytovatel
none
byl přejmenován napreview
#5842 - Poskytovatel
preview
je nyní výchozí #5842 indexScripts
je přejmenováno naorchestratorScripts
#5842
Odstraněné zastaralé možnosti
Některé zastaralé možnosti byly odstraněny:
- příkaz
vitest typecheck
– místo toho použijtevitest --typecheck
- proměnné prostředí
VITEST_JUNIT_CLASSNAME
aVITEST_JUNIT_SUITE_NAME
(místo toho použijte možnosti reportéru) - kontrola pokrytí
c8
(místo toho použijte coverage-v8) - export
SnapshotEnvironment
zvitest
– místo toho jej importujte zvitest/snapshot
SpyInstance
je odstraněno ve prospěchMockInstance
Migrace na Vitest 1.0
Minimální požadavky
Vitest 1.0 vyžaduje Vite 5.0 a Node.js 18 nebo vyšší.
Všechny podbalíčky @vitest/*
vyžadují Vitest verze 1.0.
Aktualizace snapshotů #3961
Uvozovky ve snapshotách již nejsou escapovány a všechny snapshoty používají zpětné apostrofy (`) i v případě, že se jedná pouze o jeden řádek.
- Uvozovky již nejsou escapovány:
expect({ foo: 'bar' }).toMatchInlineSnapshot(`
Object {
- \\"foo\\": \\"bar\\",
+ "foo": "bar",
}
`)
- Jednořádkové snapshoty nyní používají uvozovky "`" místo ':
- expect('some string').toMatchInlineSnapshot('"some string"')
+ expect('some string').toMatchInlineSnapshot(`"some string"`)
Došlo také ke změnám v balíčku @vitest/snapshot
. Pokud jej nepoužíváte přímo, nemusíte nic měnit.
- Již nemusíte rozšiřovat
SnapshotClient
jen proto, abyste přepsali metoduequalityCheck
: stačí ji předat jakoisEqual
při vytváření instance client.setTest
bylo přejmenováno naclient.startCurrentRun
client.resetCurrent
bylo přejmenováno naclient.finishCurrentRun
Pooly jsou standardizovány #4172
Odstranili jsme mnoho konfiguračních možností, abychom zjednodušili konfiguraci runneru podle vašich potřeb. Podívejte se prosím na příklady migrace, pokud se spoléháte na --threads
nebo jiné související příznaky.
--threads
je nyní--pool=threads
--no-threads
je nyní--pool=forks
--single-thread
je nyní--poolOptions.threads.singleThread
--experimental-vm-threads
je nyní--pool=vmThreads
--experimental-vm-worker-memory-limit
je nyní--poolOptions.vmThreads.memoryLimit
--isolate
je nyní--poolOptions.<pool-name>.isolate
abrowser.isolate
test.maxThreads
je nynítest.poolOptions.<pool-name>.maxThreads
test.minThreads
je nynítest.poolOptions.<pool-name>.minThreads
test.useAtomics
je nynítest.poolOptions.<pool-name>.useAtomics
test.poolMatchGlobs.child_process
je nynítest.poolMatchGlobs.forks
test.poolMatchGlobs.experimentalVmThreads
je nyní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"
}
}
Změny v pokrytí #4265, #4442
Možnost coverage.all
je nyní ve výchozím nastavení povolena. To znamená, že všechny soubory projektu odpovídající vzoru coverage.include
budou zpracovány, i když nebudou spuštěny.
Struktura API prahových hodnot pokrytí byla změněna a nyní podporuje specifikaci prahových hodnot pro konkrétní soubory pomocí glob vzorů:
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,
+ }
}
}
})
Typy mocků #4400
Několik typů bylo odstraněno a nahrazeno názvy "Mock" ve stylu Jest.
- import { EnhancedSpy, SpyInstance } from 'vitest'
+ import { MockInstance } from 'vitest'
WARNING
SpyInstance
je zastaralé ve prospěch MockInstance
a bude odstraněno v příští hlavní verzi.
Mockování časovačů #3925
vi.useFakeTimers()
již automaticky nemockuje process.nextTick
. Stále je možné mockovat process.nextTick
explicitním zadáním pomocí vi.useFakeTimers({ toFake: ['nextTick'] })
.
Mockování process.nextTick
však není možné při použití --pool=forks
. Pokud potřebujete mockování process.nextTick
, použijte jinou možnost --pool
.
Migrace z Jestu
Vitest byl navržen s API kompatibilním s Jestem, aby byla migrace z Jestu co nejjednodušší. Navzdory těmto snahám se stále můžete setkat s následujícími rozdíly:
Globální proměnné jako výchozí
Jest má své globální API ve výchozím nastavení povoleno. Vitest však nikoli. Můžete buď povolit globální proměnné pomocí nastavení konfigurace globals
, nebo aktualizovat svůj kód tak, aby místo toho používal importy z modulu vitest
.
Pokud se rozhodnete ponechat globální proměnné zakázané, mějte na paměti, že běžné knihovny jako testing-library
nebudou provádět automatický úklid DOM.
Mockování modulů
Při mockování modulu v Jestu je návratová hodnota argumentu factory výchozí export. Ve Vitestu musí argument factory vrátit objekt, kde je každý export explicitně definován. Například následující jest.mock
by musel být aktualizován takto:
jest.mock('./some-path', () => 'hello');
vi.mock('./some-path', () => ({
default: 'hello',
}));
Pro více podrobností se prosím podívejte na sekci API vi.mock
.
Chování automatického mockování
Na rozdíl od Jestu se mockované moduly v <root>/__mocks__
nenačítají, pokud není voláno vi.mock()
. Pokud je chcete mockovat v každém testu, stejně jako v Jestu, můžete je mockovat uvnitř setupFiles
.
Importování originálu mockovaného balíčku
Pokud mockujete balíček pouze částečně, pokud jste dříve používali funkci requireActual
z Jestu, ve Vitestu byste měli tyto volání nahradit vi.importActual
.
const { cloneDeep } = jest.requireActual('lodash/cloneDeep');
const { cloneDeep } = await vi.importActual('lodash/cloneDeep');
Rozšíření mockování pro externí knihovny
Zatímco Jest to dělá ve výchozím nastavení, při mockování modulu a jeho rozšíření na jiné externí knihovny, které používají stejný modul, byste měli explicitně uvést, kterou knihovnu třetí strany chcete mockovat. Tím zajistíte, že externí knihovna bude zpracována jako součást vašeho zdrojového kódu, a to pomocí server.deps.inline.
server.deps.inline: ["lib-name"]
expect.getState().currentTestName
Názvy testů ve Vitestu jsou spojeny symbolem >
pro snazší rozlišení testů od sad, zatímco Jest používá prázdnou mezeru ().
- `${describeTitle} ${testTitle}`
+ `${describeTitle} > ${testTitle}`
Proměnné prostředí
Stejně jako Jest, Vitest nastaví NODE_ENV
na test
, pokud nebyl nastaven dříve. Vitest má také protějšek pro JEST_WORKER_ID
nazvaný VITEST_POOL_ID
(vždy menší nebo roven maxThreads
), takže pokud se na něj spoléháte, nezapomeňte jej přejmenovat. Vitest také zpřístupňuje VITEST_WORKER_ID
, což je unikátní ID běžícího workeru – toto číslo není ovlivněno maxThreads
a bude se zvyšovat s každým vytvořeným workerem.
Nahrazení vlastnosti
Pokud chcete upravit objekt, v Jestu použijete replaceProperty API. Ve Vitestu k tomu můžete použít vi.stubEnv
nebo vi.spyOn
.
Done Callback
Od verze Vitest 0.10.0 je styl deklarování testů pomocí callbacků zastaralý. Můžete je přepsat tak, aby používaly funkce async
/await
, nebo použít Promise k simulaci stylu callbacků.
it('should work', (done) => { // [!code --]
it('should work', () => new Promise(done => { // [!code ++]
// ...
done()
}) // [!code --]
})) // [!code ++]
Hooky
Hooky beforeAll
/beforeEach
mohou ve Vitestu vracet teardown funkci. Z tohoto důvodu možná budete muset přepsat definice vašich hooků, pokud vracejí něco jiného než undefined
nebo null
:
beforeEach(() => setActivePinia(createTestingPinia()));
beforeEach(() => {
setActivePinia(createTestingPinia());
});
V Jestu jsou hooky volány sekvenčně (jeden po druhém). Ve výchozím nastavení Vitest spouští hooky paralelně. Chcete-li použít chování Jestu, aktualizujte možnost sequence.hooks
:
export default defineConfig({
test: {
sequence: {
hooks: 'list',
},
},
});
Typy
Vitest nemá ekvivalent k jmennému prostoru jest
, takže budete muset importovat typy přímo z vitest
:
let fn: jest.Mock<(name: string) => number>;
import type { Mock } from 'vitest';
let fn: Mock<(name: string) => number>;
Časovače
Vitest nepodporuje starší časovače Jestu.
Timeout
Pokud jste používali jest.setTimeout
, budete muset migrovat na vi.setConfig
:
jest.setTimeout(5_000);
vi.setConfig({ testTimeout: 5_000 });
Vue snapshoty
Toto není funkce specifická pro Jest, ale pokud jste dříve používali Jest s vue-cli
presetem, budete muset nainstalovat balíček jest-serializer-vue
a použít ho uvnitř setupFiles:
import { defineConfig } from 'vite';
export default defineConfig({
test: {
setupFiles: ['./tests/unit/setup.js'],
},
});
import vueSnapshotSerializer from 'jest-serializer-vue';
expect.addSnapshotSerializer(vueSnapshotSerializer);
Jinak budou vaše snapshoty obsahovat mnoho escapovaných uvozovek "
.