前言¶
在 DSH「一切皆插件」的開發方式下,插件作者最容易踩的坑往往不在編譯期:產物能構建、單測能通過,發佈之後卻可能因爲 tarball 缺文件、bundle 在宿主裏註冊失敗、卸載弄壞 profile 而翻車。這類問題的共同點是,它們只出現在「用戶實際安裝的那個打包產物」與「真實宿主」之間,作者本機的靜態檢查覆蓋不到。
dsh-testkit 補的就是這一段:把 npm pack 出來的產物放進精確指定的真實 DSH 宿主,完整走一遍生命週期,並把證據留給維護者審查。
這是什麼¶
iiwish/dsh-testkit 自述爲 “The real-host release gate for DeepSeek Harness plugins”,即 DeepSeek Harness 插件的真實宿主發佈門檻。它明確了自己的邊界:是發佈門檻,不是單元測試框架、靜態 linter、模型輸出評估器,也不是安全認證。整個流程不做模型調用,不需要模型 API key,許可證爲 MIT。
一次隔離運行回答三個發佈問題:
| 發佈問題 | 一次隔離運行給出的證據 |
|---|---|
| 可發佈的產物能否安裝並註冊? | npm pack、精確版本 DSH 安裝、bundle 組裝、配置行、services 與 tool schema |
| 承諾的行爲是否可用? | 確定性運行時探針、聲明的工具調用、可選 loopback HTTP 路由、顯式瀏覽器 smoke |
| 用戶能否乾淨地卸載? | 卸載、同 profile 重啓、能力檢查、owned-path 殘留、進程與端口檢查 |
生命週期:從 resolve 到 cleanup¶
一次完整的隔離生命週期是:
resolve -> install-dsh -> package -> install-plugin -> assemble -> boot -> register
-> exercise -> update? -> uninstall -> reboot -> recover? -> cleanup
每次隔離生命週期只測試一個被測插件;多插件所有權與更新順序屬於組合層面問題,不在這個工具的職責內。
適配器目前只接受 @deepseek-ai/dsh 的精確版本:0.1.1-rc.2(默認)、0.1.0-rc.8、0.1.0-rc.7、0.1.0-rc.6。未知版本會在創建 runner 之前以退出碼 4 終止,宿主版本漂移不會被誤標爲插件失敗。官方 dsh-v0.1.2-alpha.1 因對應 npm 包不可用仍是待定 canary;0.1.2-alpha.2 僅進入一次性 canary 矩陣。兩個 alpha 都不在默認支持矩陣內。
通過意味着什麼¶
- 報告中標識的同一個打包產物完成了全部必需階段;
- 配置行來自 DSH
--dump-config,services 與 tool schema 來自進程內 Cordis 探針; - 聲明的 exercise 通過真實工具運行時執行,不經過模型選擇;
- 卸載後同一 profile 重啓,沒有被測 bundle、能力或可歸因殘留;
- 必需的 observer 可用,缺少必需覆蓋記爲
unsupported,不會合成一個「通過」。
反過來,通過也不代表任意可執行代碼安全、模型輸出良好或未斷言的行爲可用。
行爲與潔淨度驗證¶
行爲側的手段包括:確定性運行時探針、聲明的工具調用、可選的 loopback HTTP 路由斷言,以及顯式的瀏覽器 smoke 測試。HTTP 與瀏覽器流量限制在 runner 自有的 127.0.0.1;缺少 Chromium 記爲 unsupported。
卸載潔淨度驗證覆蓋:同 profile 重啓、能力檢查、owned-path 殘留、進程與端口檢查。
安裝與啓用¶
運行要求:Node.js 22 或更新版本,以及 Docker(Docker 是默認 runner)。
安裝爲 devDependency:
pnpm add -D dsh-testkit
安裝後 CLI 入口爲 dsh-test,最短路徑是先生成場景,再執行測試:
pnpm dsh-test init
pnpm dsh-test
典型用法¶
dsh-test init 生成場景¶
dsh-test init 離線運行,定位最近的 Git worktree,生成三個可審查的文件:
<plugin-root>/dsh-testkit.yaml:包含精確 DSH 版本與探測到的行期望;<repository-root>/.github/workflows/dsh-lifecycle.yml:默認只讀 token 契約與正確的嵌套路徑;<repository-root>/.agents/skills/dsh-testkit/SKILL.md:讓兼容的編碼智能體執行同一道門檻。
生成是字節級冪等的,並對所有目標做預檢;發現衝突會停止全部寫入,除非顯式傳 --force。如果被測 bundle 在倉庫根目錄之下:
pnpm dsh-test init plugin/
pnpm dsh-test --config plugin/dsh-testkit.yaml
場景即代碼¶
場景是 schemaVersion: 1 的 YAML。init 生成的起始場景大致如下:
schemaVersion: 1
name: my-plugin-quick
subject:
source: .
dsh:
version: 0.1.1-rc.2
expect:
boot: success
rows: [tool-my-plugin]
services: [myService]
tools: [my_tool]
exercise:
- tool: my_tool
arguments:
value: smoke
observers:
filesystem: required
process: preferred
ports: preferred
network: off
canary: preferred
expect 聲明 boot 結果、配置行、services 與 tools,exercise 聲明要執行的工具調用。本地目錄 subject 以只讀方式掛載,複製到 runner 擁有的可寫根目錄後再打包;聲明瞭 prepare、prepack 或 postpack 時,會在副本內按 packageManager 與 lockfile 恢復依賴再 npm pack,原始檢出不會被改動。場景還支持 http.routes、更新目標、預期失敗與恢復、階段重跑、observer 策略與全局 watchdog,細節見倉庫內的 Scenario Reference。
對提供 DSH web 路由的插件,設置 profile: web 並添加僅 Docker 的斷言,例如要求 /health 返回 200:
profile: web
http:
routes:
- id: health
path: /health
expect:
status: 200
json:
status: ok
version: $subject.packageVersion
CI 集成¶
生成的 workflow 默認使用只讀 token,並把這一契約寫進文件:
permissions:
contents: read
steps:
- uses: iiwish/dsh-testkit/.github/actions/dsh-test@v0
with:
plugin: .
dsh-version: 0.1.1-rc.2
config: dsh-testkit.yaml
publish-junit-check: 'false'
默認行爲是把 JUnit 註解寫進 job、上傳完整證據目錄,並給出 artifact ID、URL、digest、報告路徑與穩定退出碼,不調用 Checks API。受信任的 push 或 release workflow 可以開啓命名 JUnit Check:
permissions:
contents: read
checks: write
steps:
- uses: iiwish/dsh-testkit/.github/actions/dsh-test@v0
with:
plugin: .
dsh-version: 0.1.1-rc.2
publish-junit-check: 'true'
開啓 publish-junit-check 需要 checks: write 權限,且不要對不受信任的 fork PR 啓用。GitHub Enterprise Server 與其他 CI 系統可以直接調用 CLI。
報告與退出碼¶
報告落在 .dsh-testkit/runs/:canonical 的 report.json、CI 可用的 junit.xml、可讀的 report.md、脫敏命令日誌與有界階段證據。
退出碼是穩定的,腳本可以直接按它分支:
| 退出碼 | 含義 |
|---|---|
| 0 | 通過 |
| 1 | 生命週期失敗 |
| 2 | 輸入無效 |
| 3 | 基礎設施錯誤 |
| 4 | 不支持 |
| 5 | flaky |
適用場景與注意¶
適合誰:維護 DSH 插件的作者、審查發佈 PR 的維護者、運營插件模板的團隊,以及需要可復現宿主級 bug 報告的人。
使用前注意幾點:
- 每次隔離生命週期只測一個被測插件;多插件的所有權與更新順序是組合層面的問題;
- 適配器只接受前文列出的四個精確 DSH 版本,其他版本以退出碼 4 終止;
- 一個「通過」不代表任意可執行代碼安全、模型輸出良好或未斷言行爲可用,它也不是安全認證;
- 兩個 alpha 版本僅進 canary 矩陣,不在默認支持範圍內。
安全方面需要說明:在 DSH 生態裏,插件以當前 dsh 進程的權限運行,安裝任何插件前都應檢查其源碼與許可證。dsh-testkit 本身以 npm devDependency 形式安裝,許可證爲 MIT,源碼公開;它不做模型調用,CI 側默認最小權限(只讀 token)。
小結¶
dsh-testkit 把發佈驗證從「我本地能跑」推進到「這個打包產物在精確的真實宿主上裝得上、跑得動、卸得乾淨,並且留下了證據」。對維護 DSH 插件的團隊來說,把它掛在發佈 PR 和 tag 上,是一種成本可控的把關方式。
- 插件目錄頁:https://www.skillhub.cn/plugins/iiwish/dsh-testkit
- GitHub 倉庫:https://github.com/iiwish/dsh-testkit
目錄頁爲社區維護的獨立站點,與 DeepSeek / 幻方無官方從屬關係。