Plugin SDK reference
اختبار Plugin
مرجع لأدوات الاختبار وأنماطه وفرض قواعد الفحص لإضافات OpenClaw.
أدوات الاختبار
مسارات أدوات الاختبار الفرعية هذه هي نقاط دخول مصدرية محلية داخل المستودع لاختبارات الإضافات المضمنة الخاصة بـ OpenClaw. وهي ليست تصديرات حزم لإضافات الجهات الخارجية، وقد تستورد Vitest أو تبعيات اختبار أخرى خاصة بالمستودع فقط.
استيراد محاكاة واجهة Plugin API: openclaw/plugin-sdk/plugin-test-api
استيراد عقد وقت تشغيل الوكيل: openclaw/plugin-sdk/agent-runtime-test-contracts
استيراد عقد القناة: openclaw/plugin-sdk/channel-contract-testing
استيراد مساعد اختبار القناة: openclaw/plugin-sdk/channel-test-helpers
استيراد اختبار هدف القناة: openclaw/plugin-sdk/channel-target-testing
استيراد عقد Plugin: openclaw/plugin-sdk/plugin-test-contracts
استيراد اختبار وقت تشغيل Plugin: openclaw/plugin-sdk/plugin-test-runtime
استيراد عقد المزوّد: openclaw/plugin-sdk/provider-test-contracts
استيراد محاكاة HTTP للمزوّد: openclaw/plugin-sdk/provider-http-test-mocks
استيراد اختبار البيئة/الشبكة: openclaw/plugin-sdk/test-env
استيراد التجهيز العام: openclaw/plugin-sdk/test-fixtures
استيراد محاكاة مكوّن Node المدمج: openclaw/plugin-sdk/test-node-mocks
داخل مستودع OpenClaw، فضّل المسارات الفرعية المركزة أدناه لاختبارات الإضافات المضمنة الجديدة. ملف التجميع الواسع
openclaw/plugin-sdk/testing مخصص للتوافق القديم فقط.
ترفض حواجز المستودع الوقائية أي استيرادات فعلية جديدة من plugin-sdk/testing و
plugin-sdk/test-utils؛ وتبقى هذه الأسماء فقط كأسطح توافق مهملة لاختبارات سجل التوافق.
shouldAckReaction, removeAckReactionAfterReply,} from "openclaw/plugin-sdk/channel-feedback"; bundledPluginRoot, createCliRuntimeCapture, typedCases,} from "openclaw/plugin-sdk/test-fixtures"; التصديرات المتاحة
| التصدير | الغرض |
|---|---|
createTestPluginApi |
بناء محاكاة بسيطة لواجهة API الخاصة بـ Plugin لاختبارات الوحدة للتسجيل المباشر. استورد من 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 |
التقاط تسجيلات الموفرين عبر عدة Plugins. استورد من 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 |
بناء مساعدات حالة الإعداد لقنوات Plugins. استورد من plugin-sdk/plugin-test-runtime |
describeOpenAIProviderRuntimeContract |
تثبيت فحوصات عقد وقت تشغيل عائلة الموفرين. استورد من plugin-sdk/provider-test-contracts |
expectPassthroughReplayPolicy |
تأكيد أن سياسات إعادة التشغيل الخاصة بالموفر تمرر أدوات الموفر وبياناته الوصفية كما هي. استورد من plugin-sdk/provider-test-contracts |
runRealtimeSttLiveTest |
تشغيل اختبار مباشر لموفر تحويل الكلام إلى نص في الوقت الفعلي باستخدام مثبتات صوت مشتركة. استورد من 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 |
الوصول إلى محاكاة Vitest الاختيارية لـ HTTP/المصادقة الخاصة بالموفر. استورد من 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 |
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 |
كتابة مثبتات 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 |
runProviderCatalog |
تنفيذ خطاف كتالوج موفر باستخدام تبعيات اختبار |
resolveProviderWizardOptions |
حل خيارات معالج إعداد الموفر في اختبارات العقد |
resolveProviderModelPickerEntries |
حل إدخالات منتقي نموذج الموفر في اختبارات العقد |
buildProviderPluginMethodChoice |
بناء معرّفات خيارات معالج الموفر للتأكيدات |
setProviderWizardProvidersResolverForTest |
حقن مزودي معالج المزود للاختبارات المعزولة |
createProviderUsageFetch |
بناء تجهيزات جلب استخدام المزود |
useFrozenTime / useRealTime |
تجميد المؤقتات واستعادتها للاختبارات الحساسة للوقت. استورد من plugin-sdk/test-env |
createTestWizardPrompter |
بناء موجّه معالج إعداد وهمي |
createRuntimeTaskFlow |
إنشاء حالة task-flow وقت تشغيل معزولة |
typedCases |
الحفاظ على الأنواع الحرفية للاختبارات المعتمدة على الجداول. استورد من plugin-sdk/test-fixtures |
تستخدم مجموعات عقود Plugins المضمنة أيضًا مسارات SDK الفرعية الخاصة بالاختبار لمساعدات سجل الاختبار فقط، والبيان، والأثر العام، وتجهيزات وقت التشغيل. تبقى المجموعات الخاصة بالنواة فقط التي تعتمد على مخزون OpenClaw المضمن ضمن src/plugins/contracts.
أبقِ اختبارات الإضافات الجديدة على مسار فرعي مركّز وموثّق في SDK مثل
plugin-sdk/plugin-test-api، أو plugin-sdk/channel-contract-testing،
أو plugin-sdk/agent-runtime-test-contracts، أو plugin-sdk/channel-test-helpers،
أو plugin-sdk/plugin-test-contracts، أو plugin-sdk/plugin-test-runtime،
أو plugin-sdk/provider-test-contracts، أو plugin-sdk/provider-http-test-mocks،
أو plugin-sdk/test-env، أو plugin-sdk/test-fixtures بدلًا من استيراد تجميعة التوافق
العريضة plugin-sdk/testing، أو ملفات المستودع src/**، أو جسور المستودع
test/helpers/* مباشرة.
الأنواع
تعيد مسارات الاختبار الفرعية المركّزة أيضًا تصدير أنواع مفيدة في ملفات الاختبار:
ChannelAccountSnapshot, ChannelGatewayContext,} from "openclaw/plugin-sdk/channel-contract"; اختبار حل الوجهات
استخدم installCommonResolveTargetErrorCases لإضافة حالات الخطأ القياسية الخاصة
بحل وجهات القنوات:
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", () => { // ... });});أنماط الاختبار
اختبار عقود التسجيل
اختبارات الوحدة التي تمرر محاكاة 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"); // No token value exposed expect(inspection).not.toHaveProperty("token"); });});اختبار وحدة Plugin موفّر
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); });});محاكاة وقت تشغيل Plugin
بالنسبة إلى الشيفرة التي تستخدم createPluginRuntimeStore، حاكِ وقت التشغيل في الاختبارات:
const store = createPluginRuntimeStore<PluginRuntime>({ pluginId: "test-plugin", errorMessage: "test runtime not set",}); // In test setupconst 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 testsstore.clearRuntime();الاختبار باستخدام بدائل لكل نسخة
فضّل البدائل لكل نسخة على تعديل النموذج الأولي:
// Preferred: per-instance stubconst client = new MyChannelClient();client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" }); // Avoid: prototype mutation// MyChannelClient.prototype.sendMessage = vi.fn();اختبارات العقود (Plugins داخل المستودع)
تملك Plugins المضمنة اختبارات عقود تتحقق من ملكية التسجيل:
pnpm test -- src/plugins/contracts/تؤكد هذه الاختبارات:
- أي Plugins تسجل أي موفرين
- أي Plugins تسجل أي موفري كلام
- صحة شكل التسجيل
- الامتثال لعقد وقت التشغيل
تشغيل اختبارات محددة النطاق
لـ 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فرض الفحص (Plugins داخل المستودع)
يفرض pnpm check ثلاث قواعد على Plugins داخل المستودع:
- لا استيرادات جذرية أحادية -- تُرفض تجميعة الجذر
openclaw/plugin-sdk - لا استيرادات مباشرة من
src/-- لا يمكن لـ Plugins استيراد../../src/مباشرة - لا استيرادات ذاتية -- لا يمكن لـ Plugins استيراد مسارها الفرعي
plugin-sdk/<name>الخاص بها
لا تخضع Plugins الخارجية لهذه القواعد الخاصة بالفحص، لكن يُوصى باتباع الأنماط نفسها.
إعدادات الاختبار
يستخدم OpenClaw Vitest مع عتبات تغطية V8. لاختبارات Plugin:
# Run all testspnpm test # Run specific plugin testspnpm test -- <bundled-plugin-root>/my-channel/src/channel.test.ts # Run with a specific test name filterpnpm test -- <bundled-plugin-root>/my-channel/ -t "resolves account" # Run with coveragepnpm test:coverageإذا سببت التشغيلات المحلية ضغطًا على الذاكرة:
OPENCLAW_VITEST_MAX_WORKERS=1 pnpm testذو صلة
- نظرة عامة على SDK -- أعراف الاستيراد
- Plugins قنوات SDK -- واجهة Plugin القناة
- Plugins موفري SDK -- خطافات Plugin الموفّر
- بناء Plugins -- دليل البدء