測試環境
Vitest 提供 environment
選項,讓您可以在特定環境中執行程式碼。您可以使用 environmentOptions
選項來調整環境行為。
預設情況下,您可以使用以下環境:
node
為預設環境。jsdom
透過jsdom
套件模擬瀏覽器環境,並提供瀏覽器 API。happy-dom
透過happy-dom
套件模擬瀏覽器環境,其速度通常比jsdom
快,但可能缺少部分 API。edge-runtime
透過@edge-runtime/vm
套件模擬 Vercel 的 edge-runtime。
INFO
當使用 jsdom
或 happy-dom
環境時,Vitest 在匯入 CSS 和 資源 時,遵循與 Vite 相同的規則。若在匯入外部依賴項時遇到 unknown extension .css
錯誤,您需要手動將所有相關套件新增至 server.deps.external
,以確保整個匯入鏈被內嵌處理。例如,若錯誤發生在 source code -> package-1 -> package-2 -> package-3
這條匯入鏈中的 package-3
,您需要將 package-1
、package-2
和 package-3
都新增到 server.deps.external
。
外部依賴項中 CSS 和資源的 require
語法會被自動解析。
特定檔案的環境
當您在設定中配置 environment
選項時,它會應用於專案中的所有測試檔案。為了更精確地控制,您可以使用控制註解來為特定檔案指定環境。控制註解以 @vitest-environment
開頭,後接環境名稱:
// @vitest-environment jsdom
import { expect, test } from 'vitest';
test('test', () => {
expect(typeof window).not.toBe('undefined');
});
此外,您也可以設定 environmentMatchGlobs
選項,根據 glob 模式來指定環境。
自訂環境
您可以建立自己的套件來擴充 Vitest 環境。為此,請建立一個名稱為 vitest-environment-${name}
的套件,或指定一個有效的 JS/TS 檔案路徑。該套件應匯出一個符合 Environment
型別的物件:
import type { Environment } from 'vitest/environments';
export default <Environment>{
name: 'custom',
transformMode: 'ssr',
// 可選 - 僅當您支援 "experimental-vm" 池時
async setupVM() {
const vm = await import('node:vm');
const context = vm.createContext();
return {
getVmContext() {
return context;
},
teardown() {
// 在所有使用此環境的測試執行完畢後呼叫
},
};
},
setup() {
// 自訂設定
return {
teardown() {
// 在所有使用此環境的測試執行完畢後呼叫
},
};
},
};
WARNING
Vitest 要求環境物件必須包含 transformMode
選項。其值應為 ssr
或 web
。此值決定了插件如何轉換原始碼。如果設定為 ssr
,插件鉤子在轉換或解析檔案時會收到 ssr: true
。否則,ssr
會設定為 false
。
您也可以透過 vitest/environments
入口存取預設的 Vitest 環境:
import { builtinEnvironments, populateGlobal } from 'vitest/environments';
console.log(builtinEnvironments); // { jsdom, happy-dom, node, edge-runtime }
Vitest 也提供了 populateGlobal
工具函式,可用於將物件的屬性移動到全域命名空間:
interface PopulateOptions {
// 非類別函式是否應綁定至全域命名空間
bindFunctions?: boolean;
}
interface PopulateResult {
// 所有已複製的鍵的列表,即使原始物件上不存在對應的值。
keys: Set<string>;
// 原始物件的對映,其中某些鍵可能已被覆寫。
// 您可以在 `teardown` 函式中傳回這些值。
originals: Map<string | symbol, any>;
}
export function populateGlobal(
global: any,
original: any,
options: PopulateOptions
): PopulateResult;