Files
openclaw/docs/plugins/sdk-testing.md
2026-03-22 08:50:48 -07:00

2.9 KiB

title, sidebarTitle, summary, read_when
title sidebarTitle summary read_when
Plugin SDK Testing Testing How to test plugin code with the public testing helpers and small local test doubles
You are writing tests for a plugin
You need fixtures for Windows command shims or shared routing failures
You want to know what the public testing surface includes

Plugin SDK Testing

OpenClaw keeps the public testing surface intentionally small.

Use openclaw/plugin-sdk/testing for helpers that are stable enough to support for plugin authors, and build small plugin-local doubles for everything else.

Public testing helpers

Current helpers include:

  • createWindowsCmdShimFixture(...)
  • installCommonResolveTargetErrorCases(...)
  • shouldAckReaction(...)
  • removeAckReactionAfterReply(...)

The testing surface also re-exports some shared types:

  • OpenClawConfig
  • PluginRuntime
  • RuntimeEnv
  • ChannelAccountSnapshot
  • ChannelGatewayContext

Example: Windows command shim fixture

import { createWindowsCmdShimFixture } from "openclaw/plugin-sdk/testing";
import { describe, expect, it } from "vitest";

describe("example CLI integration", () => {
  it("creates a command shim", async () => {
    await createWindowsCmdShimFixture({
      shimPath: "/tmp/example.cmd",
      scriptPath: "/tmp/example.js",
      shimLine: 'node "%~dp0\\example.js" %*',
    });

    expect(true).toBe(true);
  });
});

Example: shared target-resolution failures

import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/testing";

installCommonResolveTargetErrorCases({
  implicitAllowFrom: ["user-1"],
  resolveTarget({ to, mode, allowFrom }) {
    if (!to?.trim()) {
      return { ok: false, error: new Error("missing target") };
    }
    if (mode === "implicit" && allowFrom.length > 0 && to === "invalid-target") {
      return { ok: false, error: new Error("invalid target") };
    }
    return { ok: true, to };
  },
});

Runtime doubles

There is no catch-all createTestRuntime() export on the public SDK today. Instead:

  • use the public testing helpers where they fit
  • use plugin-sdk/runtime for small runtime adapters
  • build tiny plugin-local runtime doubles for the rest

Example:

import { createLoggerBackedRuntime } from "openclaw/plugin-sdk/runtime";

const logs: string[] = [];

const runtime = createLoggerBackedRuntime({
  logger: {
    info(message) {
      logs.push(`info:${message}`);
    },
    error(message) {
      logs.push(`error:${message}`);
    },
  },
});

Test guidance

  • Prefer focused unit tests over giant end-to-end harnesses.
  • Import pure types from focused SDK subpaths in tests.
  • Keep plugin-local test doubles small and explicit.
  • Avoid depending on non-exported OpenClaw test internals.