Przejdź do głównej treści
Dokumentacja narzędzi testowych, wzorców i wymuszania reguł lint dla pluginów OpenClaw.
Szukasz przykładów testów? Przewodniki how-to zawierają opracowane przykłady testów: Testy Plugin kanału oraz Testy Plugin dostawcy.

Narzędzia testowe

Te ścieżki podrzędne pomocników testowych są lokalnymi dla repozytorium punktami wejścia źródeł dla własnych testów dołączonych pluginów OpenClaw. Nie są eksportami pakietu dla pluginów zewnętrznych i mogą importować Vitest lub inne zależności testowe dostępne tylko w repozytorium. Import makiety API Plugin: openclaw/plugin-sdk/plugin-test-api Import kontraktu środowiska uruchomieniowego agenta: openclaw/plugin-sdk/agent-runtime-test-contracts Import kontraktu kanału: openclaw/plugin-sdk/channel-contract-testing Import pomocnika testów kanału: openclaw/plugin-sdk/channel-test-helpers Import testów celu kanału: openclaw/plugin-sdk/channel-target-testing Import kontraktu Plugin: openclaw/plugin-sdk/plugin-test-contracts Import testu środowiska uruchomieniowego Plugin: openclaw/plugin-sdk/plugin-test-runtime Import kontraktu dostawcy: openclaw/plugin-sdk/provider-test-contracts Import makiety HTTP dostawcy: openclaw/plugin-sdk/provider-http-test-mocks Import testów środowiska/sieci: openclaw/plugin-sdk/test-env Import ogólnego fixture: openclaw/plugin-sdk/test-fixtures Import makiety wbudowanego modułu Node: openclaw/plugin-sdk/test-node-mocks W repozytorium OpenClaw dla nowych testów dołączonych pluginów preferuj poniższe wyspecjalizowane ścieżki podrzędne. Szeroki barrel openclaw/plugin-sdk/testing służy wyłącznie starszej kompatybilności. Zabezpieczenia repozytorium odrzucają nowe rzeczywiste importy z plugin-sdk/testing i plugin-sdk/test-utils; te nazwy pozostają tylko jako przestarzałe powierzchnie kompatybilności dla testów rejestrów kompatybilności.
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";

Dostępne eksporty

