Funkcje
- Konfiguracja, transformatory, resolvery i wtyczki Vite
- Wykorzystanie tej samej konfiguracji aplikacji do uruchamiania testów.
- Inteligentny i natychmiastowy tryb obserwacji, podobny do HMR dla testów.
- Testowanie komponentów dla Vue, React, Svelte, Lit, Marko i innych.
- Natywna obsługa TypeScript i JSX.
- Priorytet dla ESM, top-level await.
- Wielowątkowość za pomocą workerów poprzez Tinypool.
- Obsługa benchmarkingu przy użyciu Tinybench.
- Filtrowanie, limity czasu i współbieżność dla zestawów testowych.
- Obsługa workspace'ów.
- Snapshoty kompatybilne z Jest.
- Chai wbudowany w asercje + API kompatybilne z Jest expect.
- Tinyspy wbudowany w mockowanie.
- happy-dom lub jsdom do mockowania DOM-u.
- Tryb przeglądarki do uruchamiania testów komponentów w przeglądarce.
- Pokrycie kodu za pomocą v8 lub istanbul.
- Testowanie w źródle, podobne do testów modułów w Rust in-source testing.
- Testowanie typów za pomocą expect-type.
- Obsługa shardingu.
Wspólna konfiguracja dla testów, środowiska deweloperskiego i kompilacji
Vitest wykorzystuje konfigurację, transformatory, resolvery i wtyczki Vite. Dzięki temu możesz użyć tej samej konfiguracji z Twojej aplikacji do uruchamiania testów.
Dowiedz się więcej w sekcji Konfiguracja Vitest.
Tryb obserwacji
$ vitest
Kiedy modyfikujesz kod źródłowy lub pliki testowe, Vitest inteligentnie przeszukuje graf modułów i ponownie uruchamia tylko powiązane testy, działając podobnie do HMR w Vite!
vitest
domyślnie uruchamia się w trybie obserwacji
w środowisku deweloperskim i w trybie uruchamiania
w środowisku CI (gdy process.env.CI
jest obecne) w sposób inteligentny. Możesz użyć vitest watch
lub vitest run
, aby jawnie określić żądany tryb.
Uruchom Vitest z flagą --standalone
, aby działał w tle. Nie uruchomi żadnych testów, dopóki nie nastąpią w nich zmiany. Vitest nie uruchomi testów, jeśli kod źródłowy zostanie zmieniony, dopóki nie zostanie uruchomiony test, który ten kod źródłowy importuje.
Typowe idiomy webowe dostępne od razu
Natywna obsługa modułów ES / TypeScript / JSX / PostCSS.
Wątki
Domyślnie Vitest uruchamia pliki testowe w wielu procesach, używając node:child_process
poprzez Tinypool (lekkie rozwidlenie Piscina), co pozwala na jednoczesne uruchamianie testów. Jeśli chcesz jeszcze bardziej przyspieszyć swój zestaw testów, rozważ włączenie --pool=threads
, aby uruchamiać testy, używając node:worker_threads
(pamiętaj, że niektóre pakiety mogą nie działać z tą konfiguracją).
Aby uruchomić testy w pojedynczym wątku lub procesie, zobacz poolOptions
.
Vitest izoluje również środowisko każdego pliku, dzięki czemu zmiany środowiska w jednym pliku nie wpływają na inne. Izolację można wyłączyć, przekazując --no-isolate
do CLI (kosztem poprawności na rzecz wydajności uruchamiania).
Filtrowanie testów
Vitest oferuje wiele sposobów na zawężenie uruchamianych testów, aby przyspieszyć testowanie i umożliwić skupienie się na rozwoju.
Dowiedz się więcej o Filtrowaniu testów.
Uruchamianie testów współbieżnie
Użyj .concurrent
w kolejnych testach, aby uruchomić je równolegle.
import { describe, it } from 'vitest';
// Dwa testy oznaczone jako concurrent zostaną uruchomione równolegle
describe('suite', () => {
it('serial test', async () => {
/* ... */
});
it.concurrent('concurrent test 1', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 2', async ({ expect }) => {
/* ... */
});
});
Jeśli użyjesz .concurrent
w zestawie, każdy test w nim zostanie uruchomiony równolegle.
import { describe, it } from 'vitest';
// Wszystkie testy w tym zestawie zostaną uruchomione równolegle
describe.concurrent('suite', () => {
it('concurrent test 1', async ({ expect }) => {
/* ... */
});
it('concurrent test 2', async ({ expect }) => {
/* ... */
});
it.concurrent('concurrent test 3', async ({ expect }) => {
/* ... */
});
});
Możesz również użyć .skip
, .only
i .todo
z współbieżnymi zestawami i testami. Przeczytaj więcej w Dokumentacji API.
WARNING
Podczas uruchamiania testów współbieżnych, snapshoty i asercje muszą używać expect
z lokalnego kontekstu testowego, aby zapewnić prawidłowe przypisanie do testu.
Snapshot
Obsługa snapshotów kompatybilnych z Jest.
import { expect, it } from 'vitest';
it('renders correctly', () => {
const result = render();
expect(result).toMatchSnapshot();
});
Dowiedz się więcej w sekcji Snapshot.
Kompatybilność Chai i Jest expect
Chai jest wbudowany do asercji z API kompatybilnymi z Jest expect
.
Należy zauważyć, że jeśli używasz bibliotek zewnętrznych, które dodają matchery, ustawienie test.globals
na true
zapewni lepszą kompatybilność.
Mockowanie
Tinyspy jest wbudowany do mockowania z API kompatybilnymi z jest
, dostępnymi na obiekcie vi
.
import { expect, vi } from 'vitest';
const fn = vi.fn();
fn('hello', 1);
expect(vi.isMockFunction(fn)).toBe(true);
expect(fn.mock.calls[0]).toEqual(['hello', 1]);
fn.mockImplementation((arg: string) => arg);
fn('world', 2);
expect(fn.mock.results[1].value).toBe('world');
Vitest obsługuje zarówno happy-dom, jak i jsdom do mockowania DOM i API przeglądarki. Nie są one dostarczane z Vitest, będziesz musiał zainstalować je osobno:
$ npm i -D happy-dom
# lub
$ npm i -D jsdom
Następnie zmień opcję environment
w pliku konfiguracyjnym:
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
environment: 'happy-dom', // lub 'jsdom', 'node'
},
});
Dowiedz się więcej w sekcji Mockowanie.
Pokrycie kodu
Vitest obsługuje natywne pokrycie kodu za pomocą v8
oraz instrumentowane pokrycie kodu za pomocą istanbul
.
{
"scripts": {
"test": "vitest",
"coverage": "vitest run --coverage"
}
}
Dowiedz się więcej w sekcji Pokrycie.
Testowanie w źródle
Vitest zapewnia również sposób na uruchamianie testów w kodzie źródłowym wraz z implementacją, podobnie do testów modułów w Rust.
Dzięki temu testy współdzielą to samo domknięcie co implementacje i mogą testować prywatne stany bez eksportowania. Jednocześnie skraca to cykl informacji zwrotnej w procesie rozwoju.
// src/index.ts
// implementacja
export function add(...args: number[]): number {
return args.reduce((a, b) => a + b, 0);
}
// zestawy testów w źródle
if (import.meta.vitest) {
const { it, expect } = import.meta.vitest;
it('add', () => {
expect(add()).toBe(0);
expect(add(1)).toBe(1);
expect(add(1, 2, 3)).toBe(6);
});
}
Dowiedz się więcej w sekcji Testowanie w źródle.
Benchmarking Eksperymentalne
Możesz uruchamiać testy wydajnościowe za pomocą funkcji bench
z wykorzystaniem Tinybench, aby porównać wyniki wydajności.
import { bench, describe } from 'vitest';
describe('sort', () => {
bench('normal', () => {
const x = [1, 5, 4, 2, 3];
x.sort((a, b) => {
return a - b;
});
});
bench('reverse', () => {
const x = [1, 5, 4, 2, 3];
x.reverse().sort((a, b) => {
return a - b;
});
});
});
Testowanie typów Eksperymentalne
Możesz pisać testy, aby wyłapywać regresje typów. Vitest zawiera pakiet expect-type
, aby zapewnić podobne i łatwe do zrozumienia API.
import { assertType, expectTypeOf, test } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name is a string
assertType(mount({ name: 42 }));
});
Sharding
Uruchamiaj testy na różnych maszynach, używając flag --shard
i --reporter=blob
. Wszystkie wyniki testów i pokrycia mogą zostać połączone na końcu potoku CI za pomocą polecenia --merge-reports
:
vitest --shard=1/2 --reporter=blob
vitest --shard=2/2 --reporter=blob
vitest --merge-reports --reporter=junit --coverage.reporter=text
Więcej informacji znajdziesz w Poprawa wydajności | Sharding
.
Zmienne środowiskowe
Vitest automatycznie ładuje zmienne środowiskowe z prefiksem VITE_
z plików .env
, aby zachować kompatybilność z testami związanymi z frontendem, zgodnie z przyjętą konwencją Vite. Aby załadować wszystkie zmienne środowiskowe z plików .env
, możesz użyć metody loadEnv
importowanej z pakietu vite
:
import { loadEnv } from 'vite';
import { defineConfig } from 'vitest/config';
export default defineConfig(({ mode }) => ({
test: {
// tryb określa, który plik ".env.{mode}" zostanie wybrany, jeśli istnieje
env: loadEnv(mode, process.cwd(), ''),
},
}));