README.zh.md 8.3 KB


description: "面向浏览器功能测试的 jsdom slot 测试运行时,供测试作者针对生产机制检验 slot、store 与渲染。"

kind: "package-library"

@deepseek-ai/dsh-client-test-runtime

English | 中文

概述

dsh-client-test-runtime 让浏览器功能测试在 jsdom 中检验生产 slot、store、渲染、更新与销毁行为,而无需重实现 UI 运行时。测试作者可以发布带类型的 Session、Workspace、projection 与 Conversation fixture,查询 slot 局部 DOM 根,并脚本化 Remote 应答或失败。缺失服务、未打桩的会话行为与意外文件上传都会在调用点失败,销毁则保持幂等。仅限仓内、面向浏览器的 Vitest 套件通过 devDependencies 使用本包;它不是产品插件或通用 Node 测试框架。

目录


使用本包

本包让浏览器功能测试拥有可挂载的真实运行时:创建测试台,声明你的功能所占用的 slot,挂载功能插件,渲染一个 slot,在局部视图上断言,然后 dispose(资源释放)——全程不存在生产逻辑的第二份实现。

搭建功能测试

SlotTestRuntime.create() 组装运行时,declare(children) 注册一个自动 frame,其逐 key 的 <div data-slot> 包裹层成为快照根,mount(plugin) 在真实 fiber 上运行功能,renderSlot(key, owner) 返回带限定查询与原位更新的 slot 局部视图:

const runtime = await SlotTestRuntime.create()
await runtime.declare({ 'feature-slot': {} })
const handle = await runtime.mount(FeaturePlugin)
const view = runtime.renderSlot('feature-slot', { owner: props })
expect(view.container).toMatchSnapshot()
await runtime.dispose()

mount 会预检必需服务,缺失时自明报错——先用 provide(name, value) 提供额外服务。运行时会提供不可用的 fileUpload 替身,使装配可以挂载;测试上传行为时,需要在挂载前替换 runtime.fileUpload.uploadstoreOf(key, scopeKey) 返回渲染器交给 slot 组件的实时 store 实例,用于身份与动作驱动写入断言。

局部 DOM 快照

注册的快照序列化器把 CSS-module 哈希类名折回语义名(_frame_a1b2c3frame),使 .snap 文件只含结构,并把 <svg> 内部折叠为 data-content 指纹。需要自定义页面 frame 的套件改用 root.declare(children, Frame) 而非自动 frame;dispose() 沿单一轴拆除视图、feature fiber、已铸 scope 与持久化 store 状态,且幂等。

脚本化 Remote 应答与失败

TestRemotectx.remote 面的替身:它把自己连同每个被脚本化的命名空间各注册一个服务,使注入 remote.<name> 的插件得以解除挂起;$on 订阅由显式的测试事件驱动器推动;$host 是普通可变字段,套件直接赋值即可脚本化带 home 或非 loopback 的 Host。UI 套件也在本包取用 RemoteError 构造器这个值——dsh-api-remotes facade 承载不了它,因为从套件发起的值 import 会拉起该装配尚未构建的 /remote 产物链。

按 Host 会答的码来脚本化失败,并以生产代码同样的方式断言——判 code,绝不判类:

import { RemoteError } from '@deepseek-ai/dsh-client-test-runtime'

remote.goals.create.mockResolvedValue({
  ok: false,
  error: new RemoteError('goal/not-found', 'goal "g1" does not exist', { goalId: 'g1' }),
})
expect(view.getByRole('alert')).toHaveTextContent('goal/not-found')

何时使用

当功能套件要在真实运行时下检验 slot、store、渲染与销毁时使用本测试台——生产 SlotRegistry、渲染器与 provide bundle 物化都会被挂载,绝不重实现。它是浏览器侧测试基础设施:永远不触及模型请求,feature 包仅以 devDependencies 依赖之。

可能出什么问题

  • 已声明服务未提供——mount 自明报错并列出缺失名称;请先用 provide() 提供。
  • declare 之前尝试渲染——renderSlot 自明报错;请先声明该 key。
  • 测试调用会话行为桩上未打桩的动词——fixture 桩按设计自明报错,缺失的桩会在调用点浮现,而非静默通过。

理解实现

实现细节——点击展开 本节解释测试台的设计;可观察行为已在[使用本包](#use-this-package)中完整说明。 ### 设计 测试台不复制生产逻辑:它挂载生产 `SlotRegistry`、生产渲染器与 `UiSession` 适配器。`TestSessions` 与 `TestWorkspaces` 实现功能通过 Cordis 消费的 owner 接口,每个 fixture Session 实现 `SessionFace`,`stubSettingsScope` 实现 `SettingsScope`。`UiSession` 从这些 Controller binding 派生标准渲染器 source。未 stub 的 `ISession` 行为会携缺失方法名失败。 ### 源码地图 | 文件 | 职责 | |---|---| | [`src/index.ts`](src/index.ts) | `SlotTestRuntime` 组装、`TestRoot`、自动 frame、`mount`/`dispose` | | [`src/sessions.ts`](src/sessions.ts) + [`src/workspaces.ts`](src/workspaces.ts) | `ISessions`/`IWorkspaces` 测试替身与 `FixtureSession` 行为桩 | | [`src/fixtures.ts`](src/fixtures.ts) | 普通 fixture 构造器:会话快照、workspace 列表状态 | | [`src/snapshot.ts`](src/snapshot.ts) | DOM 快照序列化器(类名哈希折叠、`` 指纹) | | [`src/remote.ts`](src/remote.ts) | 用于 host RPC 的 `TestRemote` 替身、`RemoteError` 值转出 | | [`src/translate.ts`](src/translate.ts) + [`src/locale-env.ts`](src/locale-env.ts) | 翻译与固定浏览器语言测试辅助 | | [`src/settings-scope.ts`](src/settings-scope.ts) | 带测试驱动发布与写入 spy 的 `stubSettingsScope` | | — | 不发布运行时不变式伴生入口;所挂载的生产包拥有各自的不变式。 | ### 生命周期 `create()` 构建全新上下文,挂载 slot 与会话注册表,安装渲染器,并提供 session/workspace 替身和明确失败的文件上传替身。`mount` 在启动 fiber 前对照上下文检查每个已声明注入,使缺失提供方自明报错而非永久挂起。`dispose()` 先卸载 React 树,再 dispose feature fiber、释放根注册、dispose 已铸 session scope 并清除持久化 store 状态;每个公共修改器都包裹在 act 中,因此测试无需自行处理 SlotCore 微任务批处理或 React `act`。

进一步探索

当包级约定不够用时阅读以下页面。它们从测试台逐步进入它所挂载的生产机制以及使用它的测试。


模型体验

无;本包是浏览器侧测试基础设施,无一物到达模型请求。

KV Cache 影响

无;本包既不组装也不发送提供方请求。

已知限制与延期工作

这些限制说明本测试台如何被消费。它们是当前包约束,不是任务积压。

  • 仅限 Vitest 与 jsdom——所有消费方都是仓内、面向浏览器的 Vitest 套件。本包不是产品插件,也不是通用 Node 测试框架。
  • Session、Conversation 与 Chat fixture 保持分离——sessionSnapshot 只包含 Session Controller 状态,conversationSnapshot 包含 target-neutral Conversation 状态,chatSnapshot 包含 Chat target 状态。组装测试提供 Session event entry,而不是向 SessionSnapshot 添加 Conversation 或 Chat 字段。

开发备注

维护者的工作上下文——点击展开 无。