EksportCel
createTestPluginApiZbuduj minimalną atrapę API Pluginu dla bezpośrednich testów jednostkowych rejestracji. Importuj z plugin-sdk/plugin-test-api
AUTH_PROFILE_RUNTIME_CONTRACTWspólna fixture kontraktu profilu uwierzytelniania dla natywnych adapterów środowiska uruchomieniowego agentów. Importuj z plugin-sdk/agent-runtime-test-contracts
DELIVERY_NO_REPLY_RUNTIME_CONTRACTWspólna fixture kontraktu tłumienia dostarczania dla natywnych adapterów środowiska uruchomieniowego agentów. Importuj z plugin-sdk/agent-runtime-test-contracts
OUTCOME_FALLBACK_RUNTIME_CONTRACTWspólna fixture kontraktu klasyfikacji fallback dla natywnych adapterów środowiska uruchomieniowego agentów. Importuj z plugin-sdk/agent-runtime-test-contracts
createParameterFreeToolZbuduj fixture schematów narzędzi dynamicznych dla testów kontraktu natywnego środowiska uruchomieniowego. Importuj z plugin-sdk/agent-runtime-test-contracts
expectChannelInboundContextContractZweryfikuj kształt kontekstu przychodzącego kanału. Importuj z plugin-sdk/channel-contract-testing
installChannelOutboundPayloadContractSuiteZainstaluj przypadki kontraktu wychodzącego payloadu kanału. Importuj z plugin-sdk/channel-contract-testing
createStartAccountContextZbuduj konteksty cyklu życia konta kanału. Importuj z plugin-sdk/channel-test-helpers
installChannelActionsContractSuiteZainstaluj ogólne przypadki kontraktu akcji wiadomości kanału. Importuj z plugin-sdk/channel-test-helpers
installChannelSetupContractSuiteZainstaluj ogólne przypadki kontraktu konfiguracji kanału. Importuj z plugin-sdk/channel-test-helpers
installChannelStatusContractSuiteZainstaluj ogólne przypadki kontraktu statusu kanału. Importuj z plugin-sdk/channel-test-helpers
expectDirectoryIdsZweryfikuj identyfikatory katalogu kanału z funkcji listowania katalogu. Importuj z plugin-sdk/channel-test-helpers
assertBundledChannelEntriesZweryfikuj, że dołączone punkty wejścia kanału udostępniają oczekiwany kontrakt publiczny. Importuj z plugin-sdk/channel-test-helpers
formatEnvelopeTimestampFormatuj deterministyczne znaczniki czasu koperty. Importuj z plugin-sdk/channel-test-helpers
expectPairingReplyTextZweryfikuj tekst odpowiedzi parowania kanału i wyodrębnij jego kod. Importuj z plugin-sdk/channel-test-helpers
describePluginRegistrationContractZainstaluj kontrole kontraktu rejestracji Pluginu. Importuj z plugin-sdk/plugin-test-contracts
registerSingleProviderPluginZarejestruj jeden Plugin dostawcy w testach dymnych loadera. Importuj z plugin-sdk/plugin-test-runtime
registerProviderPluginPrzechwyć wszystkie rodzaje dostawców z jednego Pluginu. Importuj z plugin-sdk/plugin-test-runtime
registerProviderPluginsPrzechwyć rejestracje dostawców w wielu Pluginach. Importuj z plugin-sdk/plugin-test-runtime
requireRegisteredProviderZweryfikuj, że kolekcja dostawców zawiera identyfikator. Importuj z plugin-sdk/plugin-test-runtime
createRuntimeEnvZbuduj zamockowane środowisko uruchomieniowe CLI/Pluginu. Importuj z plugin-sdk/plugin-test-runtime
createPluginRuntimeMockZbuduj zamockowaną powierzchnię środowiska uruchomieniowego Pluginu. Importuj z plugin-sdk/plugin-test-runtime
createPluginSetupWizardStatusZbuduj pomocniki statusu konfiguracji dla Pluginów kanałów. Importuj z plugin-sdk/plugin-test-runtime
describeOpenAIProviderRuntimeContractZainstaluj kontrole kontraktu środowiska uruchomieniowego rodziny dostawców. Importuj z plugin-sdk/provider-test-contracts
expectPassthroughReplayPolicyZweryfikuj, że zasady odtwarzania dostawcy przepuszczają narzędzia i metadane należące do dostawcy. Importuj z plugin-sdk/provider-test-contracts
runRealtimeSttLiveTestUruchom test live dostawcy STT czasu rzeczywistego ze wspólnymi fixture audio. Importuj z plugin-sdk/provider-test-contracts
normalizeTranscriptForMatchZnormalizuj wynik transkryptu live przed asercjami rozmytymi. Importuj z plugin-sdk/provider-test-contracts
expectExplicitVideoGenerationCapabilitiesZweryfikuj, że dostawcy wideo deklarują jawne możliwości trybu generowania. Importuj z plugin-sdk/provider-test-contracts
expectExplicitMusicGenerationCapabilitiesZweryfikuj, że dostawcy muzyki deklarują jawne możliwości generowania/edycji. Importuj z plugin-sdk/provider-test-contracts
mockSuccessfulDashscopeVideoTaskZainstaluj pomyślną odpowiedź zadania wideo zgodną z DashScope. Importuj z plugin-sdk/provider-test-contracts
getProviderHttpMocksUzyskaj dostęp do opcjonalnych mocków HTTP/auth dostawcy w Vitest. Importuj z plugin-sdk/provider-http-test-mocks
installProviderHttpMockCleanupResetuj mocki HTTP/auth dostawcy po każdym teście. Importuj z plugin-sdk/provider-http-test-mocks
installCommonResolveTargetErrorCasesWspólne przypadki testowe obsługi błędów rozwiązywania celu. Importuj z plugin-sdk/channel-target-testing
shouldAckReactionSprawdź, czy kanał powinien dodać reakcję potwierdzenia. Importuj z plugin-sdk/channel-feedback
removeAckReactionAfterReplyUsuń reakcję potwierdzenia po dostarczeniu odpowiedzi. Importuj z plugin-sdk/channel-feedback
createTestRegistryZbuduj fixture rejestru Pluginów kanałów. Importuj z plugin-sdk/plugin-test-runtime lub plugin-sdk/channel-test-helpers
createEmptyPluginRegistryZbuduj fixture pustego rejestru Pluginów. Importuj z plugin-sdk/plugin-test-runtime lub plugin-sdk/channel-test-helpers
setActivePluginRegistryZainstaluj fixture rejestru dla testów środowiska uruchomieniowego Pluginu. Importuj z plugin-sdk/plugin-test-runtime lub plugin-sdk/channel-test-helpers
createRequestCaptureJsonFetchPrzechwytuj żądania JSON fetch w testach pomocników mediów. Importuj z plugin-sdk/test-env
withServerUruchamiaj testy względem jednorazowego lokalnego serwera HTTP. Importuj z plugin-sdk/test-env
createMockIncomingRequestZbuduj minimalny obiekt przychodzącego żądania HTTP. Importuj z plugin-sdk/test-env
withFetchPreconnectUruchamiaj testy fetch z zainstalowanymi hookami preconnect. Importuj z plugin-sdk/test-env
withEnv / withEnvAsyncTymczasowo modyfikuj zmienne środowiskowe. Importuj z plugin-sdk/test-env
createTempHomeEnv / withTempHome / withTempDirTwórz izolowane fixture testowe systemu plików. Importuj z plugin-sdk/test-env
createMockServerResponseUtwórz minimalną atrapę odpowiedzi serwera HTTP. Importuj z plugin-sdk/test-env
createCliRuntimeCapturePrzechwytuj wynik środowiska uruchomieniowego CLI w testach. Importuj z plugin-sdk/test-fixtures
importFreshModuleImportuj moduł ESM ze świeżym tokenem zapytania, aby ominąć pamięć podręczną modułów. Importuj z plugin-sdk/test-fixtures
bundledPluginRoot / bundledPluginFileRozwiązuj ścieżki źródłowe dołączonego Pluginu lub ścieżki fixture dist. Importuj z plugin-sdk/test-fixtures
mockNodeBuiltinModuleZainstaluj wąskie mocki wbudowanych modułów Node w Vitest. Importuj z plugin-sdk/test-node-mocks
createSandboxTestContextZbuduj konteksty testów sandboxa. Importuj z plugin-sdk/test-fixtures
writeSkillZapisuj fixture Skills. Importuj z plugin-sdk/test-fixtures
makeAgentAssistantMessageZbuduj fixture wiadomości transkryptu agenta. Importuj z plugin-sdk/test-fixtures
peekSystemEvents / resetSystemEventsForTestSprawdzaj i resetuj fixture zdarzeń systemowych. Importuj z plugin-sdk/test-fixtures
sanitizeTerminalTextOczyszczaj wynik terminala na potrzeby asercji. Importuj z plugin-sdk/test-fixtures
countLines / hasBalancedFencesZweryfikuj kształt wyniku dzielenia na fragmenty. Importuj z plugin-sdk/test-fixtures
runProviderCatalogWykonaj hook katalogu dostawcy z zależnościami testowymi
resolveProviderWizardOptionsRozwiąż wybory kreatora konfiguracji dostawcy w testach kontraktu
resolveProviderModelPickerEntriesRozwiąż wpisy selektora modeli dostawcy w testach kontraktu
buildProviderPluginMethodChoiceZbuduj identyfikatory wyborów kreatora dostawcy dla asercji
setProviderWizardProvidersResolverForTestWstrzyknij dostawców kreatora dostawców na potrzeby izolowanych testów
createProviderUsageFetchZbuduj fixtures pobierania użycia dostawcy
useFrozenTime / useRealTimeZamroź i przywróć timery dla testów wrażliwych na czas. Importuj z plugin-sdk/test-env
createTestWizardPrompterZbuduj zamockowany prompter kreatora konfiguracji
createRuntimeTaskFlowUtwórz izolowany stan task-flow środowiska uruchomieniowego
typedCasesZachowaj typy literałów dla testów tabelarycznych. Importuj z plugin-sdk/test-fixtures
Zestawy testów kontraktów dla dołączonych pluginów używają też podścieżek testowych SDK dla pomocników fixture używanych wyłącznie w testach: rejestru, manifestu, artefaktu publicznego i runtime. Zestawy wyłącznie dla rdzenia, które zależą od dołączonego inwentarza OpenClaw, pozostają w src/plugins/contracts. Nowe testy rozszerzeń umieszczaj na udokumentowanej, wyspecjalizowanej podścieżce SDK, takiej jak 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 albo plugin-sdk/test-fixtures, zamiast importować bezpośrednio szeroki kompatybilnościowy barrel plugin-sdk/testing, pliki repozytorium src/** albo mostki repozytorium test/helpers/*.

Typy

Wyspecjalizowane podścieżki testowe ponownie eksportują też typy przydatne w plikach testowych:
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";

Rozwiązywanie celu testów

Użyj installCommonResolveTargetErrorCases, aby dodać standardowe przypadki błędów dla rozwiązywania celu kanału:
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", () => {
    // ...
  });
});

Wzorce testowania

Testowanie kontraktów rejestracji

Testy jednostkowe, które przekazują ręcznie napisany mock api do register(api), nie sprawdzają bramek akceptacji loadera OpenClaw. Dodaj co najmniej jeden test smoke oparty na loaderze dla każdej powierzchni rejestracji, od której zależy Twój plugin, szczególnie hooków i wyłącznych capabilities, takich jak pamięć. Rzeczywisty loader powoduje niepowodzenie rejestracji pluginu, gdy brakuje wymaganych metadanych albo gdy plugin wywołuje capability API, którego nie posiada. Na przykład api.registerHook(...) wymaga nazwy hooka, a api.registerMemoryCapability(...) wymaga, aby manifest pluginu albo eksportowany punkt wejścia deklarował kind: "memory".

Testowanie dostępu do konfiguracji runtime

Preferuj współdzielony mock runtime pluginu z openclaw/plugin-sdk/plugin-test-runtime. Jego przestarzałe mocki runtime.config.loadConfig() i runtime.config.writeConfigFile(...) domyślnie rzucają wyjątek, aby testy wychwytywały nowe użycia kompatybilnościowych API. Nadpisuj te mocki tylko wtedy, gdy test jawnie obejmuje starsze zachowanie kompatybilnościowe.

Testowanie jednostkowe pluginu kanału

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

Testowanie jednostkowe pluginu dostawcy

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

Mockowanie runtime pluginu

Dla kodu, który używa createPluginRuntimeStore, mockuj runtime w testach:
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();

Testowanie ze stubami na instancję

Preferuj stuby na instancję zamiast mutacji prototypu:
// Preferred: per-instance stub
const client = new MyChannelClient();
client.sendMessage = vi.fn().mockResolvedValue({ id: "msg-1" });

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

Testy kontraktów (pluginy w repozytorium)

Dołączone pluginy mają testy kontraktów, które weryfikują własność rejestracji:
pnpm test -- src/plugins/contracts/
Te testy sprawdzają:
  • Które pluginy rejestrują których dostawców
  • Które pluginy rejestrują których dostawców mowy
  • Poprawność kształtu rejestracji
  • Zgodność z kontraktem runtime

Uruchamianie testów o ograniczonym zakresie

Dla konkretnego pluginu:
pnpm test -- <bundled-plugin-root>/my-channel/
Tylko dla testów kontraktów:
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

Egzekwowanie lintowania (pluginy w repozytorium)

Trzy reguły są egzekwowane przez pnpm check dla pluginów w repozytorium:
  1. Brak monolitycznych importów z katalogu głównego — główny barrel openclaw/plugin-sdk jest odrzucany
  2. Brak bezpośrednich importów z src/ — pluginy nie mogą bezpośrednio importować ../../src/
  3. Brak samoimportów — pluginy nie mogą importować własnej podścieżki plugin-sdk/<name>
Pluginy zewnętrzne nie podlegają tym regułom lintowania, ale zaleca się stosowanie tych samych wzorców.

Konfiguracja testów

OpenClaw używa Vitest z progami pokrycia V8. Dla testów pluginów:
# 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
Jeśli lokalne uruchomienia powodują presję na pamięć:
OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test

Powiązane