跳到內容

測試背景

受到 Playwright Fixtures 的啟發,Vitest 的測試背景讓您可以在測試中定義實用程式、狀態和固定裝置。

用法

每個測試回呼的第一個參數都是測試內容。

ts
import {  } from 'vitest'

('should work', () => {
  // prints name of the test
  .(..)
})

內建測試內容

context.task

包含測試相關資料的唯讀物件。

context.expect

與目前測試關聯的 expect API

ts
import {  } from 'vitest'

('math is easy', ({  }) => {
  (2 + 2).(4)
})

此 API 可用於同時執行快照測試,因為全域性的 expect 無法追蹤它們

ts
import {  } from 'vitest'

.('math is easy', ({  }) => {
  (2 + 2).()
})

.('math is hard', ({  }) => {
  (2 * 2).()
})

context.skip

略過後續的測試執行,並將測試標記為略過

ts
import { expect, it } from 'vitest'

it('math is hard', ({ skip }) => {
  skip()
  expect(2 + 2).toBe(5)
})

延伸測試內容

Vitest 提供兩種不同的方式來協助您延伸測試內容。

test.extend

警告

此 API 自 Vitest 0.32.3 起提供。

Playwright 類似,您可以使用此方法定義自己的 test API,並搭配自訂固定裝置,並在任何地方重複使用。

例如,我們先使用兩個固定裝置(todosarchive)建立 myTest

ts
// my-test.ts
import { test } from 'vitest'

const todos = []
const archive = []

export const myTest = test.extend({
  todos: async ({}, use) => {
    // setup the fixture before each test function
    todos.push(1, 2, 3)

    // use the fixture value
    await use(todos)

    // cleanup the fixture after each test function
    todos.length = 0
  },
  archive
})

接著,我們可以匯入並使用它。

ts
import { expect } from 'vitest'
import { myTest } from './my-test.js'

myTest('add items to todos', ({ todos }) => {
  expect(todos.length).toBe(3)

  todos.push(4)
  expect(todos.length).toBe(4)
})

myTest('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)
})

我們也可以透過延伸 myTest 來新增更多固定裝置,或覆寫現有的固定裝置。

ts
export const myTest2 = myTest.extend({
  settings: {
    // ...
  }
})

固定裝置初始化

Vitest 執行器會根據使用情況智慧地初始化您的固定裝置,並將它們注入測試內容。

ts
import { test } from 'vitest'

async function todosFn({ task }, use) {
  await use([1, 2, 3])
}

const myTest = test.extend({
  todos: todosFn,
  archive: []
})

// todosFn will not run
myTest('', () => {})
myTest('', ({ archive }) => {})

// todosFn will run
myTest('', ({ todos }) => {})

警告

當使用 test.extend() 搭配固定裝置時,您應該始終使用物件解構模式 { todos } 來存取固定裝置函式和測試函式中的內容。

自動固定裝置

警告

此功能自 Vitest 1.3.0 起提供。

Vitest 也支援固定裝置的元組語法,讓您可以傳遞每個固定裝置的選項。例如,您可以使用它來明確初始化固定裝置,即使它未在測試中使用。

ts
import { test as base } from 'vitest'

const test = base.extend({
  fixture: [
    async ({}, use) => {
      // this function will run
      setup()
      await use()
      teardown()
    },
    { auto: true } // Mark as an automatic fixture
  ],
})

test('', () => {})

TypeScript

若要為所有自訂內容提供固定裝置類型,您可以將固定裝置類型傳遞為一般化。

ts
interface MyFixtures {
  todos: number[]
  archive: number[]
}

const myTest = test.extend<MyFixtures>({
  todos: [],
  archive: []
})

myTest('', (context) => {
  expectTypeOf(context.todos).toEqualTypeOf<number[]>()
  expectTypeOf(context.archive).toEqualTypeOf<number[]>()
})

beforeEachafterEach

每個測試的內容不同。您可以在 beforeEachafterEach 鉤子內存取和延伸它們。

ts
import { beforeEach, it } from 'vitest'

beforeEach(async (context) => {
  // extend context
  context.foo = 'bar'
})

it('should work', ({ foo }) => {
  console.log(foo) // 'bar'
})

TypeScript

若要為所有自訂內容提供屬性類型,您可以透過新增下列內容來彙總 TestContext 類型

ts
declare module 'vitest' {
  export interface TestContext {
    foo?: string
  }
}

如果您只想為特定的 beforeEachafterEachittest 鉤子提供屬性類型,您可以傳遞類型作為泛型。

ts
interface LocalTestContext {
  foo: string
}

beforeEach<LocalTestContext>(async (context) => {
  // typeof context is 'TestContext & LocalTestContext'
  context.foo = 'bar'
})

it<LocalTestContext>('should work', ({ foo }) => {
  // typeof foo is 'string'
  console.log(foo) // 'bar'
})