Plugin SDK reference
آزمایش Plugin
مرجعی برای ابزارهای کمکی آزمون، الگوها و اعمال قواعد لینت برای Pluginهای OpenClaw.
ابزارهای کمکی آزمون
این زیرمسیرها نقاط ورودی کد منبع محلی مخزن برای آزمونهای Pluginهای همراه خود OpenClaw هستند. آنها خروجیهای منتشرشدهٔ package.json برای Pluginهای شخص ثالث نیستند و ممکن است Vitest یا دیگر وابستگیهای آزمون مختص مخزن را وارد کنند.
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-imports
(scripts/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 |
شناسههای دایرکتوری کانال را از یک تابع فهرستکردن دایرکتوری بررسی میکند. از 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 |
یک Plugin ارائهدهنده را در آزمونهای دودِ بارگذار ثبت میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
registerProviderPlugin |
همه انواع ارائهدهنده را از یک Plugin ثبت میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
registerProviderPlugins |
ثبتهای ارائهدهنده را در چند Plugin ثبت میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
requireRegisteredProvider |
بررسی میکند که یک مجموعه ارائهدهنده دارای یک شناسه باشد. از 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 |
وضعیت ایزوله جریان وظیفه زماناجرا را ایجاد میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
runProviderCatalog |
یک هوک کاتالوگ ارائهدهنده را با وابستگیهای آزمون اجرا میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
resolveProviderWizardOptions |
گزینههای جادوگر راهاندازی ارائهدهنده را در آزمونهای قرارداد حل میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
resolveProviderModelPickerEntries |
ورودیهای انتخابگر مدل ارائهدهنده را در آزمونهای قرارداد حل میکند. از plugin-sdk/plugin-test-runtime وارد کنید |
buildProviderPluginMethodChoice |
شناسههای انتخاب جادوگر ارائهدهنده را برای بررسیها میسازد. از 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 را در آزمونهای کمکتابع رسانه ثبت میکند. از plugin-sdk/test-env وارد کنید |
withServer |
آزمونها را در برابر یک سرور محلی HTTP یکبارمصرف اجرا میکند. از plugin-sdk/test-env وارد کنید |
createMockIncomingRequest |
یک شیء حداقلی درخواست ورودی HTTP میسازد. از plugin-sdk/test-env وارد کنید |
withFetchPreconnect |
آزمونهای واکشی را با هوکهای پیشاتصال نصبشده اجرا میکند. از plugin-sdk/test-env وارد کنید |
withEnv / withEnvAsync |
متغیرهای محیطی را بهطور موقت وصله میکند. از plugin-sdk/test-env وارد کنید |
createTempHomeEnv / withTempHome / withTempDir |
فیکسچرهای آزمون ایزوله سامانه فایل را ایجاد میکند. از plugin-sdk/test-env وارد کنید |
createMockServerResponse |
یک شبیهساز حداقلی پاسخ سرور HTTP ایجاد میکند. از plugin-sdk/test-env وارد کنید |
createProviderUsageFetch |
فیکسچرهای واکشی مصرف ارائهدهنده را میسازد. از 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 همراه را حل میکند. از plugin-sdk/test-fixtures وارد کنید |
mockNodeBuiltinModule |
شبیهسازهای محدود Vitest برای ماژولهای داخلی Node را نصب میکند. از plugin-sdk/test-node-mocks وارد کنید |
createSandboxTestContext |
زمینههای آزمون سندباکس را میسازد. از plugin-sdk/test-fixtures وارد کنید |
writeSkill |
فیکسچرهای Skill را بنویسید. از 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 برای
ابزارهای کمکی رجیستری، مانیفست، آرتیفکت عمومی و فیکسچر زمان اجرا که فقط مخصوص آزمون هستند، استفاده میکنند.
در عوض، مجموعهآزمونهای مختص هسته که به موجودی Pluginهای همراه OpenClaw وابستهاند، در
src/plugins/contracts باقی میمانند.
نوعها
زیرمسیرهای متمرکز آزمون، نوعهای مفید در فایلهای آزمون را نیز دوباره صادر میکنند:
ChannelAccountSnapshot, ChannelGatewayContext,} from "openclaw/plugin-sdk/channel-contract"; آزمون تفکیک مقصد
برای افزودن حالتهای خطای استاندارد تفکیک مقصد کانال، از installCommonResolveTargetErrorCases استفاده کنید:
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 شما به آن وابسته است،
حداقل یک آزمون دود مبتنی بر بارگذار اضافه کنید؛ بهویژه برای هوکها و قابلیتهای انحصاری مانند حافظه.
بارگذار واقعی زمانی ثبت Plugin را ناموفق میکند که فراداده الزامی وجود نداشته باشد یا
Plugin یک API قابلیت را فراخوانی کند که مالک آن نیست. برای مثال،
api.registerHook(...) به نام هوک نیاز دارد و
api.registerMemoryCapability(...) مستلزم آن است که مانیفست Plugin یا ورودی صادرشده،
kind: "memory" را اعلام کند.
آزمون دسترسی به پیکربندی زمان اجرا
نمونه ساختگی مشترک زمان اجرای Plugin از openclaw/plugin-sdk/plugin-test-runtime را ترجیح دهید.
نمونههای ساختگی runtime.config.loadConfig() و runtime.config.writeConfigFile(...)
آن بهطور پیشفرض خطا میدهند تا آزمونها استفاده جدید از APIهای سازگاری منسوخشده را تشخیص دهند.
این نمونههای ساختگی را فقط زمانی بازنویسی کنید که آزمون صراحتاً رفتار سازگاری قدیمی را پوشش میدهد.
آزمون واحد یک Plugin کانال
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 ارائهدهنده
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 استفاده میکند، در آزمونها زمان اجرا را شبیهسازی کنید:
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();آزمون با جایگزینهای مخصوص هر نمونه
جایگزینهای مخصوص هر نمونه را به تغییر پروتوتایپ ترجیح دهید:
// ترجیحی: جایگزین مخصوص هر نمونهconst client = new MyChannelClient();client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" }); // اجتناب کنید: تغییر پروتوتایپ// MyChannelClient.prototype.sendMessage = vi.fn();آزمونهای قرارداد (Pluginهای درون مخزن)
Pluginهای همراه آزمونهای قراردادی دارند که مالکیت ثبت را تأیید میکنند:
pnpm test src/plugins/contracts/این آزمونها موارد زیر را بررسی میکنند:
- کدام Pluginها کدام ارائهدهندگان را ثبت میکنند
- کدام Pluginها کدام ارائهدهندگان گفتار را ثبت میکنند
- درستی ساختار ثبت
- انطباق با قرارداد زمان اجرا
اجرای آزمونهای محدودشده
برای یک Plugin مشخص:
pnpm test <bundled-plugin-root>/my-channel/فقط برای آزمونهای قرارداد:
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اعمال قواعد لینت (Pluginهای درون مخزن)
scripts/run-additional-boundary-checks.mjs مجموعهای از بررسیهای مرز واردسازی
lint:plugins:* را در CI اجرا میکند؛ هرکدام را میتوان بهصورت مستقل در محیط محلی نیز اجرا کرد:
| فرمان | آنچه اعمال میکند |
|---|---|
pnpm run lint:plugins:no-monolithic-plugin-sdk-entry-imports |
Pluginهای همراه نمیتوانند barrel ریشه یکپارچه 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/testing، plugin-sdk/test-utils یا سایر ابزارهای کمکی آزمون مختص هسته را وارد کنند. |
Pluginهای خارجی مشمول این قواعد لینت نیستند، اما پیروی از همین الگوها توصیه میشود.
پیکربندی آزمون
OpenClaw از Vitest 4 با گزارشدهی اطلاعرسان پوشش V8 استفاده میکند. برای آزمونهای Plugin:
# اجرای همه آزمونها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اگر اجراهای محلی باعث فشار حافظه میشوند:
OPENCLAW_VITEST_MAX_WORKERS=1 pnpm testمرتبط
- نمای کلی SDK -- قراردادهای واردسازی
- Pluginهای کانال SDK -- رابط Plugin کانال
- Pluginهای ارائهدهنده SDK -- هوکهای Plugin ارائهدهنده
- ساخت Pluginها -- راهنمای شروع کار