الانتقال إلى المحتوى الرئيسي

Documentation Index

Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt

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

مرجع لأدوات الاختبار وأنماطه وفرض قواعد الفحص في Plugins الخاصة بـ OpenClaw.
هل تبحث عن أمثلة اختبار؟ تتضمن أدلة الكيفية أمثلة اختبار عملية: اختبارات Plugin القناة و اختبارات Plugin المزوّد.

أدوات الاختبار

مسارات أدوات الاختبار الفرعية هذه هي نقاط دخول مصدرية محلية للمستودع لاختبارات Plugins المضمّنة الخاصة بـ OpenClaw. وهي ليست تصديرات حزم لـ Plugins الجهات الخارجية. استيراد محاكاة 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 فضّل المسارات الفرعية المركّزة أدناه لاختبارات Plugin الجديدة. أما مجموعة openclaw/plugin-sdk/testing الواسعة فهي للتوافق القديم فقط. ترفض حواجز حماية المستودع الاستيرادات الحقيقية الجديدة من plugin-sdk/testing و plugin-sdk/test-utils؛ وتبقى هذه الأسماء فقط كأسطح توافق مهملة لاختبارات سجلات التوافق.
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";

التصديرات المتاحة

التصديرالغرض
createTestPluginApiابنِ محاكاة صغيرة لواجهة Plugin 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التقط تسجيلات المزوّدين عبر عدة Plugins. استورد من plugin-sdk/plugin-test-runtime
requireRegisteredProviderتأكّد من أن مجموعة المزوّدين تحتوي على معرّف. استورد من plugin-sdk/plugin-test-runtime
createRuntimeEnvابنِ بيئة وقت تشغيل CLI/Plugin محاكية. استورد من plugin-sdk/plugin-test-runtime
createPluginSetupWizardStatusابنِ مساعدات حالة الإعداد لقنوات Plugin. استورد من 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صِل إلى محاكيات 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إنشاء حالة تدفّق مهام وقت تشغيل معزولة
typedCasesالحفاظ على الأنواع الحرفية للاختبارات المعتمدة على الجداول. استورِد من plugin-sdk/test-fixtures
تستخدم حزم عقود Plugin المضمّنة أيضًا مسارات SDK فرعية للاختبار خاصة بمساعدات السجل والبيان والأثر العام وتجهيزات وقت التشغيل المخصصة للاختبارات فقط. تبقى حزم Core-only التي تعتمد على مخزون 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 بدلًا من استيراد barrel التوافق الواسع plugin-sdk/testing أو ملفات المستودع src/** أو جسور المستودع test/helpers/* مباشرةً.

الأنواع

تعيد المسارات الفرعية المركّزة للاختبار أيضًا تصدير أنواع مفيدة في ملفات الاختبار:
import type {
  ChannelAccountSnapshot,
  ChannelGatewayContext,
} from "openclaw/plugin-sdk/channel-contract";
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts";
import type { MockFn, PluginRuntime, RuntimeEnv } from "openclaw/plugin-sdk/plugin-test-runtime";

حل هدف الاختبار

استخدم installCommonResolveTargetErrorCases لإضافة حالات الخطأ القياسية لحل أهداف القناة:
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", () => {
    // ...
  });
});

أنماط الاختبار

اختبار عقود التسجيل

اختبارات الوحدة التي تمرر محاكاة api مكتوبة يدويًا إلى register(api) لا تختبر بوابات قبول مُحمّل OpenClaw. أضف اختبار دخان واحدًا على الأقل مدعومًا بالمُحمّل لكل سطح تسجيل يعتمد عليه Plugin الخاص بك، وخصوصًا الخطافات والإمكانات الحصرية مثل الذاكرة. يفشل المُحمّل الحقيقي تسجيل Plugin عندما تكون البيانات الوصفية المطلوبة مفقودة أو عندما يستدعي Plugin واجهة API لإمكانة لا يملكها. على سبيل المثال، يتطلب api.registerHook(...) اسم خطاف، ويتطلب api.registerMemoryCapability(...) أن يصرّح بيان Plugin أو المدخل المصدّر بـ kind: "memory".

اختبار الوصول إلى إعداد وقت التشغيل

فضّل محاكاة وقت تشغيل Plugin المشتركة من openclaw/plugin-sdk/channel-test-helpers عند اختبار Plugin القنوات المضمّنة. محاكيتا runtime.config.loadConfig() و runtime.config.writeConfigFile(...) المهجورتان فيها ترميان خطأ افتراضيًا حتى تلتقط الاختبارات أي استخدام جديد لواجهات API التوافقية. لا تتجاوز هذه المحاكيات إلا عندما يكون الاختبار يغطي صراحةً سلوك التوافق القديم.

اختبار وحدة Plugin قناة

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");
  });
});

اختبار وحدة Plugin موفّر

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);
  });
});

محاكاة وقت تشغيل Plugin

للتعليمات البرمجية التي تستخدم createPluginRuntimeStore، حاكِ وقت التشغيل في الاختبارات:
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();

الاختبار باستخدام بدائل لكل مثيل

فضّل البدائل لكل مثيل على تعديل النموذج الأولي:
// Preferred: per-instance stub
const client = new MyChannelClient();
client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" });

// Avoid: prototype mutation
// MyChannelClient.prototype.sendMessage = vi.fn();

اختبارات العقد (Plugin داخل المستودع)

تملك Plugins المضمّنة اختبارات عقد تتحقق من ملكية التسجيل:
pnpm test -- src/plugins/contracts/
تؤكد هذه الاختبارات:
  • أي Plugins تسجّل أي موفّرين
  • أي Plugins تسجّل أي موفّري كلام
  • صحة شكل التسجيل
  • الامتثال لعقد وقت التشغيل

تشغيل اختبارات محددة النطاق

لـ Plugin محدد:
pnpm test -- <bundled-plugin-root>/my-channel/
لاختبارات العقد فقط:
pnpm test -- src/plugins/contracts/shape.contract.test.ts
pnpm test -- src/plugins/contracts/auth-choice.contract.test.ts
pnpm test -- src/plugins/contracts/runtime-seams.contract.test.ts

فرض الفحص الساكن (Plugins داخل المستودع)

يفرض pnpm check ثلاث قواعد على Plugins داخل المستودع:
  1. لا استيرادات جذرية موحّدة — يُرفض barrel الجذري openclaw/plugin-sdk
  2. لا استيرادات مباشرة من src/ — لا يمكن لـ Plugins استيراد ../../src/ مباشرةً
  3. لا استيرادات ذاتية — لا يمكن لـ Plugins استيراد مسارها الفرعي الخاص plugin-sdk/<name>
لا تخضع Plugins الخارجية لقواعد الفحص الساكن هذه، لكن يوصى باتباع الأنماط نفسها.

إعداد الاختبار

يستخدم OpenClaw Vitest مع حدود تغطية V8. لاختبارات Plugin:
# 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
إذا سبّبت عمليات التشغيل المحلية ضغطًا على الذاكرة:
OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test

ذات صلة