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

113 lines
2.9 KiB
Markdown

---
title: "Plugin SDK Testing"
sidebarTitle: "Testing"
summary: "How to test plugin code with the public testing helpers and small local test doubles"
read_when:
- 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
```ts
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
```ts
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:
```ts
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.
## Related
- [Building Plugins](/plugins/building-plugins)
- [Plugin SDK Overview](/plugins/sdk-overview)
- [Plugin Runtime](/plugins/sdk-runtime)