Plugin SDK reference

外掛測試

OpenClaw 外掛的測試公用程式、模式與 lint 強制規則參考。

測試公用程式

這些子路徑是 OpenClaw 自有內建外掛測試在存放庫本機使用的原始碼進入點。它們並非為第三方外掛發布的 package.json 匯出,且可能會匯入 Vitest 或其他僅限存放庫使用的測試相依套件。

typescript
   shouldAckReaction,  removeAckReactionAfterReply,} from "openclaw/plugin-sdk/channel-feedback";               bundledPluginRoot,  createCliRuntimeCapture,  typedCases,} from "openclaw/plugin-sdk/test-fixtures"; 

內建外掛測試請使用這些聚焦的子路徑。先前的 openclaw/plugin-sdk/testing 彙總入口僅供存放庫本機使用,未包含在發布的套件中,現已移除。先前的 openclaw/plugin-sdk/test-utils 別名也隨之移除。pnpm run lint:plugins:no-extension-test-core-importsscripts/check-no-extension-test-core-imports.ts)會讓擴充功能測試繼續使用上述聚焦的測試子路徑。

可用的匯出

匯出項目 用途
createTestPluginApi 建立最小化的外掛 API 模擬,用於直接註冊單元測試。從 plugin-sdk/plugin-test-api 匯入
AUTH_PROFILE_RUNTIME_CONTRACT 原生代理程式執行階段介面卡共用的驗證設定檔契約測試資料。從 plugin-sdk/agent-runtime-test-contracts 匯入
DELIVERY_NO_REPLY_RUNTIME_CONTRACT 原生代理程式執行階段介面卡共用的傳遞抑制契約測試資料。從 plugin-sdk/agent-runtime-test-contracts 匯入
OUTCOME_FALLBACK_RUNTIME_CONTRACT 原生代理程式執行階段介面卡共用的後援分類契約測試資料。從 plugin-sdk/agent-runtime-test-contracts 匯入
createParameterFreeTool 建立動態工具結構描述測試資料,用於原生執行階段契約測試。從 plugin-sdk/agent-runtime-test-contracts 匯入
expectChannelInboundContextContract 斷言頻道傳入內容的形狀。從 plugin-sdk/channel-contract-testing 匯入
installChannelOutboundPayloadContractSuite 安裝頻道傳出承載資料契約測試案例。從 plugin-sdk/channel-contract-testing 匯入
createStartAccountContext 建立頻道帳號生命週期內容。從 plugin-sdk/channel-test-helpers 匯入
installChannelActionsContractSuite 安裝通用頻道訊息動作契約測試案例。從 plugin-sdk/channel-test-helpers 匯入
installChannelSetupContractSuite 安裝通用頻道設定契約測試案例。從 plugin-sdk/channel-test-helpers 匯入
installChannelStatusContractSuite 安裝通用頻道狀態契約測試案例。從 plugin-sdk/channel-test-helpers 匯入
expectDirectoryIds 從目錄清單函式斷言頻道目錄 ID。從 plugin-sdk/channel-test-helpers 匯入
assertBundledChannelEntries 斷言隨附頻道進入點公開預期的公用契約。從 plugin-sdk/channel-test-helpers 匯入
formatEnvelopeTimestamp 格式化具確定性的封套時間戳記。從 plugin-sdk/channel-test-helpers 匯入
expectPairingReplyText 斷言頻道配對回覆文字並擷取其代碼。從 plugin-sdk/channel-test-helpers 匯入
describePluginRegistrationContract 安裝外掛註冊契約檢查。從 plugin-sdk/plugin-test-contracts 匯入
registerSingleProviderPlugin 在載入器冒煙測試中註冊一個供應商外掛。從 plugin-sdk/plugin-test-runtime 匯入
registerProviderPlugin 從一個外掛擷取所有供應商種類。從 plugin-sdk/plugin-test-runtime 匯入
registerProviderPlugins 擷取多個外掛的供應商註冊項目。從 plugin-sdk/plugin-test-runtime 匯入
requireRegisteredProvider 斷言供應商集合包含某個 ID。從 plugin-sdk/plugin-test-runtime 匯入
createRuntimeEnv 建立模擬的命令列介面/外掛執行階段環境。從 plugin-sdk/plugin-test-runtime 匯入
createPluginRuntimeMock 建立模擬的外掛執行階段介面。從 plugin-sdk/plugin-test-runtime 匯入
createPluginSetupWizardStatus 為頻道外掛建立設定狀態輔助工具。從 plugin-sdk/plugin-test-runtime 匯入
createTestWizardPrompter 建立模擬的設定精靈提示器。從 plugin-sdk/plugin-test-runtime 匯入
createRuntimeTaskFlow 建立隔離的執行階段 TaskFlow 狀態。從 plugin-sdk/plugin-test-runtime 匯入
runProviderCatalog 使用測試相依項目執行供應商目錄鉤子。從 plugin-sdk/plugin-test-runtime 匯入
resolveProviderWizardOptions 在契約測試中解析供應商設定精靈選項。從 plugin-sdk/plugin-test-runtime 匯入
resolveProviderModelPickerEntries 在契約測試中解析供應商模型選擇器項目。從 plugin-sdk/plugin-test-runtime 匯入
buildProviderPluginMethodChoice 建立供應商精靈選項 ID 以供斷言。從 plugin-sdk/plugin-test-runtime 匯入
setProviderWizardProvidersResolverForTest 為隔離測試注入供應商精靈的供應商。從 plugin-sdk/plugin-test-runtime 匯入
describeOpenAIProviderRuntimeContract 安裝供應商系列執行階段契約檢查。從 plugin-sdk/provider-test-contracts 匯入
expectPassthroughReplayPolicy 斷言供應商重播原則會傳遞供應商自有的工具與中繼資料。從 plugin-sdk/provider-test-contracts 匯入
runRealtimeSttLiveTest 使用共用音訊測試資料執行即時 STT 供應商實機測試。從 plugin-sdk/provider-test-contracts 匯入
normalizeTranscriptForMatch 在模糊斷言前正規化實機轉錄輸出。從 plugin-sdk/provider-test-contracts 匯入
expectExplicitVideoGenerationCapabilities 斷言影片供應商明確宣告生成模式功能。從 plugin-sdk/provider-test-contracts 匯入
expectExplicitMusicGenerationCapabilities 斷言音樂供應商明確宣告生成/編輯功能。從 plugin-sdk/provider-test-contracts 匯入
mockSuccessfulDashscopeVideoTask 安裝成功的 DashScope 相容影片任務回應。從 plugin-sdk/provider-test-contracts 匯入
getProviderHttpMocks 存取選擇啟用的供應商 HTTP/驗證 Vitest 模擬。從 plugin-sdk/provider-http-test-mocks 匯入
installProviderHttpMockCleanup 在每項測試後重設供應商 HTTP/驗證模擬。從 plugin-sdk/provider-http-test-mocks 匯入
installCommonResolveTargetErrorCases 目標解析錯誤處理的共用測試案例。從 plugin-sdk/channel-target-testing 匯入
shouldAckReaction 檢查頻道是否應新增確認反應。從 plugin-sdk/channel-feedback 匯入
removeAckReactionAfterReply 回覆傳遞後移除確認反應。從 plugin-sdk/channel-feedback 匯入
createTestRegistry 建立頻道外掛登錄測試資料。從 plugin-sdk/plugin-test-runtimeplugin-sdk/channel-test-helpers 匯入
createEmptyPluginRegistry 建立空的外掛登錄測試資料。從 plugin-sdk/plugin-test-runtimeplugin-sdk/channel-test-helpers 匯入
setActivePluginRegistry 為外掛執行階段測試安裝登錄測試資料。從 plugin-sdk/plugin-test-runtimeplugin-sdk/channel-test-helpers 匯入
createRequestCaptureJsonFetch 在媒體輔助工具測試中擷取 JSON fetch 請求。從 plugin-sdk/test-media-understanding 匯入
isLiveTestEnabled 控制選擇啟用的實機供應商測試。從 plugin-sdk/test-live 匯入
collectProviderApiKeys 探索實機供應商測試的認證資訊。從 plugin-sdk/test-live-auth 匯入
parseProviderModelMap 剖析音樂/影片實機測試的模型覆寫值。從 plugin-sdk/test-media-generation 匯入
withServer 對可拋棄的本機 HTTP 伺服器執行測試。從 plugin-sdk/test-env 匯入
createMockIncomingRequest 建立最小化的傳入 HTTP 請求物件。從 plugin-sdk/test-env 匯入
withFetchPreconnect 執行已安裝預連線鉤子的 fetch 測試。從 plugin-sdk/test-env 匯入
withEnv / withEnvAsync 暫時修補環境變數。從 plugin-sdk/test-env 匯入
createTempHomeEnv / withTempHome / withTempDir 建立隔離的檔案系統測試資料。從 plugin-sdk/test-env 匯入
createMockServerResponse 建立最小化的 HTTP 伺服器回應模擬。從 plugin-sdk/test-env 匯入
createProviderUsageFetch 建立供應商用量 fetch 測試資料。從 plugin-sdk/test-env 匯入
useFrozenTime / useRealTime 凍結並還原計時器,用於時間敏感的測試。從 plugin-sdk/test-env 匯入
createCliRuntimeCapture 在測試中擷取命令列介面執行階段輸出。從 plugin-sdk/test-fixtures 匯入
importFreshModule 使用新的查詢權杖匯入 ESM 模組,以略過模組快取。從 plugin-sdk/test-fixtures 匯入
bundledPluginRoot / bundledPluginFile 解析隨附外掛的原始碼或 dist 測試資料路徑。從 plugin-sdk/test-fixtures 匯入
mockNodeBuiltinModule 安裝範圍有限的 Node 內建 Vitest 模擬。從 plugin-sdk/test-node-mocks 匯入
createSandboxTestContext 建立沙箱測試內容。從 plugin-sdk/test-fixtures 匯入
writeSkill 寫入 Skills 測試資料。從 plugin-sdk/test-fixtures 匯入
makeAgentAssistantMessage 建立代理程式轉錄訊息測試資料。從 plugin-sdk/test-fixtures 匯入
peekSystemEvents / resetSystemEventsForTest 檢查並重設系統事件測試資料。從 plugin-sdk/test-fixtures 匯入
sanitizeTerminalText 清理終端輸出以供斷言。從 plugin-sdk/test-fixtures 匯入
countLines / hasBalancedFences 斷言分塊輸出的形狀。從 plugin-sdk/test-fixtures 匯入
typedCases 保留表格驅動測試的常值型別。從 plugin-sdk/test-fixtures 匯入

