Plugin SDK reference

Plugin のテスト

OpenClaw Plugin向けのテストユーティリティ、パターン、lint適用に関するリファレンスです。

テストユーティリティ

これらのサブパスは、OpenClaw独自のバンドル済みPluginテスト向けの、リポジトリローカルなソースエントリポイントです。サードパーティPlugin向けに公開されたpackage.jsonのエクスポートではなく、Vitestやその他のリポジトリ専用テスト依存関係をインポートする場合があります。

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

新しいバンドル済みPluginのテストでは、これらの目的別サブパスを優先してください。広範な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 直接登録のユニットテスト用に最小限のPlugin 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登録契約のチェックを導入します。plugin-sdk/plugin-test-contractsからインポートします
registerSingleProviderPlugin ローダーのスモークテストで1つのプロバイダーPluginを登録します。plugin-sdk/plugin-test-runtimeからインポートします
registerProviderPlugin 1つのPluginからすべてのプロバイダー種別をキャプチャします。plugin-sdk/plugin-test-runtimeからインポートします
registerProviderPlugins 複数のPluginにわたるプロバイダー登録をキャプチャします。plugin-sdk/plugin-test-runtimeからインポートします
requireRegisteredProvider プロバイダーコレクションに指定のIDが含まれていることをアサートします。plugin-sdk/plugin-test-runtimeからインポートします
createRuntimeEnv モック化されたCLI/Pluginランタイム環境を構築します。plugin-sdk/plugin-test-runtimeからインポートします
createPluginRuntimeMock モック化されたPluginランタイムサーフェスを構築します。plugin-sdk/plugin-test-runtimeからインポートします
createPluginSetupWizardStatus チャネルPlugin用のセットアップステータスヘルパーを構築します。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レジストリのフィクスチャを構築します。plugin-sdk/plugin-test-runtimeまたはplugin-sdk/channel-test-helpersからインポートします
createEmptyPluginRegistry 空のPluginレジストリフィクスチャを構築します。plugin-sdk/plugin-test-runtimeまたはplugin-sdk/channel-test-helpersからインポートします
setActivePluginRegistry Pluginランタイムテスト用のレジストリフィクスチャを導入します。plugin-sdk/plugin-test-runtimeまたはplugin-sdk/channel-test-helpersからインポートします
createRequestCaptureJsonFetch メディアヘルパーテストでJSON fetchリクエストをキャプチャします。plugin-sdk/test-envからインポートします
withServer 使い捨てのローカルHTTPサーバーに対してテストを実行します。plugin-sdk/test-envからインポートします
createMockIncomingRequest 最小限の受信HTTPリクエストオブジェクトを構築します。plugin-sdk/test-envからインポートします
withFetchPreconnect preconnectフックを導入した状態で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 テストでCLIランタイム出力をキャプチャします。plugin-sdk/test-fixturesからインポートします
importFreshModule モジュールキャッシュを回避するため、新しいクエリトークンを使用してESMモジュールをインポートします。plugin-sdk/test-fixturesからインポートします
bundledPluginRoot / bundledPluginFile バンドルされたPluginのソースまたは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 からインポートします

バンドル済みPluginのコントラクトスイートでも、テスト専用のレジストリ、マニフェスト、公開アーティファクト、ランタイムフィクスチャのヘルパーとして、これらのSDKテスト用サブパスを使用します。 一方、バンドル済みOpenClawインベントリに依存するコア専用スイートは、引き続き src/plugins/contracts に配置します。

特定用途向けのテスト用サブパスでは、テストファイルで役立つ型も再エクスポートされます。

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

テスト対象の解決

チャンネルの対象解決に標準的なエラーケースを追加するには、installCommonResolveTargetErrorCases を使用します。

