80 KiB
| read_when | summary | title | x-i18n | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Набір тестування: набори unit/e2e/live, ранери Docker і що охоплює кожен тест | Тестування |
|
OpenClaw має три набори Vitest (unit/integration, e2e, live) і невеликий набір ранерів Docker. Цей документ — посібник «як ми тестуємо»:
- Що охоплює кожен набір (і що він навмисно не охоплює).
- Які команди запускати для типових сценаріїв роботи (локально, перед push, налагодження).
- Як live-тести знаходять облікові дані та вибирають моделі/провайдерів.
- Як додавати регресійні тести для реальних проблем із моделями/провайдерами.
Швидкий старт
У більшості випадків:
- Повний gate (очікується перед push):
pnpm build && pnpm check && pnpm check:test-types && pnpm test - Швидший локальний запуск повного набору на потужній машині:
pnpm test:max - Прямий цикл спостереження Vitest:
pnpm test:watch - Прямий таргетинг файлу тепер також маршрутизує шляхи extension/channel:
pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts - Під час ітерацій над однією проблемою спочатку віддавайте перевагу цільовим запускам.
- QA-сайт на базі Docker:
pnpm qa:lab:up - QA lane на базі Linux VM:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
Коли ви змінюєте тести або хочете додаткової впевненості:
- Gate покриття:
pnpm test:coverage - Набір E2E:
pnpm test:e2e
Під час налагодження реальних провайдерів/моделей (потрібні реальні облікові дані):
- Набір live (моделі + зондування tool/image через Gateway):
pnpm test:live - Тихо націлити один live-файл:
pnpm test:live -- src/agents/models.profiles.live.test.ts - Docker sweep live-моделей:
pnpm test:docker:live-models- Кожна вибрана модель тепер виконує текстовий хід плюс невелике зондування у стилі читання файлу.
Моделі, чиї метадані вказують на вхід
image, також виконують невеликий хід із зображенням. Вимкніть додаткові зондування черезOPENCLAW_LIVE_MODEL_FILE_PROBE=0абоOPENCLAW_LIVE_MODEL_IMAGE_PROBE=0, коли ізолюєте збої провайдера. - Покриття в CI: щоденні
OpenClaw Scheduled Live And E2E Checksі ручніOpenClaw Release Checksобидва викликають повторно використовуваний workflow live/E2E зinclude_live_suites: true, який включає окремі matrix jobs Docker live-моделей, розбиті за провайдерами. - Для точкових повторних запусків у CI викликайте
OpenClaw Live And E2E Checks (Reusable)зinclude_live_suites: trueіlive_models_only: true. - Додавайте нові високосигнальні секрети провайдерів до
scripts/ci-hydrate-live-auth.sh, а також до.github/workflows/openclaw-live-and-e2e-checks-reusable.ymlі його викликів зі schedule/release.
- Кожна вибрана модель тепер виконує текстовий хід плюс невелике зондування у стилі читання файлу.
Моделі, чиї метадані вказують на вхід
- Native Codex smoke для bound-chat:
pnpm test:docker:live-codex-bind- Запускає Docker live lane проти шляху Codex app-server, прив’язує синтетичний
Slack DM через
/codex bind, виконує/codex fastі/codex permissions, а потім перевіряє, що звичайна відповідь і вкладення-зображення проходять через native Plugin binding, а не через ACP.
- Запускає Docker live lane проти шляху Codex app-server, прив’язує синтетичний
Slack DM через
- Smoke команди rescue для Crestodian:
pnpm test:live:crestodian-rescue-channel- Необов’язкова додаткова перевірка поверхні команди rescue для message-channel.
Вона виконує
/crestodian status, ставить у чергу стійку зміну моделі, відповідає/crestodian yesі перевіряє шлях запису audit/config.
- Необов’язкова додаткова перевірка поверхні команди rescue для message-channel.
Вона виконує
- Docker smoke planner для Crestodian:
pnpm test:docker:crestodian-planner- Запускає Crestodian у контейнері без конфігурації з фальшивим Claude CLI у
PATHі перевіряє, що нечіткий fallback planner перетворюється на audited typed запис у конфігурацію.
- Запускає Crestodian у контейнері без конфігурації з фальшивим Claude CLI у
- Docker smoke першого запуску для Crestodian:
pnpm test:docker:crestodian-first-run- Стартує з порожнього каталогу стану OpenClaw, маршрутизує голий
openclawдо Crestodian, застосовує записи setup/model/agent/Discord Plugin + SecretRef, перевіряє конфігурацію та записи audit. Той самий шлях налаштування Ring 0 також охоплюється в QA Lab черезpnpm openclaw qa suite --scenario crestodian-ring-zero-setup.
- Стартує з порожнього каталогу стану OpenClaw, маршрутизує голий
- Smoke перевірка вартості Moonshot/Kimi: якщо встановлено
MOONSHOT_API_KEY, виконайтеopenclaw models list --provider moonshot --json, потім виконайте ізольованийopenclaw agent --local --session-id live-kimi-cost --message 'Reply exactly: KIMI_LIVE_OK' --thinking off --jsonпротиmoonshot/kimi-k2.6. Перевірте, що JSON повідомляє Moonshot/K2.6 і що transcript асистента зберігає нормалізованеusage.cost.
Порада: коли вам потрібен лише один збійний випадок, віддавайте перевагу звуженню live-тестів через env-змінні allowlist, описані нижче.
Спеціальні ранери для QA
Ці команди стоять поруч з основними наборами тестів, коли вам потрібен реалізм QA-lab:
CI запускає QA Lab в окремих workflow. Parity gate запускається для відповідних PR
і через ручний dispatch з mock-провайдерами. QA-Lab - All Lanes запускається щоночі на
main і через ручний dispatch із mock parity gate, live Matrix lane і
керованим Convex live Telegram lane як паралельними jobs. OpenClaw Release Checks
запускає ті самі lane перед затвердженням релізу.
-
pnpm openclaw qa suite- Запускає сценарії QA на базі репозиторію безпосередньо на хості.
- За замовчуванням запускає кілька вибраних сценаріїв паралельно з ізольованими
worker-и Gateway. Для
qa-channelтиповим є concurrency 4 (обмежується кількістю вибраних сценаріїв). Використовуйте--concurrency <count>для налаштування кількості worker-ів або--concurrency 1для старішого послідовного lane. - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте
--allow-failures, коли вам потрібні артефакти без коду завершення з помилкою. - Підтримує режими провайдерів
live-frontier,mock-openaiіaimock.aimockзапускає локальний сервер провайдера на базі AIMock для експериментального покриття фікстур і protocol-mock без заміни lanemock-openai, орієнтованого на сценарії.
-
pnpm openclaw qa suite --runner multipass- Запускає той самий QA suite всередині тимчасової Linux VM Multipass.
- Зберігає ту саму поведінку вибору сценаріїв, що й
qa suiteна хості. - Повторно використовує ті самі прапорці вибору провайдера/моделі, що й
qa suite. - Live-запуски передають підтримувані вхідні дані автентифікації QA, практичні для guest:
ключі провайдерів через env, шлях до конфігурації live-провайдера QA і
CODEX_HOME, якщо він наявний. - Каталоги виводу мають залишатися під коренем репозиторію, щоб guest міг записувати назад через змонтований робочий простір.
- Записує звичайний звіт і підсумок QA, а також логи Multipass у
.artifacts/qa-e2e/....
-
pnpm qa:lab:up- Запускає QA-сайт на базі Docker для операторської роботи в QA.
-
pnpm test:docker:npm-onboard-channel-agent- Збирає npm tarball з поточного checkout, глобально встановлює його в Docker, виконує неінтерактивний onboarding з ключем OpenAI API, за замовчуванням налаштовує Telegram, перевіряє, що ввімкнення Plugin встановлює runtime-залежності на вимогу, запускає doctor і один локальний хід агента проти mocked OpenAI endpoint.
- Використовуйте
OPENCLAW_NPM_ONBOARD_CHANNEL=discord, щоб запустити той самий lane пакетного встановлення з Discord.
-
pnpm test:docker:session-runtime-context- Запускає детермінований Docker smoke для зібраного застосунку для transcript-ів із
вбудованим runtime context. Перевіряє, що прихований runtime context OpenClaw
зберігається як недоступне для відображення кастомне повідомлення замість витоку у видимий хід користувача,
потім підставляє уражений зламаний JSONL сесії та перевіряє, що
openclaw doctor --fixпереписує його в активну гілку з резервною копією.
- Запускає детермінований Docker smoke для зібраного застосунку для transcript-ів із
вбудованим runtime context. Перевіряє, що прихований runtime context OpenClaw
зберігається як недоступне для відображення кастомне повідомлення замість витоку у видимий хід користувача,
потім підставляє уражений зламаний JSONL сесії та перевіряє, що
-
pnpm test:docker:npm-telegram-live- Встановлює опублікований пакет OpenClaw у Docker, виконує onboarding встановленого пакета, налаштовує Telegram через встановлений CLI, а потім повторно використовує QA lane live Telegram із цим встановленим пакетом як SUT Gateway.
- За замовчуванням використовується
OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@beta. - Використовує ті самі env-облікові дані Telegram або джерело облікових даних Convex, що й
pnpm openclaw qa telegram. Для автоматизації CI/release встановітьOPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex, а такожOPENCLAW_QA_CONVEX_SITE_URLі role secret. ЯкщоOPENCLAW_QA_CONVEX_SITE_URLі secret ролі Convex присутні в CI, обгортка Docker автоматично вибирає Convex. OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci|maintainerперевизначає спільнийOPENCLAW_QA_CREDENTIAL_ROLEлише для цього lane.- GitHub Actions надає цей lane як ручний workflow для мейнтейнерів
NPM Telegram Beta E2E. Він не запускається при merge. Workflow використовує середовищеqa-live-sharedі оренду облікових даних Convex CI.
-
pnpm test:docker:bundled-channel-deps- Пакує та встановлює поточну збірку OpenClaw у Docker, запускає Gateway зі сконфігурованим OpenAI, а потім вмикає bundled channel/plugins через зміни конфігурації.
- Перевіряє, що виявлення setup залишає runtime-залежності не налаштованих Plugin відсутніми, що перший налаштований запуск Gateway або doctor встановлює runtime-залежності кожного bundled Plugin на вимогу, і що другий restart не перевстановлює залежності, які вже були активовані.
- Також встановлює відому старішу npm-базову версію, вмикає Telegram перед запуском
openclaw update --tag <candidate>, а потім перевіряє, що post-update doctor у candidate відновлює runtime-залежності bundled channel без postinstall-виправлення з боку harness.
-
pnpm test:parallels:npm-update-
Запускає native smoke оновлення пакетного встановлення в guest-системах Parallels. Для кожної вибраної платформи спочатку встановлюється потрібний базовий пакет, а потім у тій самій guest-системі запускається встановлена команда
openclaw updateі перевіряються встановлена версія, статус оновлення, готовність Gateway і один локальний хід агента. -
Під час ітерацій над однією guest-системою використовуйте
--platform macos,--platform windowsабо--platform linux. Використовуйте--jsonдля шляху до підсумкового артефакту і статусу кожного lane. -
Обгортайте довгі локальні запуски в host timeout, щоб зависання транспорту Parallels не з’їли решту вікна тестування:
timeout --foreground 150m pnpm test:parallels:npm-update -- --json timeout --foreground 90m pnpm test:parallels:npm-update -- --platform windows --json -
Скрипт записує вкладені логи lane у
/tmp/openclaw-parallels-npm-update.*. Перевіряйтеwindows-update.log,macos-update.logабоlinux-update.log, перш ніж припускати, що зовнішня обгортка зависла. -
Оновлення Windows може витрачати від 10 до 15 хвилин на post-update doctor/runtime repair залежностей на холодній guest-системі; це все ще нормальний стан, якщо вкладений npm debug log продовжує оновлюватися.
-
Не запускайте цю агреговану обгортку паралельно з окремими smoke lane Parallels для macOS, Windows або Linux. Вони спільно використовують стан VM і можуть конфліктувати під час відновлення snapshot, обслуговування пакетів або стану guest Gateway.
-
Post-update proof запускає звичайну поверхню bundled Plugin, оскільки capability facades, такі як speech, генерація зображень і розуміння медіа, завантажуються через bundled runtime API, навіть коли сам хід агента перевіряє лише просту текстову відповідь.
-
-
pnpm openclaw qa aimock- Запускає лише локальний сервер провайдера AIMock для прямого smoke-тестування протоколу.
-
pnpm openclaw qa matrix- Запускає live QA lane Matrix проти тимчасового homeserver Tuwunel на базі Docker.
- Цей QA host наразі призначений лише для repo/dev. Пакетні встановлення OpenClaw не постачають
qa-lab, тому не відкриваютьopenclaw qa. - Checkout-и репозиторію завантажують bundled runner напряму; окремий крок встановлення Plugin не потрібен.
- Створює трьох тимчасових користувачів Matrix (
driver,sut,observer) плюс одну приватну кімнату, а потім запускає дочірній QA gateway з реальним Plugin Matrix як транспортом SUT. - За замовчуванням використовує зафіксований стабільний образ Tuwunel
ghcr.io/matrix-construct/tuwunel:v1.5.1. Перевизначайте черезOPENCLAW_QA_MATRIX_TUWUNEL_IMAGE, коли потрібно протестувати інший образ. - Matrix не надає спільних прапорців джерела облікових даних, оскільки lane локально створює тимчасових користувачів.
- Записує звіт Matrix QA, підсумок, артефакт observed-events і об’єднаний лог виводу stdout/stderr у
.artifacts/qa-e2e/.... - За замовчуванням виводить прогрес і примусово застосовує жорсткий timeout виконання через
OPENCLAW_QA_MATRIX_TIMEOUT_MS(типово 30 хвилин). Очищення обмежуєтьсяOPENCLAW_QA_MATRIX_CLEANUP_TIMEOUT_MS, а у випадку збоїв включається команда відновленняdocker compose ... down --remove-orphans.
-
pnpm openclaw qa telegram- Запускає live QA lane Telegram проти реальної приватної групи, використовуючи токени ботів driver і SUT з env.
- Потребує
OPENCLAW_QA_TELEGRAM_GROUP_ID,OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKENіOPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN. Ідентифікатор групи має бути числовим chat id Telegram. - Підтримує
--credential-source convexдля спільних пулованих облікових даних. За замовчуванням використовуйте режим env або встановітьOPENCLAW_QA_CREDENTIAL_SOURCE=convex, щоб перейти на пуловані lease. - Завершується з ненульовим кодом, якщо будь-який сценарій зазнав невдачі. Використовуйте
--allow-failures, коли вам потрібні артефакти без коду завершення з помилкою. - Потребує двох різних ботів в одній приватній групі, причому бот SUT має мати username Telegram.
- Для стабільного спостереження bot-to-bot увімкніть Bot-to-Bot Communication Mode у
@BotFatherдля обох ботів і переконайтеся, що бот driver може спостерігати трафік ботів у групі. - Записує звіт Telegram QA, підсумок і артефакт observed-messages у
.artifacts/qa-e2e/.... Сценарії з відповідями включають RTT від запиту на надсилання від driver до спостережуваної відповіді SUT.
Live transport lane використовують один стандартний контракт, щоб нові транспорти не розходилися:
qa-channel залишається широким синтетичним набором QA і не входить до матриці покриття live transport.
| Lane | Canary | Фільтрація за згадуванням | Блокування allowlist | Відповідь верхнього рівня | Відновлення після restart | Подальша відповідь у треді | Ізоляція тредів | Спостереження за реакціями | Команда help |
|---|---|---|---|---|---|---|---|---|---|
| Matrix | x | x | x | x | x | x | x | x | |
| Telegram | x | x |
Спільні облікові дані Telegram через Convex (v1)
Коли для openclaw qa telegram увімкнено --credential-source convex (або OPENCLAW_QA_CREDENTIAL_SOURCE=convex),
QA lab отримує ексклюзивний lease із пулу на базі Convex, надсилає Heartbeat
для цього lease, поки lane виконується, і звільняє lease під час завершення роботи.
Еталонний scaffold проєкту Convex:
qa/convex-credential-broker/
Обов’язкові env-змінні:
OPENCLAW_QA_CONVEX_SITE_URL(наприклад,https://your-deployment.convex.site)- Один секрет для вибраної ролі:
OPENCLAW_QA_CONVEX_SECRET_MAINTAINERдляmaintainerOPENCLAW_QA_CONVEX_SECRET_CIдляci
- Вибір ролі облікових даних:
- CLI:
--credential-role maintainer|ci - Типове значення env:
OPENCLAW_QA_CREDENTIAL_ROLE(типовоciу CI, інакшеmaintainer)
- CLI:
Необов’язкові env-змінні:
OPENCLAW_QA_CREDENTIAL_LEASE_TTL_MS(типово1200000)OPENCLAW_QA_CREDENTIAL_HEARTBEAT_INTERVAL_MS(типово30000)OPENCLAW_QA_CREDENTIAL_ACQUIRE_TIMEOUT_MS(типово90000)OPENCLAW_QA_CREDENTIAL_HTTP_TIMEOUT_MS(типово15000)OPENCLAW_QA_CONVEX_ENDPOINT_PREFIX(типово/qa-credentials/v1)OPENCLAW_QA_CREDENTIAL_OWNER_ID(необов’язковий trace id)OPENCLAW_QA_ALLOW_INSECURE_HTTP=1дозволяє loopback URL Convexhttp://лише для локальної розробки.
У звичайному режимі роботи OPENCLAW_QA_CONVEX_SITE_URL має використовувати https://.
Адміністративні команди мейнтейнера (додавання/видалення/список пулу) потребують
саме OPENCLAW_QA_CONVEX_SECRET_MAINTAINER.
CLI-хелпери для мейнтейнерів:
pnpm openclaw qa credentials doctor
pnpm openclaw qa credentials add --kind telegram --payload-file qa/telegram-credential.json
pnpm openclaw qa credentials list --kind telegram
pnpm openclaw qa credentials remove --credential-id <credential-id>
Використовуйте doctor перед live-запусками, щоб перевірити URL сайту Convex, секрети брокера,
префікс endpoint, HTTP timeout і доступність admin/list без виведення
значень секретів. Використовуйте --json для машиночитаного виводу в скриптах і CI
утилітах.
Контракт endpoint за замовчуванням (OPENCLAW_QA_CONVEX_SITE_URL + /qa-credentials/v1):
POST /acquire- Запит:
{ kind, ownerId, actorRole, leaseTtlMs, heartbeatIntervalMs } - Успіх:
{ status: "ok", credentialId, leaseToken, payload, leaseTtlMs?, heartbeatIntervalMs? } - Вичерпано/можна повторити:
{ status: "error", code: "POOL_EXHAUSTED" | "NO_CREDENTIAL_AVAILABLE", ... }
- Запит:
POST /heartbeat- Запит:
{ kind, ownerId, actorRole, credentialId, leaseToken, leaseTtlMs } - Успіх:
{ status: "ok" }(або порожній2xx)
- Запит:
POST /release- Запит:
{ kind, ownerId, actorRole, credentialId, leaseToken } - Успіх:
{ status: "ok" }(або порожній2xx)
- Запит:
POST /admin/add(лише секрет maintainer)- Запит:
{ kind, actorId, payload, note?, status? } - Успіх:
{ status: "ok", credential }
- Запит:
POST /admin/remove(лише секрет maintainer)- Запит:
{ credentialId, actorId } - Успіх:
{ status: "ok", changed, credential } - Захист активного lease:
{ status: "error", code: "LEASE_ACTIVE", ... }
- Запит:
POST /admin/list(лише секрет maintainer)- Запит:
{ kind?, status?, includePayload?, limit? } - Успіх:
{ status: "ok", credentials, count }
- Запит:
Форма payload для типу Telegram:
{ groupId: string, driverToken: string, sutToken: string }groupIdмає бути рядком із числовим chat id Telegram.admin/addперевіряє цю форму дляkind: "telegram"і відхиляє некоректні payload.
Додавання каналу до QA
Додавання каналу до markdown-системи QA потребує рівно двох речей:
- Транспортний адаптер для каналу.
- Пакет сценаріїв, який перевіряє контракт каналу.
Не додавайте новий кореневий top-level-командний простір QA, якщо спільний host qa-lab
може керувати цим потоком.
qa-lab керує спільною механікою host:
- кореневою командою
openclaw qa - запуском і завершенням suite
- паралелізмом worker-ів
- записом артефактів
- генерацією звітів
- виконанням сценаріїв
- alias сумісності для старіших сценаріїв
qa-channel
Runner Plugin володіють транспортним контрактом:
- як
openclaw qa <runner>монтується під спільним коренемqa - як Gateway конфігурується для цього транспорту
- як перевіряється готовність
- як інжектуються вхідні події
- як спостерігаються вихідні повідомлення
- як надаються transcript-и й нормалізований транспортний стан
- як виконуються дії, прив’язані до транспорту
- як обробляються транспортно-специфічні reset або cleanup
Мінімальний поріг прийняття для нового каналу:
- Залишити
qa-labвласником спільного кореняqa. - Реалізувати transport runner на спільному seam host
qa-lab. - Залишити транспортно-специфічну механіку всередині runner Plugin або harness каналу.
- Монтувати runner як
openclaw qa <runner>замість реєстрації конкуруючої кореневої команди. Runner Plugin мають оголошуватиqaRunnersуopenclaw.plugin.jsonі експортувати відповідний масивqaRunnerCliRegistrationsізruntime-api.ts. Залишайтеruntime-api.tsлегким; ліниве виконання CLI і runner має бути винесене за окремі entrypoint. - Створювати або адаптувати markdown-сценарії в тематичних каталогах
qa/scenarios/. - Для нових сценаріїв використовувати загальні scenario helper-и.
- Зберігати працездатність наявних alias сумісності, якщо тільки репозиторій не виконує навмисну міграцію.
Правило ухвалення рішення суворе:
- Якщо поведінку можна один раз виразити в
qa-lab, розміщуйте її вqa-lab. - Якщо поведінка залежить від одного транспортного каналу, залишайте її в runner Plugin або harness цього Plugin.
- Якщо сценарію потрібна нова можливість, яку може використовувати більше ніж один канал, додавайте загальний helper замість channel-specific гілки в
suite.ts. - Якщо поведінка має сенс лише для одного транспорту, залишайте сценарій транспортно-специфічним і явно фіксуйте це в контракті сценарію.
Для нових сценаріїв бажані назви загальних helper-ів:
waitForTransportReadywaitForChannelReadyinjectInboundMessageinjectOutboundMessagewaitForTransportOutboundMessagewaitForChannelOutboundMessagewaitForNoTransportOutboundgetTransportSnapshotreadTransportMessagereadTransportTranscriptformatTransportTranscriptresetTransport
Alias сумісності залишаються доступними для наявних сценаріїв, зокрема:
waitForQaChannelReadywaitForOutboundMessagewaitForNoOutboundformatConversationTranscriptresetBus
Нова робота над каналами має використовувати загальні назви helper-ів. Alias сумісності існують, щоб уникнути міграції «в один день», а не як модель для створення нових сценаріїв.
Набори тестів (що де запускається)
Сприймайте набори як «зростання реалізму» (і зростання нестабільності/вартості):
Unit / integration (типово)
- Команда:
pnpm test - Конфігурація: нетаргетовані запуски використовують набір shard
vitest.full-*.config.tsі можуть розгортати multi-project shard-и в конфігурації для окремих проєктів для паралельного планування - Файли: інвентарі core/unit у
src/**/*.test.ts,packages/**/*.test.ts,test/**/*.test.tsі whitelisted node-тестиui, які охоплюютьсяvitest.unit.config.ts - Обсяг:
- Чисті unit-тести
- In-process integration-тести (автентифікація Gateway, маршрутизація, tooling, парсинг, конфігурація)
- Детерміновані регресії для відомих багів
- Очікування:
- Запускається в CI
- Реальні ключі не потрібні
- Має бути швидким і стабільним
- Нетаргетований `pnpm test` запускає дванадцять менших конфігурацій shard (`core-unit-fast`, `core-unit-src`, `core-unit-security`, `core-unit-ui`, `core-unit-support`, `core-support-boundary`, `core-contracts`, `core-bundled`, `core-runtime`, `agentic`, `auto-reply`, `extensions`) замість одного гігантського native root-project процесу. Це зменшує піковий RSS на завантажених машинах і не дає роботі auto-reply/extension витісняти не пов’язані набори.
- `pnpm test --watch` усе ще використовує native root-граф проєктів `vitest.config.ts`, оскільки цикл watch із кількома shard не є практичним.
- `pnpm test`, `pnpm test:watch` і `pnpm test:perf:imports` спочатку маршрутизують явні цілі файлів/каталогів через scoped lane, тож `pnpm test extensions/discord/src/monitor/message-handler.preflight.test.ts` уникає повної вартості запуску root project.
- `pnpm test:changed` розгортає змінені git-шляхи в ті самі scoped lane, коли diff зачіпає лише routable файли джерел/тестів; редагування config/setup усе ще повертаються до широкого повторного запуску root-project.
- `pnpm check:changed` — це звичайний розумний локальний gate для вузької роботи. Він класифікує diff на core, core tests, extensions, extension tests, apps, docs, release metadata і tooling, а потім запускає відповідні lane typecheck/lint/test. Зміни в публічному Plugin SDK і plugin-contract включають один прохід валідації extension, оскільки extensions залежать від цих контрактів core. Підвищення версії лише в release metadata запускають цільові перевірки version/config/root-dependency замість повного набору, із захистом, який відхиляє зміни пакета поза полем версії верхнього рівня.
- Unit-тести з легкими імпортами з agents, commands, plugins, helper-ів auto-reply, `plugin-sdk` і подібних чистих утилітних областей маршрутизуються через lane `unit-fast`, який пропускає `test/setup-openclaw-runtime.ts`; файли зі станом/важким runtime залишаються в наявних lane.
- Вибрані helper-вихідники `plugin-sdk` і `commands` також зіставляють запуски в режимі changed з явними сусідніми тестами в цих легких lane, тож редагування helper-ів уникають повторного запуску повного важкого набору для цього каталогу.
- `auto-reply` має окремі кошики для top-level helper-ів core, top-level integration-тестів `reply.*` і піддерева `src/auto-reply/reply/**`. CI додатково розділяє піддерево reply на shard agent-runner, dispatch і commands/state-routing, щоб один кошик із важкими імпортами не контролював увесь tail Node.
- Коли ви змінюєте вхідні дані виявлення message-tool або runtime
context Compaction, зберігайте обидва рівні покриття.
- Додавайте сфокусовані регресії helper-ів для чистих меж маршрутизації та
нормалізації.
- Підтримуйте інтеграційні набори embedded runner у здоровому стані:
`src/agents/pi-embedded-runner/compact.hooks.test.ts`,
`src/agents/pi-embedded-runner/run.overflow-compaction.test.ts` і
`src/agents/pi-embedded-runner/run.overflow-compaction.loop.test.ts`.
- Ці набори перевіряють, що scoped id і поведінка compaction все ще проходять
через реальні шляхи `run.ts` / `compact.ts`; тести лише helper-ів
не є достатньою заміною для цих інтеграційних шляхів.
- Базова конфігурація Vitest типово використовує `threads`.
- Спільна конфігурація Vitest фіксує `isolate: false` і використовує
неізольований runner у root projects, e2e і live config.
- Root lane UI зберігає свій `jsdom` setup і optimizer, але теж запускається на
спільному неізольованому runner.
- Кожен shard `pnpm test` успадковує ті самі типові значення `threads` + `isolate: false`
зі спільної конфігурації Vitest.
- `scripts/run-vitest.mjs` типово додає `--no-maglev` для дочірніх процесів Node Vitest,
щоб зменшити churn компіляції V8 під час великих локальних запусків.
Встановіть `OPENCLAW_VITEST_ENABLE_MAGLEV=1`, щоб порівняти зі стандартною
поведінкою V8.
- `pnpm changed:lanes` показує, які архітектурні lane зачіпає diff.
- Pre-commit hook виконує лише форматування. Він знову додає відформатовані файли до stage і
не запускає lint, typecheck або тести.
- Явно запускайте `pnpm check:changed` перед передачею роботи або push, коли
вам потрібен розумний локальний gate. Зміни в публічному Plugin SDK і plugin-contract
включають один прохід валідації extension.
- `pnpm test:changed` маршрутизує через scoped lane, коли змінені шляхи
чітко зіставляються з меншим набором.
- `pnpm test:max` і `pnpm test:changed:max` зберігають ту саму поведінку маршрутизації,
лише з вищим лімітом worker-ів.
- Автомасштабування локальних worker-ів навмисно є консервативним і зменшує навантаження,
коли середнє навантаження хоста вже високе, тож кілька одночасних
запусків Vitest типово завдають менше шкоди.
- Базова конфігурація Vitest позначає файли projects/config як
`forceRerunTriggers`, щоб повторні запуски в режимі changed залишалися коректними, коли
змінюється зв’язування тестів.
- Конфігурація зберігає `OPENCLAW_VITEST_FS_MODULE_CACHE` увімкненим на підтримуваних
хостах; встановіть `OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=/abs/path`, якщо хочете
мати одну явну локацію кешу для прямого профілювання.
- `pnpm test:perf:imports` вмикає звітування Vitest про тривалість імпортів плюс
вивід детального розбору імпортів.
- `pnpm test:perf:imports:changed` обмежує той самий режим профілювання
файлами, зміненими відносно `origin/main`.
- Дані часу shard записуються до `.artifacts/vitest-shard-timings.json`.
Запуски всієї конфігурації використовують шлях конфігурації як ключ; shard-и CI з include-pattern
додають назву shard, щоб відфільтровані shard можна було відстежувати
окремо.
- Коли один гарячий тест усе ще витрачає більшість часу на стартові імпорти,
тримайте важкі залежності за вузьким локальним seam `*.runtime.ts` і
напряму mock-айте цей seam замість глибокого імпорту helper-ів runtime
лише для того, щоб передати їх у `vi.mock(...)`.
- `pnpm test:perf:changed:bench -- --ref <git-ref>` порівнює маршрутизований
`test:changed` з native шляхом root-project для цього зафіксованого
diff і виводить wall time плюс macOS max RSS.
- `pnpm test:perf:changed:bench -- --worktree` вимірює поточне брудне дерево,
маршрутизуючи список змінених файлів через
`scripts/test-projects.mjs` і root-конфігурацію Vitest.
- `pnpm test:perf:profile:main` записує профіль CPU основного потоку для
накладних витрат старту та transform у Vitest/Vite.
- `pnpm test:perf:profile:runner` записує профілі CPU+heap runner-а для
unit-набору з вимкненим паралелізмом файлів.
Стабільність (Gateway)
- Команда:
pnpm test:stability:gateway - Конфігурація:
vitest.gateway.config.ts, примусово один worker - Обсяг:
- Запускає реальний loopback Gateway з діагностикою, увімкненою за замовчуванням
- Проганяє синтетичне навантаження повідомленнями gateway, пам’яттю та великими payload через шлях діагностичних подій
- Виконує запит до
diagnostics.stabilityчерез WS RPC Gateway - Охоплює helper-и збереження пакета діагностичної стабільності
- Перевіряє, що recorder залишається обмеженим, синтетичні зразки RSS лишаються в межах бюджету тиску, а глибини черг на сесію знову зменшуються до нуля
- Очікування:
- Безпечно для CI і не потребує ключів
- Вузький lane для подальшої роботи над регресіями стабільності, а не заміна повного набору Gateway
E2E (smoke для gateway)
- Команда:
pnpm test:e2e - Конфігурація:
vitest.e2e.config.ts - Файли:
src/**/*.e2e.test.ts,test/**/*.e2e.test.tsі bundled-plugin E2E-тести вextensions/ - Типові параметри runtime:
- Використовує
threadsVitest зisolate: false, як і решта репозиторію. - Використовує адаптивну кількість worker-ів (CI: до 2, локально: 1 за замовчуванням).
- За замовчуванням запускається в тихому режимі, щоб зменшити накладні витрати на вивід у консоль.
- Використовує
- Корисні перевизначення:
OPENCLAW_E2E_WORKERS=<n>, щоб примусово задати кількість worker-ів (обмежено 16).OPENCLAW_E2E_VERBOSE=1, щоб знову ввімкнути детальний вивід у консоль.
- Обсяг:
- Наскрізна поведінка gateway з кількома екземплярами
- Поверхні WebSocket/HTTP, спарювання Node і важчий мережевий стек
- Очікування:
- Запускається в CI (коли увімкнено в pipeline)
- Реальні ключі не потрібні
- Більше рухомих частин, ніж у unit-тестах (може бути повільніше)
E2E: smoke для backend OpenShell
- Команда:
pnpm test:e2e:openshell - Файл:
extensions/openshell/src/backend.e2e.test.ts - Обсяг:
- Запускає ізольований Gateway OpenShell на хості через Docker
- Створює sandbox із тимчасового локального Dockerfile
- Перевіряє backend OpenShell у OpenClaw через реальні
sandbox ssh-config+ SSH exec - Перевіряє remote-canonical поведінку файлової системи через sandbox fs bridge
- Очікування:
- Лише opt-in; не входить до типового запуску
pnpm test:e2e - Потребує локальний CLI
openshellі робочий Docker daemon - Використовує ізольовані
HOME/XDG_CONFIG_HOME, після чого знищує тестовий gateway і sandbox
- Лише opt-in; не входить до типового запуску
- Корисні перевизначення:
OPENCLAW_E2E_OPENSHELL=1, щоб увімкнути тест під час ручного запуску ширшого набору e2eOPENCLAW_E2E_OPENSHELL_COMMAND=/path/to/openshell, щоб вказати нестандартний бінарний файл CLI або wrapper-скрипт
Live (реальні провайдери + реальні моделі)
- Команда:
pnpm test:live - Конфігурація:
vitest.live.config.ts - Файли:
src/**/*.live.test.ts,test/**/*.live.test.tsі bundled-plugin live-тести вextensions/ - Типово: увімкнено через
pnpm test:live(встановлюєOPENCLAW_LIVE_TEST=1) - Обсяг:
- «Чи справді цей провайдер/модель працює сьогодні з реальними обліковими даними?»
- Виявляє зміни формату провайдера, особливості виклику tool, проблеми автентифікації та поведінку rate limit
- Очікування:
- За задумом не є стабільним для CI (реальні мережі, реальні політики провайдерів, квоти, збої)
- Коштує грошей / використовує rate limit
- Краще запускати звужені підмножини, а не «все»
- Live-запуски використовують
~/.profile, щоб підхопити відсутні API-ключі. - За замовчуванням live-запуски все одно ізолюють
HOMEі копіюють матеріали config/auth у тимчасовий тестовий home, щоб unit-фікстури не могли змінити ваш реальний~/.openclaw. - Встановлюйте
OPENCLAW_LIVE_USE_REAL_HOME=1лише тоді, коли навмисно хочете, щоб live-тести використовували ваш реальний домашній каталог. pnpm test:liveтепер типово працює в тихішому режимі: він зберігає вивід прогресу[live] ..., але приховує додаткове повідомлення про~/.profileі приглушує логи bootstrap Gateway/шум Bonjour. ВстановітьOPENCLAW_LIVE_TEST_QUIET=0, якщо хочете повернути повні стартові логи.- Ротація API-ключів (специфічна для провайдера): встановлюйте
*_API_KEYSу форматі з комами/крапками з комою або*_API_KEY_1,*_API_KEY_2(наприклад,OPENAI_API_KEYS,ANTHROPIC_API_KEYS,GEMINI_API_KEYS) або перевизначення для окремого live-запуску черезOPENCLAW_LIVE_*_KEY; тести повторюють спробу у відповідь на rate limit. - Вивід прогресу/Heartbeat:
- Live-набори тепер виводять рядки прогресу в stderr, тож довгі виклики провайдера видно як активні навіть тоді, коли захоплення консолі Vitest є тихим.
vitest.live.config.tsвимикає перехоплення консолі Vitest, щоб рядки прогресу провайдера/Gateway негайно транслювалися під час live-запусків.- Налаштовуйте Heartbeat для direct-model через
OPENCLAW_LIVE_HEARTBEAT_MS. - Налаштовуйте Heartbeat для gateway/probe через
OPENCLAW_LIVE_GATEWAY_HEARTBEAT_MS.
Який набір мені запускати?
Користуйтеся цією таблицею рішень:
- Редагуєте логіку/тести: запускайте
pnpm test(іpnpm test:coverage, якщо змінили багато) - Зачіпаєте мережеву взаємодію Gateway / WS protocol / pairing: додайте
pnpm test:e2e - Налагоджуєте «мій бот не працює» / специфічні збої провайдера / виклик tool: запускайте звужений
pnpm test:live
Live-тести (із доступом до мережі)
Для live-матриці моделей, smoke backend CLI, smoke ACP, harness app-server Codex і всіх live-тестів медіапровайдерів (Deepgram, BytePlus, ComfyUI, image, music, video, media harness) — а також для обробки облікових даних для live-запусків — див. Тестування — live-набори.
Ранери Docker (необов’язкові перевірки «працює в Linux»)
Ці ранери Docker поділяються на дві групи:
- Ранери live-моделей:
test:docker:live-modelsіtest:docker:live-gatewayзапускають лише відповідний live-файл із profile-key всередині образу Docker репозиторію (src/agents/models.profiles.live.test.tsіsrc/gateway/gateway-models.profiles.live.test.ts), монтують ваш локальний каталог конфігурації та робочий простір (і використовують~/.profile, якщо його змонтовано). Відповідні локальні entrypoint-и —test:live:models-profilesіtest:live:gateway-profiles. - Docker live runner-и типово мають менший smoke-ліміт, щоб повний Docker sweep залишався практичним:
test:docker:live-modelsтипово використовуєOPENCLAW_LIVE_MAX_MODELS=12, аtest:docker:live-gatewayтипово використовуєOPENCLAW_LIVE_GATEWAY_SMOKE=1,OPENCLAW_LIVE_GATEWAY_MAX_MODELS=8,OPENCLAW_LIVE_GATEWAY_STEP_TIMEOUT_MS=45000іOPENCLAW_LIVE_GATEWAY_MODEL_TIMEOUT_MS=90000. Перевизначайте ці env-змінні, коли вам явно потрібне більше, вичерпне сканування. test:docker:allодин раз збирає live Docker image черезtest:docker:live-build, а потім повторно використовує його для live Docker lane. Також він збирає один спільний imagescripts/e2e/Dockerfileчерезtest:docker:e2e-buildі повторно використовує його для E2E smoke-ранерів у контейнерах, які перевіряють зібраний застосунок. Агрегат використовує зважений локальний планувальник:OPENCLAW_DOCKER_ALL_PARALLELISMкерує слотами процесів, тоді як обмеження ресурсів не дають одночасно стартувати всім важким live-, npm-install- і multi-service lane. Типові значення: 10 слотів,OPENCLAW_DOCKER_ALL_LIVE_LIMIT=6,OPENCLAW_DOCKER_ALL_NPM_LIMIT=8іOPENCLAW_DOCKER_ALL_SERVICE_LIMIT=7; налаштовуйтеOPENCLAW_DOCKER_ALL_WEIGHT_LIMITабоOPENCLAW_DOCKER_ALL_DOCKER_LIMITлише тоді, коли Docker host має більший запас ресурсів. Runner типово виконує Docker preflight, видаляє застарілі контейнери OpenClaw E2E, виводить статус кожні 30 секунд, зберігає таймінги успішних lane у.artifacts/docker-tests/lane-timings.jsonі використовує ці таймінги, щоб у наступних запусках спочатку стартували довші lane. ВикористовуйтеOPENCLAW_DOCKER_ALL_DRY_RUN=1, щоб вивести зважений маніфест lane без збирання або запуску Docker.- Smoke-ранери контейнерів:
test:docker:openwebui,test:docker:onboard,test:docker:npm-onboard-channel-agent,test:docker:session-runtime-context,test:docker:agents-delete-shared-workspace,test:docker:gateway-network,test:docker:mcp-channels,test:docker:pi-bundle-mcp-tools,test:docker:cron-mcp-cleanup,test:docker:plugins,test:docker:plugin-updateіtest:docker:config-reloadпіднімають один або кілька реальних контейнерів і перевіряють інтеграційні шляхи вищого рівня.
Docker runner-и live-моделей також bind-mount-ять лише потрібні home-каталоги CLI auth (або всі підтримувані, якщо запуск не звужено), а потім копіюють їх у home каталогу контейнера перед запуском, щоб OAuth зовнішнього CLI міг оновлювати токени без змін у host auth store:
- Прямі моделі:
pnpm test:docker:live-models(скрипт:scripts/test-live-models-docker.sh) - Smoke bind для ACP:
pnpm test:docker:live-acp-bind(скрипт:scripts/test-live-acp-bind-docker.sh; типово охоплює Claude, Codex і Gemini, із суворим покриттям OpenCode черезpnpm test:docker:live-acp-bind:opencode) - Smoke для backend CLI:
pnpm test:docker:live-cli-backend(скрипт:scripts/test-live-cli-backend-docker.sh) - Smoke harness app-server Codex:
pnpm test:docker:live-codex-harness(скрипт:scripts/test-live-codex-harness-docker.sh) - Gateway + dev agent:
pnpm test:docker:live-gateway(скрипт:scripts/test-live-gateway-models-docker.sh) - Live smoke Open WebUI:
pnpm test:docker:openwebui(скрипт:scripts/e2e/openwebui-docker.sh) - Майстер onboarding (TTY, повне scaffolding):
pnpm test:docker:onboard(скрипт:scripts/e2e/onboard-docker.sh) - Smoke onboarding/channel/agent через npm tarball:
pnpm test:docker:npm-onboard-channel-agentглобально встановлює упакований tarball OpenClaw у Docker, налаштовує OpenAI через onboarding з env-ref плюс типово Telegram, перевіряє, що doctor відновлює runtime deps активованого Plugin, і виконує один агентський хід проти mocked OpenAI. Використовуйте вже зібраний tarball черезOPENCLAW_NPM_ONBOARD_PACKAGE_TGZ=/path/to/openclaw-*.tgz, пропустіть host rebuild черезOPENCLAW_NPM_ONBOARD_HOST_BUILD=0або змініть канал черезOPENCLAW_NPM_ONBOARD_CHANNEL=discord. - Smoke runtime context сесії:
pnpm test:docker:session-runtime-contextперевіряє збереження transcript прихованого runtime context плюс виправлення doctor для уражених дубльованих гілок prompt-rewrite. - Smoke глобального встановлення Bun:
bash scripts/e2e/bun-global-install-smoke.shпакує поточне дерево, встановлює його черезbun install -gв ізольований home і перевіряє, щоopenclaw infer image providers --jsonповертає bundled image providers замість зависання. Використовуйте вже зібраний tarball черезOPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ=/path/to/openclaw-*.tgz, пропустіть host build черезOPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0або скопіюйтеdist/із зібраного Docker image черезOPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE=openclaw-dockerfile-smoke:local. - Docker smoke інсталятора:
bash scripts/test-install-sh-docker.shвикористовує один npm cache для своїх контейнерів root, update і direct-npm. Smoke оновлення типово бере npmlatestяк стабільну базову версію перед оновленням до tarball-кандидата. Перевірки інсталятора без root зберігають ізольований npm cache, щоб записи кешу з правами root не маскували поведінку локального встановлення користувача. ВстановітьOPENCLAW_INSTALL_SMOKE_NPM_CACHE_DIR=/path/to/cache, щоб повторно використовувати кеш root/update/direct-npm між локальними перезапусками. - Install Smoke CI пропускає дубльований direct-npm global update через
OPENCLAW_INSTALL_SMOKE_SKIP_NPM_GLOBAL=1; локально запускайте скрипт без цього env, коли потрібне покриття прямогоnpm install -g. - Smoke CLI для видалення спільного робочого простору agents:
pnpm test:docker:agents-delete-shared-workspace(скрипт:scripts/e2e/agents-delete-shared-workspace-docker.sh) типово збирає image з root Dockerfile, ініціалізує двох агентів з одним робочим простором в ізольованому home контейнера, виконуєagents delete --jsonі перевіряє коректний JSON плюс поведінку зі збереженням робочого простору. Повторно використовуйте image install-smoke черезOPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_IMAGE=openclaw-dockerfile-smoke:local OPENCLAW_AGENTS_DELETE_SHARED_WORKSPACE_E2E_SKIP_BUILD=1. - Мережева взаємодія Gateway (два контейнери, WS auth + health):
pnpm test:docker:gateway-network(скрипт:scripts/e2e/gateway-network-docker.sh) - Регресія мінімального reasoning для OpenAI Responses web_search:
pnpm test:docker:openai-web-search-minimal(скрипт:scripts/e2e/openai-web-search-minimal-docker.sh) запускає mocked сервер OpenAI через Gateway, перевіряє, щоweb_searchпіднімаєreasoning.effortізminimalдоlow, потім примушує схему провайдера відхилити запит і перевіряє, що сирі деталі з’являються в логах Gateway. - Міст каналу MCP (seeded Gateway + stdio bridge + smoke сирого notification-frame Claude):
pnpm test:docker:mcp-channels(скрипт:scripts/e2e/mcp-channels-docker.sh) - Інструменти MCP у Pi bundle (реальний stdio MCP server + smoke allow/deny для вбудованого профілю Pi):
pnpm test:docker:pi-bundle-mcp-tools(скрипт:scripts/e2e/pi-bundle-mcp-tools-docker.sh) - Очищення MCP для Cron/subagent (реальний Gateway + teardown дочірнього stdio MCP після ізольованих запусків cron і одноразового subagent):
pnpm test:docker:cron-mcp-cleanup(скрипт:scripts/e2e/cron-mcp-cleanup-docker.sh) - Plugins (smoke встановлення + alias
/plugin+ семантика restart для Claude-bundle):pnpm test:docker:plugins(скрипт:scripts/e2e/plugins-docker.sh) - Smoke оновлення Plugin без змін:
pnpm test:docker:plugin-update(скрипт:scripts/e2e/plugin-update-unchanged-docker.sh) - Smoke метаданих перезавантаження конфігурації:
pnpm test:docker:config-reload(скрипт:scripts/e2e/config-reload-source-docker.sh) - Runtime deps bundled Plugin:
pnpm test:docker:bundled-channel-depsтипово збирає невеликий Docker runner image, один раз збирає та пакує OpenClaw на host, а потім монтує цей tarball у кожен Linux-сценарій встановлення. Повторно використовуйте image черезOPENCLAW_SKIP_DOCKER_BUILD=1, пропустіть host rebuild після свіжої локальної збірки черезOPENCLAW_BUNDLED_CHANNEL_HOST_BUILD=0або вкажіть наявний tarball черезOPENCLAW_BUNDLED_CHANNEL_PACKAGE_TGZ=/path/to/openclaw-*.tgz. Повний Docker aggregate один раз попередньо пакує цей tarball, а потім розбиває перевірки bundled channel на незалежні lane, зокрема окремі lane оновлення для Telegram, Discord, Slack, Feishu, memory-lancedb і ACPX. ВикористовуйтеOPENCLAW_BUNDLED_CHANNELS=telegram,slack, щоб звузити channel matrix під час прямого запуску bundled lane, абоOPENCLAW_BUNDLED_CHANNEL_UPDATE_TARGETS=telegram,acpx, щоб звузити сценарій оновлення. Lane також перевіряє, щоchannels.<id>.enabled=falseіplugins.entries.<id>.enabled=falseпригнічують відновлення doctor/runtime-dependency. - Під час ітерацій звужуйте runtime deps bundled Plugin, вимикаючи не пов’язані сценарії, наприклад:
OPENCLAW_BUNDLED_CHANNEL_SCENARIOS=0 OPENCLAW_BUNDLED_CHANNEL_UPDATE_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_ROOT_OWNED_SCENARIO=0 OPENCLAW_BUNDLED_CHANNEL_SETUP_ENTRY_SCENARIO=0 pnpm test:docker:bundled-channel-deps.
Щоб вручну попередньо зібрати і повторно використовувати спільний image built-app:
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local pnpm test:docker:e2e-build
OPENCLAW_DOCKER_E2E_IMAGE=openclaw-docker-e2e:local OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:mcp-channels
Перевизначення image для конкретних наборів, як-от OPENCLAW_GATEWAY_NETWORK_E2E_IMAGE, усе ще мають пріоритет, якщо встановлені. Коли OPENCLAW_SKIP_DOCKER_BUILD=1 вказує на віддалений спільний image, скрипти завантажують його, якщо його ще немає локально. Docker-тести QR та інсталятора зберігають власні Dockerfile, оскільки вони перевіряють поведінку пакування/встановлення, а не спільний runtime зібраного застосунку.
Docker runner-и live-моделей також bind-mount-ять поточний checkout у режимі лише для читання і
розміщують його в тимчасовому workdir усередині контейнера. Це дозволяє зберегти runtime
image компактним, водночас запускаючи Vitest точно проти вашого локального source/config.
Крок staging пропускає великі локальні кеші та вихідні дані збірки застосунків, такі як
.pnpm-store, .worktrees, __openclaw_vitest__ і локальні для застосунків каталоги .build або
вихідні каталоги Gradle, щоб Docker live-запуски не витрачали хвилини на копіювання
машинно-специфічних артефактів.
Вони також встановлюють OPENCLAW_SKIP_CHANNELS=1, щоб live-probe Gateway не запускали
реальні worker-и каналів Telegram/Discord тощо всередині контейнера.
test:docker:live-models усе ще запускає pnpm test:live, тому також передавайте
OPENCLAW_LIVE_GATEWAY_*, коли вам потрібно звузити або виключити live-покриття Gateway з цього Docker lane.
test:docker:openwebui — це smoke перевірка сумісності вищого рівня: вона запускає
контейнер Gateway OpenClaw з увімкненими HTTP endpoint-ами, сумісними з OpenAI,
запускає зафіксований контейнер Open WebUI проти цього Gateway, входить через
Open WebUI, перевіряє, що /api/models показує openclaw/default, а потім надсилає
реальний chat-запит через проксі /api/chat/completions Open WebUI.
Перший запуск може бути помітно повільнішим, оскільки Docker може потребувати завантаження
image Open WebUI, а Open WebUI може потребувати завершення власного cold-start налаштування.
Цей lane очікує придатний ключ live-моделі, а OPENCLAW_PROFILE_FILE
(типово ~/.profile) — основний спосіб надати його в Dockerized-запусках.
Успішні запуски виводять невеликий JSON payload на кшталт { "ok": true, "model": "openclaw/default", ... }.
test:docker:mcp-channels навмисно є детермінованим і не потребує
реального облікового запису Telegram, Discord або iMessage. Він запускає seeded контейнер
Gateway, стартує другий контейнер, який запускає openclaw mcp serve, а потім
перевіряє виявлення маршрутованих розмов, читання transcript, метадані вкладень,
поведінку черги live-подій, маршрутизацію outbound send, а також сповіщення у стилі Claude про канал +
дозволи через реальний stdio MCP bridge. Перевірка сповіщень
безпосередньо аналізує сирі stdio MCP frame, тож smoke перевіряє те, що міст
справді виводить, а не лише те, що випадково показує конкретний клієнтський SDK.
test:docker:pi-bundle-mcp-tools є детермінованим і не потребує
ключа live-моделі. Він збирає Docker image репозиторію, запускає реальний stdio MCP probe server
усередині контейнера, матеріалізує цей сервер через embedded Pi bundle
MCP runtime, виконує tool, а потім перевіряє, що coding і messaging зберігають
інструменти bundle-mcp, тоді як minimal і tools.deny: ["bundle-mcp"] їх відфільтровують.
test:docker:cron-mcp-cleanup є детермінованим і не потребує ключа live-моделі.
Він запускає seeded Gateway з реальним stdio MCP probe server, виконує ізольований
хід cron і одноразовий дочірній хід /subagents spawn, а потім перевіряє,
що дочірній процес MCP завершується після кожного запуску.
Ручний smoke для ACP plain-language thread (не CI):
bun scripts/dev/discord-acp-plain-language-smoke.ts --channel <discord-channel-id> ...- Зберігайте цей скрипт для робочих процесів регресії/налагодження. Він може знову знадобитися для перевірки маршрутизації ACP thread, тому не видаляйте його.
Корисні env-змінні:
OPENCLAW_CONFIG_DIR=...(типово:~/.openclaw) монтується в/home/node/.openclawOPENCLAW_WORKSPACE_DIR=...(типово:~/.openclaw/workspace) монтується в/home/node/.openclaw/workspaceOPENCLAW_PROFILE_FILE=...(типово:~/.profile) монтується в/home/node/.profileі source-иться перед запуском тестівOPENCLAW_DOCKER_PROFILE_ENV_ONLY=1, щоб перевіряти лише env-змінні, source-нуті зOPENCLAW_PROFILE_FILE, використовуючи тимчасові каталоги config/workspace і без монтування зовнішнього CLI authOPENCLAW_DOCKER_CLI_TOOLS_DIR=...(типово:~/.cache/openclaw/docker-cli-tools) монтується в/home/node/.npm-globalдля кешованих встановлень CLI всередині Docker- Зовнішні каталоги/файли CLI auth під
$HOMEмонтуються в режимі лише для читання під/host-auth..., а потім копіюються до/home/node/...перед початком тестів- Типові каталоги:
.minimax - Типові файли:
~/.codex/auth.json,~/.codex/config.toml,.claude.json,~/.claude/.credentials.json,~/.claude/settings.json,~/.claude/settings.local.json - Звужені запуски провайдерів монтують лише потрібні каталоги/файли, визначені з
OPENCLAW_LIVE_PROVIDERS/OPENCLAW_LIVE_GATEWAY_PROVIDERS - Перевизначайте вручну через
OPENCLAW_DOCKER_AUTH_DIRS=all,OPENCLAW_DOCKER_AUTH_DIRS=noneабо список через кому, наприкладOPENCLAW_DOCKER_AUTH_DIRS=.claude,.codex
- Типові каталоги:
OPENCLAW_LIVE_GATEWAY_MODELS=.../OPENCLAW_LIVE_MODELS=..., щоб звузити запускOPENCLAW_LIVE_GATEWAY_PROVIDERS=.../OPENCLAW_LIVE_PROVIDERS=..., щоб фільтрувати провайдерів усередині контейнераOPENCLAW_SKIP_DOCKER_BUILD=1, щоб повторно використовувати наявний imageopenclaw:local-liveдля перезапусків, яким не потрібна нова збіркаOPENCLAW_LIVE_REQUIRE_PROFILE_KEYS=1, щоб гарантувати, що облікові дані надходять зі сховища профілю (а не з env)OPENCLAW_OPENWEBUI_MODEL=..., щоб вибрати модель, яку Gateway показує для smoke Open WebUIOPENCLAW_OPENWEBUI_PROMPT=..., щоб перевизначити prompt для перевірки nonce, який використовує smoke Open WebUIOPENWEBUI_IMAGE=..., щоб перевизначити зафіксований тег image Open WebUI
Перевірка документації
Після редагування документації запускайте перевірки docs: pnpm check:docs.
Запускайте повну перевірку anchor у Mintlify, коли вам також потрібні перевірки заголовків усередині сторінки: pnpm docs:check-links:anchors.
Offline-регресія (безпечна для CI)
Це регресії «реального pipeline» без реальних провайдерів:
- Виклик tool через Gateway (mock OpenAI, реальний Gateway + цикл агента):
src/gateway/gateway.test.ts(випадок: "runs a mock OpenAI tool call end-to-end via gateway agent loop") - Wizard Gateway (WS
wizard.start/wizard.next, записує config + auth enforced):src/gateway/gateway.test.ts(випадок: "runs wizard over ws and writes auth token config")
Оцінювання надійності агентів (Skills)
У нас уже є кілька безпечних для CI тестів, які поводяться як «оцінювання надійності агентів»:
- Mock tool-calling через реальний Gateway + цикл агента (
src/gateway/gateway.test.ts). - Наскрізні потоки wizard, які перевіряють прив’язку сесії та ефекти конфігурації (
src/gateway/gateway.test.ts).
Що ще бракує для Skills (див. Skills):
- Ухвалення рішень: коли Skills перелічені в prompt, чи вибирає агент правильний skill (або уникає нерелевантних)?
- Відповідність вимогам: чи читає агент
SKILL.mdперед використанням і чи виконує потрібні кроки/аргументи? - Контракти workflow: багатокрокові сценарії, які перевіряють порядок tool, перенесення історії сесії та межі sandbox.
Майбутні eval мають спочатку залишатися детермінованими:
- Runner сценаріїв із mock-провайдерами для перевірки викликів tool + порядку, читання файлів skill і прив’язки сесії.
- Невеликий набір сценаріїв, зосереджених на skill (використовувати чи уникати, gating, prompt injection).
- Необов’язкові live-eval (opt-in, керовані env) лише після того, як безпечний для CI набір уже буде на місці.
Contract-тести (форма Plugin і каналу)
Contract-тести перевіряють, що кожен зареєстрований Plugin і канал відповідає своєму
контракту інтерфейсу. Вони ітеруються по всіх виявлених Plugin і запускають набір
перевірок форми та поведінки. Типовий unit lane pnpm test навмисно
пропускає ці файли спільних seam і smoke; запускайте contract-команди явно,
коли зачіпаєте спільні поверхні каналу або провайдера.
Команди
- Усі контракти:
pnpm test:contracts - Лише контракти каналів:
pnpm test:contracts:channels - Лише контракти провайдерів:
pnpm test:contracts:plugins
Контракти каналів
Розташовані в src/channels/plugins/contracts/*.contract.test.ts:
- plugin - Базова форма Plugin (id, name, capabilities)
- setup - Контракт setup wizard
- session-binding - Поведінка прив’язки сесії
- outbound-payload - Структура payload повідомлення
- inbound - Обробка вхідних повідомлень
- actions - Обробники дій каналу
- threading - Обробка ID тредів
- directory - API каталогу/складу
- group-policy - Застосування групової політики
Контракти статусу провайдера
Розташовані в src/plugins/contracts/*.contract.test.ts.
- status - Зондування статусу каналу
- registry - Форма реєстру Plugin
Контракти провайдерів
Розташовані в src/plugins/contracts/*.contract.test.ts:
- auth - Контракт потоку автентифікації
- auth-choice - Вибір/selection автентифікації
- catalog - API каталогу моделей
- discovery - Виявлення Plugin
- loader - Завантаження Plugin
- runtime - Runtime провайдера
- shape - Форма/інтерфейс Plugin
- wizard - Setup wizard
Коли запускати
- Після зміни export-ів або subpath у plugin-sdk
- Після додавання або зміни каналу чи Plugin провайдера
- Після рефакторингу реєстрації або виявлення Plugin
Contract-тести запускаються в CI і не потребують реальних API-ключів.
Додавання регресійних тестів (настанови)
Коли ви виправляєте проблему провайдера/моделі, виявлену в live:
- Якщо можливо, додайте безпечну для CI регресію (mock/stub провайдера або фіксацію точної трансформації форми запиту)
- Якщо проблема за своєю природою лише live (rate limit, політики auth), залишайте live-тест вузьким і opt-in через env-змінні
- Віддавайте перевагу найменшому рівню, який виявляє баг:
- баг перетворення/відтворення запиту провайдера → direct models test
- баг pipeline сесії/історії/tool у gateway → live smoke Gateway або безпечний для CI mock-тест Gateway
- Захисне правило обходу SecretRef:
src/secrets/exec-secret-ref-id-parity.test.tsвиводить одну вибіркову ціль на клас SecretRef із метаданих реєстру (listSecretTargetRegistryEntries()), а потім перевіряє, що exec id сегментів обходу відхиляються.- Якщо ви додаєте нову цільову сім’ю SecretRef з
includeInPlanуsrc/secrets/target-registry-data.ts, оновітьclassifyTargetClassу цьому тесті. Тест навмисно падає на некласифікованих target id, щоб нові класи не могли бути тихо пропущені.