TaskFlow
DashboardFreewriteWhiteboardsProjectsCRMTasksNotificationsSettingsAgent TowerAPI Docs
OpenClaw Docs
?

User

Member

Caricamento in corso...

Home
Progetti
Task
Notifiche
CRM

    OpenClaw

    Documentation Mirror

    Documentation Overview

    Docs

    Auth credential semantics
    Scheduled tasks
    Hooks
    Automation & tasks
    Standing orders
    Task flow
    Background tasks
    BlueBubbles
    Broadcast groups
    Channel routing
    Discord
    Feishu
    Google Chat
    Group messages
    Groups
    iMessage
    Chat channels
    IRC
    LINE
    Channel location parsing
    Matrix
    Matrix migration
    Matrix push rules for quiet previews
    Mattermost
    Microsoft Teams
    Nextcloud Talk
    Nostr
    Pairing
    QA channel
    QQ bot
    Signal
    Slack
    Synology Chat
    Telegram
    Tlon
    Channel troubleshooting
    Twitch
    WeChat
    WhatsApp
    Yuanbao
    Zalo
    Zalo personal
    CI pipeline
    ACP
    Agent
    Agents
    Approvals
    Backup
    Browser
    Channels
    Clawbot
    `openclaw commitments`
    Completion
    Config
    Configure
    Cron
    Daemon
    Dashboard
    Devices
    Directory
    DNS
    Docs
    Doctor
    Flows (redirect)
    Gateway
    Health
    Hooks
    CLI reference
    Inference CLI
    Logs
    MCP
    Memory
    Message
    Migrate
    Models
    Node
    Nodes
    Onboard
    Pairing
    Plugins
    Proxy
    QR
    Reset
    Sandbox CLI
    Secrets
    Security
    Sessions
    Setup
    Skills
    Status
    System
    `openclaw tasks`
    TUI
    Uninstall
    Update
    Voicecall
    Webhooks
    Wiki
    Active memory
    Agent runtime
    Agent loop
    Agent runtimes
    Agent workspace
    Gateway architecture
    Channel docking
    Inferred commitments
    Compaction
    Context
    Context engine
    Delegate architecture
    Dreaming
    Experimental features
    Features
    Markdown formatting
    Memory overview
    Builtin memory engine
    Honcho memory
    QMD memory engine
    Memory search
    Messages
    Model failover
    Model providers
    Models CLI
    Multi-agent routing
    OAuth
    OpenClaw App SDK
    Presence
    QA overview
    Matrix QA
    Command queue
    Steering queue
    Retry policy
    Session management
    Session pruning
    Session tools
    SOUL.md personality guide
    Streaming and chunking
    System prompt
    Timezones
    TypeBox
    Typing indicators
    Usage tracking
    Date and time
    Node + tsx crash
    Diagnostics flags
    Authentication
    Background exec and process tool
    Bonjour discovery
    Bridge protocol
    CLI backends
    Configuration — agents
    Configuration — channels
    Configuration — tools and custom providers
    Configuration
    Configuration examples
    Configuration reference
    Diagnostics export
    Discovery and transports
    Doctor
    Gateway lock
    Health checks
    Heartbeat
    Gateway runbook
    Local models
    Gateway logging
    Multiple gateways
    Network model
    OpenAI chat completions
    OpenResponses API
    OpenShell
    OpenTelemetry export
    Gateway-owned pairing
    Prometheus metrics
    Gateway protocol
    Remote access
    Remote gateway setup
    Sandbox vs tool policy vs elevated
    Sandboxing
    Secrets management
    Secrets apply plan contract
    Security audit checks
    Security
    Tailscale
    Tools invoke API
    Troubleshooting
    Trusted proxy auth
    Debugging
    Environment variables
    FAQ
    FAQ: first-run setup
    FAQ: models and auth
    GPT-5.5 / Codex agentic parity
    GPT-5.5 / Codex parity maintainer notes
    Help
    Scripts
    Testing
    Testing: live suites
    General troubleshooting
    OpenClaw
    Ansible
    Azure
    Bun (experimental)
    ClawDock
    Release channels
    DigitalOcean
    Docker
    Docker VM runtime
    exe.dev
    Fly.io
    GCP
    Hetzner
    Hostinger
    Install
    Installer internals
    Kubernetes
    macOS VMs
    Migration guide
    Migrating from Claude
    Migrating from Hermes
    Nix
    Node.js
    Northflank
    Oracle Cloud
    Podman
    Railway
    Raspberry Pi
    Render
    Uninstall
    Updating
    Logging
    Network
    Audio and voice notes
    Camera capture
    Image and media support
    Nodes
    Location command
    Media understanding
    Talk mode
    Node troubleshooting
    Voice wake
    Pi integration architecture
    Pi development workflow
    Android app
    Platforms
    iOS app
    Linux app
    Gateway on macOS
    Canvas
    Gateway lifecycle
    macOS dev setup
    Health checks (macOS)
    Menu bar icon
    macOS logging
    Menu bar
    Peekaboo bridge
    macOS permissions
    Remote control
    macOS signing
    Skills (macOS)
    Voice overlay
    Voice wake (macOS)
    WebChat (macOS)
    macOS IPC
    macOS app
    Windows
    Plugin internals
    Plugin architecture internals
    Building plugins
    Plugin bundles
    Codex Computer Use
    Codex harness
    Community plugins
    Plugin compatibility
    Google Meet plugin
    Plugin hooks
    Plugin manifest
    Memory LanceDB
    Memory wiki
    Message presentation
    Agent harness plugins
    Building channel plugins
    Channel turn kernel
    Plugin entry points
    Plugin SDK migration
    Plugin SDK overview
    Building provider plugins
    Plugin runtime helpers
    Plugin setup and config
    Plugin SDK subpaths
    Plugin testing
    Skill workshop plugin
    Voice call plugin
    Webhooks plugin
    Zalo personal plugin
    OpenProse
    Alibaba Model Studio
    Anthropic
    Arcee AI
    Azure Speech
    Amazon Bedrock
    Amazon Bedrock Mantle
    Chutes
    Claude Max API proxy
    Cloudflare AI gateway
    ComfyUI
    Deepgram
    Deepinfra
    DeepSeek
    ElevenLabs
    Fal
    Fireworks
    GitHub Copilot
    GLM (Zhipu)
    Google (Gemini)
    Gradium
    Groq
    Hugging Face (inference)
    Provider directory
    Inferrs
    Inworld
    Kilocode
    LiteLLM
    LM Studio
    MiniMax
    Mistral
    Model provider quickstart
    Moonshot AI
    NVIDIA
    Ollama
    OpenAI
    OpenCode
    OpenCode Go
    OpenRouter
    Perplexity
    Qianfan
    Qwen
    Runway
    SGLang
    StepFun
    Synthetic
    Tencent Cloud (TokenHub)
    Together AI
    Venice AI
    Vercel AI gateway
    vLLM
    Volcengine (Doubao)
    Vydra
    xAI
    Xiaomi MiMo
    Z.AI
    Default AGENTS.md
    Release policy
    API usage and costs
    Credits
    Device model database
    Full release validation
    Memory configuration reference
    OpenClaw App SDK API design
    Prompt caching
    Rich output protocol
    RPC adapters
    SecretRef credential surface
    Session management deep dive
    AGENTS.md template
    BOOT.md template
    BOOTSTRAP.md template
    HEARTBEAT.md template
    IDENTITY template
    SOUL.md template
    TOOLS.md template
    USER template
    Tests
    Token use and costs
    Transcript hygiene
    Onboarding reference
    Contributing to the threat model
    Threat model (MITRE ATLAS)
    Formal verification (security models)
    Network proxy
    Agent bootstrapping
    Docs directory
    Getting started
    Docs hubs
    OpenClaw lore
    Onboarding (macOS app)
    Onboarding overview
    Personal assistant setup
    Setup
    Showcase
    Onboarding (CLI)
    CLI automation
    CLI setup reference
    ACP agents
    ACP agents — setup
    Agent send
    apply_patch tool
    Brave search
    Browser (OpenClaw-managed)
    Browser control API
    Browser troubleshooting
    Browser login
    WSL2 + Windows + remote Chrome CDP troubleshooting
    BTW side questions
    ClawHub
    Code execution
    Creating skills
    Diffs
    DuckDuckGo search
    Elevated mode
    Exa search
    Exec tool
    Exec approvals
    Exec approvals — advanced
    Firecrawl
    Gemini search
    Grok search
    Image generation
    Tools and plugins
    Kimi search
    LLM task
    Lobster
    Tool-loop detection
    Media overview
    MiniMax search
    Multi-agent sandbox and tools
    Music generation
    Ollama web search
    PDF tool
    Perplexity search
    Plugins
    Reactions
    SearXNG search
    Skills
    Skills config
    Slash commands
    Sub-agents
    Tavily
    Thinking levels
    Tokenjuice
    Trajectory bundles
    Text-to-speech
    Video generation
    Web search
    Web fetch
    Linux server
    Control UI
    Dashboard
    Web
    TUI
    WebChat

    OpenAPI Specs

    openapi
    TaskFlow
    docs/openclaw
    Original Docs

    Real-time Synchronized Documentation

    Last sync: 01/05/2026 07:00:08

    Note: This content is mirrored from docs.openclaw.ai and is subject to their terms and conditions.

    OpenClaw Docs

    v2.4.0 Production

    Last synced: Today, 22:00

    Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.

    Use this file to discover all available pages before exploring further.

    Plugin testing

    Reference for test utilities, patterns, and lint enforcement for OpenClaw plugins.

    tip

    **Looking for test examples?** The how-to guides include worked test examples: [Channel plugin tests](/plugins/sdk-channel-plugins#step-6-test) and [Provider plugin tests](/plugins/sdk-provider-plugins#step-6-test).

    Test utilities

    Plugin API mock import:

    text
    openclaw/plugin-sdk/plugin-test-api

    Agent runtime contract import:

    text
    openclaw/plugin-sdk/agent-runtime-test-contracts

    Channel contract import:

    text
    openclaw/plugin-sdk/channel-contract-testing

    Channel test helper import:

    text
    openclaw/plugin-sdk/channel-test-helpers

    Channel target test import:

    text
    openclaw/plugin-sdk/channel-target-testing

    Plugin contract import:

    text
    openclaw/plugin-sdk/plugin-test-contracts

    Plugin runtime test import:

    text
    openclaw/plugin-sdk/plugin-test-runtime

    Provider contract import:

    text
    openclaw/plugin-sdk/provider-test-contracts

    Provider HTTP mock import:

    text
    openclaw/plugin-sdk/provider-http-test-mocks

    Environment/network test import:

    text
    openclaw/plugin-sdk/test-env

    Generic fixture import:

    text
    openclaw/plugin-sdk/test-fixtures

    Node builtin mock import:

    text
    openclaw/plugin-sdk/test-node-mocks

    Prefer the focused subpaths below for new plugin tests. The broad

    text
    openclaw/plugin-sdk/testing
    barrel is legacy compatibility only. Repo guardrails reject new real imports from
    text
    plugin-sdk/testing
    and
    text
    plugin-sdk/test-utils
    ; those names remain only as deprecated compatibility surfaces for external plugins and compatibility-record tests.

    typescript
    import { shouldAckReaction, removeAckReactionAfterReply, } from "openclaw/plugin-sdk/channel-feedback"; import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/channel-target-testing"; import { AUTH_PROFILE_RUNTIME_CONTRACT } from "openclaw/plugin-sdk/agent-runtime-test-contracts"; import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api"; import { expectChannelInboundContextContract } from "openclaw/plugin-sdk/channel-contract-testing"; import { createStartAccountContext } from "openclaw/plugin-sdk/channel-test-helpers"; import { describePluginRegistrationContract } from "openclaw/plugin-sdk/plugin-test-contracts"; import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-runtime"; import { describeOpenAIProviderRuntimeContract } from "openclaw/plugin-sdk/provider-test-contracts"; import { getProviderHttpMocks } from "openclaw/plugin-sdk/provider-http-test-mocks"; import { withEnv, withFetchPreconnect, withServer } from "openclaw/plugin-sdk/test-env"; import { bundledPluginRoot, createCliRuntimeCapture, typedCases, } from "openclaw/plugin-sdk/test-fixtures"; import { mockNodeBuiltinModule } from "openclaw/plugin-sdk/test-node-mocks";

    Available exports

    ExportPurpose
    text
    createTestPluginApi
    Build a minimal plugin API mock for direct registration unit tests. Import from
    text
    plugin-sdk/plugin-test-api
    text
    AUTH_PROFILE_RUNTIME_CONTRACT
    Shared auth-profile contract fixture for native agent runtime adapters. Import from
    text
    plugin-sdk/agent-runtime-test-contracts
    text
    DELIVERY_NO_REPLY_RUNTIME_CONTRACT
    Shared delivery suppression contract fixture for native agent runtime adapters. Import from
    text
    plugin-sdk/agent-runtime-test-contracts
    text
    OUTCOME_FALLBACK_RUNTIME_CONTRACT
    Shared fallback-classification contract fixture for native agent runtime adapters. Import from
    text
    plugin-sdk/agent-runtime-test-contracts
    text
    createParameterFreeTool
    Build dynamic-tool schema fixtures for native runtime contract tests. Import from
    text
    plugin-sdk/agent-runtime-test-contracts
    text
    expectChannelInboundContextContract
    Assert channel inbound context shape. Import from
    text
    plugin-sdk/channel-contract-testing
    text
    installChannelOutboundPayloadContractSuite
    Install channel outbound payload contract cases. Import from
    text
    plugin-sdk/channel-contract-testing
    text
    createStartAccountContext
    Build channel account lifecycle contexts. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    installChannelActionsContractSuite
    Install generic channel message-action contract cases. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    installChannelSetupContractSuite
    Install generic channel setup contract cases. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    installChannelStatusContractSuite
    Install generic channel status contract cases. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    expectDirectoryIds
    Assert channel directory ids from a directory-list function. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    assertBundledChannelEntries
    Assert bundled channel entrypoints expose the expected public contract. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    formatEnvelopeTimestamp
    Format deterministic envelope timestamps. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    expectPairingReplyText
    Assert channel pairing reply text and extract its code. Import from
    text
    plugin-sdk/channel-test-helpers
    text
    describePluginRegistrationContract
    Install plugin registration contract checks. Import from
    text
    plugin-sdk/plugin-test-contracts
    text
    registerSingleProviderPlugin
    Register one provider plugin in loader smoke tests. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    registerProviderPlugin
    Capture all provider kinds from one plugin. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    registerProviderPlugins
    Capture provider registrations across multiple plugins. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    requireRegisteredProvider
    Assert that a provider collection contains an id. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    createRuntimeEnv
    Build a mocked CLI/plugin runtime environment. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    createPluginSetupWizardStatus
    Build setup status helpers for channel plugins. Import from
    text
    plugin-sdk/plugin-test-runtime
    text
    describeOpenAIProviderRuntimeContract
    Install provider-family runtime contract checks. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    expectPassthroughReplayPolicy
    Assert provider replay policies pass through provider-owned tools and metadata. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    runRealtimeSttLiveTest
    Run a live realtime STT provider test with shared audio fixtures. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    normalizeTranscriptForMatch
    Normalize live transcript output before fuzzy assertions. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    expectExplicitVideoGenerationCapabilities
    Assert video providers declare explicit generation mode capabilities. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    expectExplicitMusicGenerationCapabilities
    Assert music providers declare explicit generation/edit capabilities. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    mockSuccessfulDashscopeVideoTask
    Install a successful DashScope-compatible video task response. Import from
    text
    plugin-sdk/provider-test-contracts
    text
    getProviderHttpMocks
    Access opt-in provider HTTP/auth Vitest mocks. Import from
    text
    plugin-sdk/provider-http-test-mocks
    text
    installProviderHttpMockCleanup
    Reset provider HTTP/auth mocks after each test. Import from
    text
    plugin-sdk/provider-http-test-mocks
    text
    installCommonResolveTargetErrorCases
    Shared test cases for target resolution error handling. Import from
    text
    plugin-sdk/channel-target-testing
    text
    shouldAckReaction
    Check whether a channel should add an ack reaction. Import from
    text
    plugin-sdk/channel-feedback
    text
    removeAckReactionAfterReply
    Remove ack reaction after reply delivery. Import from
    text
    plugin-sdk/channel-feedback
    text
    createTestRegistry
    Build a channel plugin registry fixture. Import from
    text
    plugin-sdk/plugin-test-runtime
    or
    text
    plugin-sdk/channel-test-helpers
    text
    createEmptyPluginRegistry
    Build an empty plugin registry fixture. Import from
    text
    plugin-sdk/plugin-test-runtime
    or
    text
    plugin-sdk/channel-test-helpers
    text
    setActivePluginRegistry
    Install a registry fixture for plugin runtime tests. Import from
    text
    plugin-sdk/plugin-test-runtime
    or
    text
    plugin-sdk/channel-test-helpers
    text
    createRequestCaptureJsonFetch
    Capture JSON fetch requests in media helper tests. Import from
    text
    plugin-sdk/test-env
    text
    withServer
    Run tests against a disposable local HTTP server. Import from
    text
    plugin-sdk/test-env
    text
    createMockIncomingRequest
    Build a minimal incoming HTTP request object. Import from
    text
    plugin-sdk/test-env
    text
    withFetchPreconnect
    Run fetch tests with preconnect hooks installed. Import from
    text
    plugin-sdk/test-env
    text
    withEnv
    /
    text
    withEnvAsync
    Temporarily patch environment variables. Import from
    text
    plugin-sdk/test-env
    text
    createTempHomeEnv
    /
    text
    withTempHome
    /
    text
    withTempDir
    Create isolated filesystem test fixtures. Import from
    text
    plugin-sdk/test-env
    text
    createMockServerResponse
    Create a minimal HTTP server response mock. Import from
    text
    plugin-sdk/test-env
    text
    createCliRuntimeCapture
    Capture CLI runtime output in tests. Import from
    text
    plugin-sdk/test-fixtures
    text
    importFreshModule
    Import an ESM module with a fresh query token to bypass module cache. Import from
    text
    plugin-sdk/test-fixtures
    text
    bundledPluginRoot
    /
    text
    bundledPluginFile
    Resolve bundled plugin source or dist fixture paths. Import from
    text
    plugin-sdk/test-fixtures
    text
    mockNodeBuiltinModule
    Install narrow Node builtin Vitest mocks. Import from
    text
    plugin-sdk/test-node-mocks
    text
    createSandboxTestContext
    Build sandbox test contexts. Import from
    text
    plugin-sdk/test-fixtures
    text
    writeSkill
    Write skill fixtures. Import from
    text
    plugin-sdk/test-fixtures
    text
    makeAgentAssistantMessage
    Build agent transcript message fixtures. Import from
    text
    plugin-sdk/test-fixtures
    text
    peekSystemEvents
    /
    text
    resetSystemEventsForTest
    Inspect and reset system event fixtures. Import from
    text
    plugin-sdk/test-fixtures
    text
    sanitizeTerminalText
    Sanitize terminal output for assertions. Import from
    text
    plugin-sdk/test-fixtures
    text
    countLines
    /
    text
    hasBalancedFences
    Assert chunking output shape. Import from
    text
    plugin-sdk/test-fixtures
    text
    runProviderCatalog
    Execute a provider catalog hook with test dependencies
    text
    resolveProviderWizardOptions
    Resolve provider setup wizard choices in contract tests
    text
    resolveProviderModelPickerEntries
    Resolve provider model-picker entries in contract tests
    text
    buildProviderPluginMethodChoice
    Build provider wizard choice ids for assertions
    text
    setProviderWizardProvidersResolverForTest
    Inject provider wizard providers for isolated tests
    text
    createProviderUsageFetch
    Build provider usage fetch fixtures
    text
    useFrozenTime
    /
    text
    useRealTime
    Freeze and restore timers for time-sensitive tests. Import from
    text
    plugin-sdk/test-env
    text
    createTestWizardPrompter
    Build a mocked setup wizard prompter
    text
    createRuntimeTaskFlow
    Create isolated runtime task-flow state
    text
    typedCases
    Preserve literal types for table-driven tests. Import from
    text
    plugin-sdk/test-fixtures

    Bundled-plugin contract suites also use SDK testing subpaths for test-only registry, manifest, public-artifact, and runtime fixture helpers. Core-only suites that depend on bundled OpenClaw inventory stay under

    text
    src/plugins/contracts
    . Keep new extension tests on a documented focused SDK subpath such as
    text
    plugin-sdk/plugin-test-api
    ,
    text
    plugin-sdk/channel-contract-testing
    ,
    text
    plugin-sdk/agent-runtime-test-contracts
    ,
    text
    plugin-sdk/channel-test-helpers
    ,
    text
    plugin-sdk/plugin-test-contracts
    ,
    text
    plugin-sdk/plugin-test-runtime
    ,
    text
    plugin-sdk/provider-test-contracts
    ,
    text
    plugin-sdk/provider-http-test-mocks
    ,
    text
    plugin-sdk/test-env
    , or
    text
    plugin-sdk/test-fixtures
    rather than importing the broad
    text
    plugin-sdk/testing
    compatibility barrel, repo
    text
    src/**
    files, or repo
    text
    test/helpers/*
    bridges directly.

    Types

    Focused testing subpaths also re-export types useful in test files:

    typescript
    import type { ChannelAccountSnapshot, ChannelGatewayContext, } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types"; import type { MockFn, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/plugin-test-runtime";

    Testing target resolution

    Use

    text
    installCommonResolveTargetErrorCases
    to add standard error cases for channel target resolution:

    typescript
    import { describe } from "vitest"; import { installCommonResolveTargetErrorCases } from "openclaw/plugin-sdk/channel-target-testing"; describe("my-channel target resolution", () => { installCommonResolveTargetErrorCases({ resolveTarget: ({ to, mode, allowFrom }) => { // Your channel's target resolution logic return myChannelResolveTarget({ to, mode, allowFrom }); }, implicitAllowFrom: ["user1", "user2"], }); // Add channel-specific test cases it("should resolve @username targets", () => { // ... }); });

    Testing patterns

    Testing registration contracts

    Unit tests that pass a hand-written

    text
    api
    mock to
    text
    register(api)
    do not exercise OpenClaw's loader acceptance gates. Add at least one loader-backed smoke test for each registration surface your plugin depends on, especially hooks and exclusive capabilities such as memory.

    The real loader fails plugin registration when required metadata is missing or a plugin calls a capability API it does not own. For example,

    text
    api.registerHook(...)
    requires a hook name, and
    text
    api.registerMemoryCapability(...)
    requires the plugin manifest or exported entry to declare
    text
    kind: "memory"
    .

    Testing runtime config access

    Prefer the shared plugin runtime mock from

    text
    openclaw/plugin-sdk/channel-test-helpers
    when testing bundled channel plugins. Its deprecated
    text
    runtime.config.loadConfig()
    and
    text
    runtime.config.writeConfigFile(...)
    mocks throw by default so tests catch new usage of compatibility APIs. Override those mocks only when the test is explicitly covering legacy compatibility behavior.

    Unit testing a channel plugin

    typescript
    import { describe, it, expect, vi } from "vitest"; 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"); // No token value exposed expect(inspection).not.toHaveProperty("token"); }); });

    Unit testing a provider plugin

    typescript
    import { describe, it, expect } from "vitest"; describe("my-provider plugin", () => { it("should resolve dynamic models", () => { const model = myProvider.resolveDynamicModel({ modelId: "custom-model-v2", // ... context }); 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" }), // ... context }); expect(result?.provider?.models).toHaveLength(2); }); });

    Mocking the plugin runtime

    For code that uses

    text
    createPluginRuntimeStore
    , mock the runtime in tests:

    typescript
    import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store"; const store = createPluginRuntimeStore<PluginRuntime>({ pluginId: "test-plugin", errorMessage: "test runtime not set", }); // In test setup const mockRuntime = { agent: { resolveAgentDir: vi.fn().mockReturnValue("/tmp/agent"), // ... other mocks }, config: { current: vi.fn(() => ({}) as const), mutateConfigFile: vi.fn(), replaceConfigFile: vi.fn(), }, // ... other namespaces } as unknown as PluginRuntime; store.setRuntime(mockRuntime); // After tests store.clearRuntime();

    Testing with per-instance stubs

    Prefer per-instance stubs over prototype mutation:

    typescript
    // Preferred: per-instance stub const client = new MyChannelClient(); client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" }); // Avoid: prototype mutation // MyChannelClient.prototype.sendMessage = vi.fn();

    Contract tests (in-repo plugins)

    Bundled plugins have contract tests that verify registration ownership:

    bash
    pnpm test -- src/plugins/contracts/

    These tests assert:

    • Which plugins register which providers
    • Which plugins register which speech providers
    • Registration shape correctness
    • Runtime contract compliance

    Running scoped tests

    For a specific plugin:

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

    For contract tests only:

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

    Lint enforcement (in-repo plugins)

    Three rules are enforced by

    text
    pnpm check
    for in-repo plugins:

    1. No monolithic root imports --
      text
      openclaw/plugin-sdk
      root barrel is rejected
    2. No direct
      text
      src/
      imports
      -- plugins cannot import
      text
      ../../src/
      directly
    3. No self-imports -- plugins cannot import their own
      text
      plugin-sdk/<name>
      subpath

    External plugins are not subject to these lint rules, but following the same patterns is recommended.

    Test configuration

    OpenClaw uses Vitest with V8 coverage thresholds. For plugin tests:

    bash
    # Run all tests pnpm test # Run specific plugin tests pnpm test -- <bundled-plugin-root>/my-channel/src/channel.test.ts # Run with a specific test name filter pnpm test -- <bundled-plugin-root>/my-channel/ -t "resolves account" # Run with coverage pnpm test:coverage

    If local runs cause memory pressure:

    bash
    OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test

    Related

    • SDK Overview -- import conventions
    • SDK Channel Plugins -- channel plugin interface
    • SDK Provider Plugins -- provider plugin hooks
    • Building Plugins -- getting started guide

    © 2024 TaskFlow Mirror

    Powered by TaskFlow Sync Engine