測試環境
Vitest 提供了 environment
選項,允許您在特定的環境中執行程式碼。您可以使用 environmentOptions
選項來調整這些環境的行為。
預設情況下,您可以使用以下環境:
node
:預設環境。jsdom
:透過提供瀏覽器 API 來模擬瀏覽器環境,使用jsdom
套件。happy-dom
:透過提供瀏覽器 API 來模擬瀏覽器環境,據稱比 jsdom 更快,但缺少一些 API,使用happy-dom
套件。edge-runtime
:模擬 Vercel 的 edge-runtime,使用@edge-runtime/vm
套件。
特定檔案的環境
在您的設定中設置 environment
選項時,該設定會應用於您專案中的所有測試檔案。若要更精確地控制,您可以使用控制註解來指定特定檔案的環境。控制註解以 @vitest-environment
開頭,後接環境名稱:
ts
// @vitest-environment jsdom
import { test } from 'vitest';
test('test', () => {
expect(typeof window).not.toBe('undefined');
});
或者,您也可以設定 environmentMatchGlobs
選項,根據 glob 模式指定環境。
自訂環境
自 0.23.0 起,您可以建立自己的套件來擴充 Vitest 環境。為此,請建立一個名為 vitest-environment-${name}
的套件,或者指定一個有效的 JS 檔案路徑(自 0.34.0 開始支援)。該套件應匯出一個符合 Environment
型別的物件:
ts
import type { Environment } from 'vitest';
export default <Environment>{
name: 'custom',
transformMode: 'ssr',
// optional - only if you support "experimental-vm" pool
async setupVM() {
const vm = await import('node:vm');
const context = vm.createContext();
return {
getVmContext() {
return context;
},
teardown() {
// called after all tests with this env have been run
},
};
},
setup() {
// custom setup
return {
teardown() {
// called after all tests with this env have been run
},
};
},
};
WARNING
自 0.34.0 起,Vitest 需要在環境物件上設置 transformMode
選項。它應該等於 ssr
或 web
。此值決定外掛程式如何轉換原始碼。如果設定為 ssr
,則外掛程式掛鉤在轉換或解析檔案時將收到 ssr: true
。否則,ssr
設定為 false
。
您還可以透過 vitest/environments
條目訪問預設的 Vitest 環境:
ts
import { builtinEnvironments, populateGlobal } from 'vitest/environments';
console.log(builtinEnvironments); // { jsdom, happy-dom, node, edge-runtime }
Vitest 還提供了 populateGlobal
實用函式,可用於將屬性從物件移動到全域命名空間:
ts
interface PopulateOptions {
// should non-class functions be bind to the global namespace
bindFunctions?: boolean;
}
interface PopulateResult {
// a list of all keys that were copied, even if value doesn't exist on original object
keys: Set<string>;
// a map of original object that might have been overridden with keys
// you can return these values inside `teardown` function
originals: Map<string | symbol, any>;
}
export function populateGlobal(
global: any,
original: any,
options: PopulateOptions
): PopulateResult;