typescript
  describe("my-channel target resolution", () => {  installCommonResolveTargetErrorCases({    resolveTarget: ({ to, mode, allowFrom }) => {      // チャンネル固有の対象解決ロジック      return myChannelResolveTarget({ to, mode, allowFrom });    },    implicitAllowFrom: ["user1", "user2"],  });   // チャンネル固有のテストケースを追加  it("should resolve @username targets", () => {    // ...  });});

テストパターン

登録コントラクトのテスト

手書きの api モックを register(api) に渡すユニットテストでは、OpenClawのローダー受け入れゲートを検証できません。Pluginが依存する各登録サーフェスに対して、ローダー経由のスモークテストを少なくとも1つ追加してください。特に、フックやメモリなどの排他的な機能では重要です。

必要なメタデータが欠けている場合や、Pluginが所有していない機能APIを呼び出した場合、実際のローダーではPluginの登録に失敗します。たとえば、 api.registerHook(...) にはフック名が必要であり、 api.registerMemoryCapability(...) には、Pluginマニフェストまたはエクスポートされたエントリで kind: "memory" を宣言する必要があります。

ランタイム設定アクセスのテスト

openclaw/plugin-sdk/plugin-test-runtime の共有Pluginランタイムモックを推奨します。 その runtime.config.loadConfig() および runtime.config.writeConfigFile(...) のモックはデフォルトで例外をスローするため、非推奨の互換性APIが新たに使用されるとテストで検出できます。テストがレガシー互換動作を明示的に検証する場合にのみ、これらのモックをオーバーライドしてください。

チャンネルPluginのユニットテスト

typescript
 describe("my-channel plugin", () => {  it("should resolve account from config", () => {    const cfg = {      channels: {        "my-channel": {          token: "test-token",          allowFrom: ["user1"],        },      },    };     const account = myPlugin.setup.resolveAccount(cfg, undefined);    expect(account.token).toBe("test-token");  });   it("should inspect account without materializing secrets", () => {    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");  });});

プロバイダーPluginのユニットテスト

typescript
 describe("my-provider plugin", () => {  it("should resolve dynamic models", () => {    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("should return catalog when API key is available", async () => {    const result = await myProvider.catalog.run({      resolveProviderApiKey: () => ({ apiKey: "test-key" }),      // ... コンテキスト    });     expect(result?.provider?.models).toHaveLength(2);  });});

Pluginランタイムのモック

createPluginRuntimeStore を使用するコードでは、テスト内でランタイムをモックします。

typescript
  const store = createPluginRuntimeStore<PluginRuntime>({  pluginId: "test-plugin",  errorMessage: "test runtime not set",}); // テストのセットアップ内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();

コントラクトテスト(リポジトリ内Plugin)

バンドル済みPluginには、登録の所有権を検証するコントラクトテストがあります。

bash
pnpm test src/plugins/contracts/

これらのテストでは、次の項目を検証します。

  • どのPluginがどのプロバイダーを登録するか
  • どのPluginがどの音声プロバイダーを登録するか
  • 登録形式の正しさ
  • ランタイムコントラクトへの準拠

スコープを限定したテストの実行

特定のPluginの場合:

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による適用(リポジトリ内Plugin)

scripts/run-additional-boundary-checks.mjs は、CIで一連の lint:plugins:* インポート境界チェックを実行します。各チェックはローカルでも単独で実行できます。

コマンド 適用内容
pnpm run lint:plugins:no-monolithic-plugin-sdk-entry-imports バンドル済みPluginは、モノリシックな openclaw/plugin-sdk ルートバレルをインポートできません。
pnpm run lint:plugins:no-extension-src-imports 本番用拡張ファイルは、リポジトリの src/** ツリーを直接インポートできません(../../src/...)。
pnpm run lint:plugins:no-extension-test-core-imports 拡張のテストファイルは、openclaw/plugin-sdk/testingplugin-sdk/test-utils、その他のコア専用テストヘルパーをインポートできません。

外部Pluginにはこれらのlintルールは適用されませんが、同じパターンに従うことを推奨します。

テスト設定

OpenClawは、参考情報としてV8カバレッジを報告するVitest 4を使用します。Pluginのテストでは、次のコマンドを使用します。

bash
# すべてのテストを実行pnpm test # 特定のPluginテストを実行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