內建外掛的合約測試套件也會使用這些 SDK 測試子路徑,取得僅供測試使用的登錄檔、資訊清單、公開成品與執行階段固定資料輔助工具。 依賴內建 OpenClaw 清單的僅限核心測試套件則仍放在 src/plugins/contracts 下。

型別

聚焦測試的子路徑也會重新匯出測試檔案中實用的型別:

typescript
   ChannelAccountSnapshot,  ChannelGatewayContext,} from "openclaw/plugin-sdk/channel-contract";  

測試目標解析

使用 installCommonResolveTargetErrorCases 為頻道目標解析新增標準錯誤案例:

typescript
  describe("my-channel 目標解析", () => {  installCommonResolveTargetErrorCases({    resolveTarget: ({ to, mode, allowFrom }) => {      // 你的頻道目標解析邏輯      return myChannelResolveTarget({ to, mode, allowFrom });    },    implicitAllowFrom: ["user1", "user2"],  });   // 新增頻道特定的測試案例  it("應解析 @username 目標", () => {    // ...  });});

測試模式

測試註冊合約

將手寫的 api 模擬物件傳給 register(api) 的單元測試,不會 執行 OpenClaw 的載入器接受閘門。你的外掛所依賴的每個註冊介面都應至少新增一個由載入器支援的 冒煙測試,尤其是鉤子與記憶等專屬功能。

若缺少必要的中繼資料,或外掛呼叫不屬於自己的功能 API,真正的載入器會使外掛註冊失敗。例如, api.registerHook(...) 需要鉤子名稱,而 api.registerMemoryCapability(...) 要求外掛資訊清單或匯出的 進入點宣告 kind: "memory"

測試執行階段設定存取

優先使用 openclaw/plugin-sdk/plugin-test-runtime 的共用外掛執行階段模擬物件。其執行階段設定輔助工具會模擬 目前的快照與變更 API。

對頻道外掛進行單元測試

typescript
 describe("my-channel 外掛", () => {  it("應從設定解析帳號", () => {    const cfg = {      channels: {        "my-channel": {          token: "test-token",          allowFrom: ["user1"],        },      },    };     const account = myPlugin.setup.resolveAccount(cfg, undefined);    expect(account.token).toBe("test-token");  });   it("應檢查帳號而不具現化機密", () => {    const cfg = {      channels: {        "my-channel": { token: "test-token" },      },    };     const inspection = myPlugin.setup.inspectAccount(cfg, undefined);    expect(inspection.configured).toBe(true);    expect(inspection.tokenStatus).toBe("available");    // 未公開權杖值    expect(inspection).not.toHaveProperty("token");  });});

對供應商外掛進行單元測試

typescript
 describe("my-provider 外掛", () => {  it("應解析動態模型", () => {    const model = myProvider.resolveDynamicModel({      modelId: "custom-model-v2",      // ... 情境    });     expect(model.id).toBe("custom-model-v2");    expect(model.provider).toBe("my-provider");    expect(model.api).toBe("openai-completions");  });   it("當 API 金鑰可用時應傳回目錄", async () => {    const result = await myProvider.catalog.run({      resolveProviderApiKey: () => ({ apiKey: "test-key" }),      // ... 情境    });     expect(result?.provider?.models).toHaveLength(2);  });});

模擬外掛執行階段

對於使用 createPluginRuntimeStore 的程式碼,請在測試中模擬執行階段:

typescript
  const store = createPluginRuntimeStore<PluginRuntime>({  pluginId: "test-plugin",  errorMessage: "測試執行階段尚未設定",}); // 在測試設定中const mockRuntime = {  agent: {    resolveAgentDir: vi.fn().mockReturnValue("/tmp/agent"),    // ... 其他模擬物件  },  config: {    current: vi.fn(() => ({}) as const),    mutateConfigFile: vi.fn(),    replaceConfigFile: vi.fn(),  },  // ... 其他命名空間} as unknown as PluginRuntime; store.setRuntime(mockRuntime); // 測試後store.clearRuntime();

使用個別執行個體的虛設常式進行測試

優先使用個別執行個體的虛設常式,而不是修改原型:

typescript
// 建議:個別執行個體的虛設常式const client = new MyChannelClient();client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" }); // 避免:修改原型// MyChannelClient.prototype.sendMessage = vi.fn();

合約測試(存放於儲存庫內的外掛)

內建外掛具有驗證註冊所有權的合約測試:

bash
pnpm test src/plugins/contracts/

這些測試會斷言:

  • 哪些外掛註冊哪些供應商
  • 哪些外掛註冊哪些語音供應商
  • 註冊形式的正確性
  • 執行階段合約遵循情況

執行限定範圍的測試

針對特定外掛:

bash
pnpm test <bundled-plugin-root>/my-channel/

僅執行合約測試:

bash
pnpm test src/plugins/contracts/shape.contract.test.tspnpm test src/plugins/contracts/auth-choice.contract.test.tspnpm test src/plugins/contracts/runtime-seams.contract.test.ts

Lint 強制檢查(存放於儲存庫內的外掛)

scripts/run-additional-boundary-checks.mjs 會在 CI 中執行一組 lint:plugins:* 匯入邊界檢查;每項檢查也可以在本機獨立執行:

命令 強制規則
pnpm run lint:plugins:no-monolithic-plugin-sdk-entry-imports 內建外掛不得匯入單體式的 openclaw/plugin-sdk 根彙總模組。
pnpm run lint:plugins:no-extension-src-imports 正式環境的擴充功能檔案不得直接匯入儲存庫的 src/** 樹狀結構(../../src/...)。
pnpm run lint:plugins:no-extension-test-core-imports 擴充功能測試檔案不得匯入已移除的 SDK 測試別名或其他僅限核心使用的測試輔助工具。

外部外掛不受這些 lint 規則約束,但建議遵循相同的 模式。

測試設定

OpenClaw 使用 Vitest 4,並提供資訊用途的 V8 覆蓋率報告。針對外掛測試:

bash
# 執行所有測試pnpm test # 執行特定外掛測試pnpm test <bundled-plugin-root>/my-channel/src/channel.test.ts # 使用特定測試名稱篩選條件執行pnpm test <bundled-plugin-root>/my-channel/ -t "resolves account" # 執行並產生覆蓋率報告pnpm test:coverage

若本機執行造成記憶體壓力:

bash
OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test

相關內容

Was this useful?
On this page

On this page