Test Ortamı
Playwright Fixtures'tan ilham alan Vitest'in test ortamı, testlerinizde kullanılabilecek yardımcı programlar, durumlar ve fikstürler tanımlamanıza olanak tanır.
Kullanım
Her test geri çağrısının ilk argümanı bir test ortamıdır.
import { it } from 'vitest';
it('should work', ({ task }) => {
// testin adını yazdırır
console.log(task.name);
});
Yerleşik Test Ortamı
task
Test hakkında meta veri içeren salt okunur bir nesne.
expect
Mevcut teste bağlı expect
API'si:
import { it } from 'vitest';
it('math is easy', ({ expect }) => {
expect(2 + 2).toBe(4);
});
Bu API, anlık görüntü testlerini eşzamanlı olarak çalıştırmak için kullanışlıdır çünkü genel expect
bunları izleyemez:
import { it } from 'vitest';
it.concurrent('math is easy', ({ expect }) => {
expect(2 + 2).toMatchInlineSnapshot();
});
it.concurrent('math is hard', ({ expect }) => {
expect(2 * 2).toMatchInlineSnapshot();
});
skip
function skip(note?: string): never;
function skip(condition: boolean, note?: string): void;
Sonraki test yürütmesini atlar ve testi atlandı olarak işaretler:
import { expect, it } from 'vitest';
it('math is hard', ({ skip }) => {
skip();
expect(2 + 2).toBe(5);
});
Vitest 3.1'den beri, testi koşullu olarak atlamak için bir boolean parametresi kabul eder:
it('math is hard', ({ skip, mind }) => {
skip(mind === 'foggy');
expect(2 + 2).toBe(5);
});
annotate
3.2.0+
function annotate(
message: string,
attachment?: TestAttachment
): Promise<TestAnnotation>;
function annotate(
message: string,
type?: string,
attachment?: TestAttachment
): Promise<TestAnnotation>;
Raporlayıcınız tarafından görüntülenecek bir test açıklaması ekleyin.
test('annotations API', async ({ annotate }) => {
await annotate('https://github.com/vitest-dev/vitest/pull/7953', 'issues');
});
signal
3.2.0+
Vitest tarafından iptal edilebilen bir AbortSignal
nesnesidir. Sinyal şu durumlarda iptal edilir:
- Test zaman aşımına uğrar.
- Kullanıcı test çalıştırmasını Ctrl+C ile manuel olarak iptal etti.
vitest.cancelCurrentRun
programlı olarak çağrıldı.- Paralel olarak başka bir test başarısız oldu ve
bail
bayrağı ayarlandı.
it('stop request when test times out', async ({ signal }) => {
await fetch('/resource', { signal });
}, 2000);
onTestFailed
Mevcut teste bağlı onTestFailed
kancası. Bu API, testleri eşzamanlı olarak çalıştırıyorsanız ve yalnızca bu belirli test için özel bir durum yönetimi yapmanız gerekiyorsa kullanışlıdır.
onTestFinished
Mevcut teste bağlı onTestFinished
kancası. Bu API, testleri eşzamanlı olarak çalıştırıyorsanız ve yalnızca bu belirli test için özel bir durum yönetimi yapmanız gerekiyorsa kullanışlıdır.
Test Ortamını Genişletme
Vitest, test ortamını genişletmenize yardımcı olacak iki farklı yol sunar.
test.extend
Playwright gibi, bu yöntemi kendi test
API'nizi özel fikstürlerle tanımlamak ve her yerde yeniden kullanmak için kullanabilirsiniz.
Örneğin, önce iki fikstürle (todos
ve archive
) test
toplayıcısını oluştururuz.
import { test as baseTest } from 'vitest';
const todos = [];
const archive = [];
export const test = baseTest.extend({
todos: async ({}, use) => {
// her test fonksiyonundan önce fikstürü ayarla
todos.push(1, 2, 3);
// fikstür değerini kullan
await use(todos);
// her test fonksiyonundan sonra fikstürü temizle
todos.length = 0;
},
archive,
});
Sonra onu içe aktarabilir ve kullanabiliriz.
import { expect } from 'vitest';
import { test } from './my-test.js';
test('add items to todos', ({ todos }) => {
expect(todos.length).toBe(3);
todos.push(4);
expect(todos.length).toBe(4);
});
test('move items from todos to archive', ({ todos, archive }) => {
expect(todos.length).toBe(3);
expect(archive.length).toBe(0);
archive.push(todos.pop());
expect(todos.length).toBe(2);
expect(archive.length).toBe(1);
});
Ayrıca test
'imizi genişleterek daha fazla fikstür ekleyebilir veya mevcut fikstürleri geçersiz kılabiliriz.
import { test as todosTest } from './my-test.js';
export const test = todosTest.extend({
settings: {
// ...
},
});
Fikstür Başlatma
Vitest çalıştırıcısı, fikstürlerinizi akıllıca başlatacak ve kullanıma göre test ortamına enjekte edecektir.
import { test as baseTest } from 'vitest';
const test = baseTest.extend<{
todos: number[];
archive: number[];
}>({
todos: async ({ task }, use) => {
await use([1, 2, 3]);
},
archive: [],
});
// todos çalışmayacak
test('skip', () => {});
test('skip', ({ archive }) => {});
// todos çalışacak
test('run', ({ todos }) => {});
WARNING
test.extend()
'i fikstürlerle kullanırken, hem fikstür fonksiyonunda hem de test fonksiyonunda ortama erişmek için her zaman { todos }
nesne ayrıştırma desenini kullanmalısınız.
test('context must be destructured', (context) => {
expect(context.todos.length).toBe(2)
})
test('context must be destructured', ({ todos }) => {
expect(todos.length).toBe(2)
})
Otomatik Fikstür
Vitest ayrıca fikstürler için tuple sözdizimini de destekler ve her fikstür için seçenekler geçirmenize olanak tanır. Örneğin, bir fikstürü, testlerde kullanılmasa bile açıkça başlatmak için kullanabilirsiniz.
import { test as base } from 'vitest';
const test = base.extend({
fixture: [
async ({}, use) => {
// bu fonksiyon çalışacak
setup();
await use();
teardown();
},
{ auto: true }, // Otomatik fikstür olarak işaretle
],
});
test('works correctly');
Varsayılan Fikstür
Vitest 3'ten beri, farklı projelerde farklı değerler sağlayabilirsiniz. Bu özelliği etkinleştirmek için, seçeneklere { injected: true }
geçirin. Anahtar proje yapılandırmasında belirtilmemişse, varsayılan değer kullanılacaktır.
import { test as base } from 'vitest';
const test = base.extend({
url: [
// yapılandırmada "url" tanımlanmamışsa varsayılan değer
'/default',
// geçersiz kılmaya izin vermek için fikstürü "enjekte edilmiş" olarak işaretle
{ injected: true },
],
});
test('works correctly', ({ url }) => {
// "project-new" içinde url "/default"
// "project-full" içinde url "/full"
// "project-empty" içinde url "/empty"
});
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
name: 'project-new',
},
},
{
test: {
name: 'project-full',
provide: {
url: '/full',
},
},
},
{
test: {
name: 'project-empty',
provide: {
url: '/empty',
},
},
},
],
},
});
Süite Değerleri Kapsamlama 3.1.0+
Vitest 3.1'den beri, test.scoped
API'sini kullanarak süite ve alt öğelerine göre ortam değerlerini geçersiz kılabilirsiniz:
import { test as baseTest, describe, expect } from 'vitest';
const test = baseTest.extend({
dependency: 'default',
dependant: ({ dependency }, use) => use({ dependency }),
});
describe('use scoped values', () => {
test.scoped({ dependency: 'new' });
test('uses scoped value', ({ dependant }) => {
// `dependant`, bu süitteki tüm testlere kapsamlı olan yeni geçersiz kılınan değeri kullanır
expect(dependant).toEqual({ dependency: 'new' });
});
describe('keeps using scoped value', () => {
test('uses scoped value', ({ dependant }) => {
// iç içe süit değeri miras aldı
expect(dependant).toEqual({ dependency: 'new' });
});
});
});
test('keep using the default values', ({ dependant }) => {
// `dependency`, .scoped ile süitin dışında varsayılan değeri kullanıyor
expect(dependant).toEqual({ dependency: 'default' });
});
Bu API, bir veritabanı bağlantısı gibi dinamik bir değişkene dayanan bir ortam değeriniz varsa özellikle kullanışlıdır:
const test = baseTest.extend<{
db: Database;
schema: string;
}>({
db: async ({ schema }, use) => {
const db = await createDb({ schema });
await use(db);
await cleanup(db);
},
schema: '',
});
describe('one type of schema', () => {
test.scoped({ schema: 'schema-1' });
// ... testler
});
describe('another type of schema', () => {
test.scoped({ schema: 'schema-2' });
// ... testler
});
Kapsam Başına Ortam 3.2.0+
Dosya veya çalışan başına bir kez başlatılacak ortam tanımlayabilirsiniz. Nesne parametresiyle normal bir fikstürle aynı şekilde başlatılır:
import { test as baseTest } from 'vitest';
export const test = baseTest.extend({
perFile: [({}, { use }) => use([]), { scope: 'file' }],
perWorker: [({}, { use }) => use([]), { scope: 'worker' }],
});
Değer, herhangi bir testin ona ilk eriştiği anda başlatılır, fikstür seçeneklerinde auto: true
yoksa - bu durumda değer herhangi bir test çalışmadan önce başlatılır.
const test = baseTest.extend({
perFile: [
({}, { use }) => use([]),
{
scope: 'file',
// herhangi bir testten önce bu kancayı her zaman çalıştır
auto: true,
},
],
});
worker
kapsamı, fikstürü çalışan başına bir kez çalıştıracaktır. Çalışan çalışanların sayısı çeşitli faktörlere bağlıdır. Varsayılan olarak, her dosya ayrı bir çalışanda çalışır, bu nedenle file
ve worker
kapsamları aynı şekilde çalışır.
Ancak, izolasyonu devre dışı bırakırsanız, çalışanların sayısı maxWorkers
veya poolOptions
yapılandırmasıyla sınırlıdır.
vmThreads
veya vmForks
içinde testleri çalıştırırken scope: 'worker'
belirtmenin scope: 'file'
ile aynı şekilde çalışacağını unutmayın. Bu sınırlama, her test dosyasının kendi VM ortamına sahip olması nedeniyle mevcuttur, bu nedenle Vitest onu bir kez başlatacak olsaydı, bir ortam diğerine sızabilir ve birçok referans tutarsızlığı yaratabilirdi (aynı sınıfın örnekleri, örneğin farklı yapıcılara başvururdu).
TypeScript
Tüm özel ortamlarınız için fikstür türleri sağlamak için, fikstür türünü genel olarak geçirebilirsiniz.
interface MyFixtures {
todos: number[];
archive: number[];
}
const test = baseTest.extend<MyFixtures>({
todos: [],
archive: [],
});
test('types are defined correctly', ({ todos, archive }) => {
expectTypeOf(todos).toEqualTypeOf<number[]>();
expectTypeOf(archive).toEqualTypeOf<number[]>();
});
Tür Çıkarımı
use
fonksiyonu çağrıldığında Vitest'in türleri çıkarmayı desteklemediğini unutmayın. test.extend
çağrıldığında her zaman tüm ortam türünü genel tür olarak geçirmek tercih edilir:
import { test as baseTest } from 'vitest';
const test = baseTest.extend<{
todos: number[];
schema: string;
}>({
todos: ({ schema }, use) => use([]),
schema: 'test',
});
test('types are correct', ({
todos, // number[]
schema, // string
}) => {
// ...
});
beforeEach
ve afterEach
Kullanımdan Kaldırıldı
Bu, ortamı genişletmenin eski bir yoludur ve test
, test.extend
ile genişletildiğinde çalışmayacaktır.
Ortamlar her test için farklıdır. Bunlara beforeEach
ve afterEach
kancalarında erişebilir ve bunları genişletebilirsiniz.
import { beforeEach, it } from 'vitest';
beforeEach(async context => {
// ortamı genişlet
context.foo = 'bar';
});
it('should work', ({ foo }) => {
console.log(foo); // 'bar'
});
TypeScript
Tüm özel ortamlarınız için özellik türleri sağlamak isterseniz, TestContext
türünü ekleyerek genişletebilirsiniz:
declare module 'vitest' {
export interface TestContext {
foo?: string;
}
}
Yalnızca belirli beforeEach
, afterEach
, it
ve test
kancaları için özellik türleri sağlamak isterseniz, türü genel olarak geçirebilirsiniz.
interface LocalTestContext {
foo: string;
}
beforeEach<LocalTestContext>(async context => {
// context'in türü 'TestContext & LocalTestContext'
context.foo = 'bar';
});
it<LocalTestContext>('should work', ({ foo }) => {
// foo'nun türü 'string'
console.log(foo); // 'bar'
});