尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

DeepChat 测试体系完全指南:作用域划分、命令矩阵与回归覆盖策略

DeepChat 测试体系完全指南:作用域划分、命令矩阵与回归覆盖策略 DeepChat 测试体系完全指南作用域划分、命令矩阵与回归覆盖策略【免费下载链接】deepchatDeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchatDeepChat 是一个连接多种 AI 能力与个人工作空间的 Electron 桌面 Agent 客户端。本指南以仓库中 test/README.md 为骨架系统讲解 DeepChat 测试体系的作用域划分、可复制的命令矩阵、持久化回归覆盖策略、原生 SQLite ABI 注意事项以及手工 deeplink 验证流程并结合package.json、vitest.config.ts、Playwright 配置与测试夹具源码给出可直接落地的运行与维护方案。读完本文你将能在本地精确地运行最小测试目标、理解各测试层的边界与取舍、遵守删除测试的准则并在交付前正确执行完整质量门禁。测试体系的定位守护工作流与维护契约DeepChat 的测试体系遵循一条核心原则测试保护用户工作流user workflows与维护契约maintained contracts完成一个功能并不等于可以撤销其回归覆盖。也就是说回归测试是功能交付的一部分而不是可以随版本迭代随意裁剪的附属物。这一理念与仓库的验证策略一脉相承根据 docs/spec-driven-dev.md 中的Implementation-First, Risk-Based Validation原则实现完成之后应运行最小相关的现有测试与静态/构建检查并把能保护用户可见行为、跨模块契约、持久化与迁移、生命周期与并发、恢复、安全边界或已被证实的回归的最小测试提交为持久化回归保护durable regression protection。测试是验证机制之一其存在目的是锁定契约与行为而非追逐覆盖率数字。因此在 DeepChat 仓库中任何测试的增删都应回答同一个问题这条测试保护了哪个工作流或契约删掉它之后回归保护的空缺在哪里作用域与命令矩阵所有测试命令都从仓库根目录执行使用 pnpm并遵循package.json中engines声明的 Node 版本。当前仓库声明为node 24.18.0 25、pnpm 10.34.5 11见 package.json。首次使用时先执行pnpm install安装依赖当所选验证需要可选应用运行时如 OCR、DuckDB VSS 等原生组件时再通过pnpm run installRuntime安装。以下命令矩阵完整覆盖了 test/README.md 定义的全部作用域作用域命令边界Main 与 Rendererpnpm testvitest.config.ts中声明的 Vitest projectsMain、共享契约与脚本pnpm run test:mainNode 环境test/mainRendererpnpm run test:rendererVue Test Utils 与 jsdomtest/rendererPortable Memory可移植内存pnpm run test:memory作用域校验、测试类型检查与可移植套件Electron smokepnpm run e2e:smoke构建后的应用见 E2E 环境与隔离CI Electron 子集pnpm run e2e:smoke:ci启动与 Settings 导航覆盖率pnpm run test:coverage报告输出到coverage/交互式监听pnpm run test:watch显式 watch 模式命令背后的实际配置pnpm test即vitest run见 package.json由 vitest.config.ts 通过projects同时定义renderer与main两个 projectrenderer 使用jsdom环境includetest/renderer/**/*.{test,spec}.{js,ts}main 使用node环境includetest/main/**/*.{test,spec}.{js,ts}。两个 project 都通过 alias 与 test/mocks/electron.ts 将electron、electron-toolkit/utils替换为测试 mock。一个值得注意的细节electron-store11 是 ESM-only 包会被外部化因此配置中通过server.deps.inline: [electron-store]将其内联保证它内部的electronimport 解析到测试 mock 而非真实包。覆盖率由 v8 provider 生成vitest.config.ts中全局阈值要求 branches / functions / lines / statements 均不低于 80%报告目录为./coverage。Renderer 套件有独立配置 vitest.config.renderer.ts同样使用 jsdommaxWorkers: 2与主配置一致TEST_MAX_WORKERS 2默认超时 10 秒。注释明确说明这是为了避免重负载的 jsdom/Markstream 套件在无约束时竞争 CPU 与 GC。pnpm run test:memory是三段式组合命令见 package.json先跑test:memory:scope执行 scripts/check-memory-test-scope.mjs 校验内存测试作用域清单再跑test:memory:type执行 scripts/typecheck-memory-tests.mjs 对内存测试做类型检查最后执行vitest --config vitest.config.memory.ts --run运行可移植套件。E2E 使用 Playwrighttest/e2e/playwright.config.ts 设置fullyParallel: false、workers: 1、用例超时 300 秒、断言超时 30 秒失败时保留截图、视频与 trace并约定data-testid作为测试标识属性。CI 子集则使用独立的 test/e2e/playwright.ci.config.ts。只跑最小的相关目标全量套件耗时较长开发迭代期间应只运行与当前改动相关的最小目标。test/README.md 给出的两个典型示例pnpm exec vitest run --config vitest.config.ts test/main/session/lifecycle.test.ts pnpm exec vitest run --config vitest.config.renderer.ts test/renderer/stores/sessionStore.test.ts第一条直接指定主进程套件中的单个测试文件走vitest.config.ts的 main project第二条显式使用 renderer 配置运行单个 store 测试。对应 E2E 场景也可以只跑一个确定的 Playwright 用例例如pnpm exec playwright test -c test/e2e/playwright.config.ts 36-chat-streaming原生 SQLite 的 ABI 注意事项Native SQLite 的 Node ABI 重建与必需的原生校验属于 CI 的职责不要为了跑一个本地测试而重建共享依赖——那可能把 Electron ABI 覆盖掉导致应用在真实环境中无法加载原生模块。与此配套的机制是原生与平台门控platform-gated的套件在前提条件不可用时可以跳过且跳过skipped的测试不能作为该平台通过的证据。内存测试的作用域分类清单位于 test/memory-test-scope.json它把test/main下的内存相关测试划分为四类behavior纯行为测试例如test/main/memory/retrievalService.test.ts、test/main/memory/writeCoordinator.test.ts、test/main/agent/deepchat/memory/memoryRuntimeCoordinator.test.tsnative依赖原生 SQLite 的测试例如test/main/memory/agentMemoryTable.test.ts、test/main/session/data/tapeLifecycle.test.tseval评测类例如test/main/memory/memoryRetrieval.eval.test.tsperf性能类位于test/main/performance/memory/下例如tapeScale.perf.ts、recallScale.perf.ts。从 scripts/check-memory-test-scope.mjs 的源码可以看到归类逻辑native类需要匹配itIfSqlite/describeIfSqlite这类门控调用如test/main/session/data/tapeRecall.test.ts中大量使用itIfSqlite(...)同时会校验清单中是否存在遗漏或多余条目防止内存测试在不知不觉中被划出门禁。清单还包含exemptions字段用于显式登记少数跨域套件留在完整 main 门禁中的理由。持久化覆盖测试保护的能力分组test/README.md 用一张分组表概括了各测试目录守护的核心能力这是理解整个测试体系布局的钥匙分组受保护的能力Agent、session 与 Tape准入admission、取消、并发、恢复、投影projection与持久化历史Provider、ACP、MCP、tools 与 plugins协议兼容性、权限、凭据、生命周期与故障隔离Memory、storage、sync 与 import隔离、迁移、损坏恢复与持久化数据Desktop、preload、routes 与 renderer clients调用方授权、可序列化契约、事件投递与清理Renderer 组件、stores 与 composables键盘与焦点行为、无障碍内容、草稿、配置与异步状态构建与脚本包完整性、支持的目标平台、签名、更新器兼容性与必需 CI 门禁Electron smoke通过真实 renderer/preload/main 边界验证应用装配与工作流这些分组与仓库目录一一对应test/main/下按 agent、session、provider、mcp、memory、tool 等子目录组织test/renderer/下对应 components、stores、composablesE2E 的 38 个 spec 文件test/e2e/specs/则从01-launch到37-accessibility依次覆盖启动、Settings 导航、typed IPC 边界、workspace watcher、provider 配置、Agent 与插件管理、composer 草稿、本地流式生成以及无障碍检查等真实工作流。测试策略保留真实域逻辑替代昂贵边界test/README.md 给出三条明确的策略准则在能提供有效行为覆盖的地方保留真实的域逻辑、store 与临时文件替代网络、模型、操作系统以及其他昂贵或不确定nondeterministic的边界当交互本身就是契约时例如授权、幂等性、协议调用交互断言才是恰当的。E2E 层是这条策略的典型体现根据 test/e2e/README.md默认的 smoke 套件覆盖启动、Settings 导航、typed IPC 边界、workspace watchers、provider 配置、Agent 与插件管理、composer 草稿和本地流式生成其中插件与流式 spec 通过真实应用路由使用 loopback HTTP/MCP 夹具不需要任何外部 provider 凭据。只有 5 个 spec基础对话、会话持久化、provider 连通性、聊天滚动归属、composer 宽度要求RUN_PROVIDER_INTEGRATIONtrue其默认 provider/model 为minimax/MiniMax-M2.7可用DEEPCHAT_E2E_PROVIDER_ID与DEEPCHAT_E2E_MODEL_ID覆盖默认值定义见 test/e2e/helpers/testData.ts。jsdom 的边界要认清jsdom 并不能验证原生窗口焦点、屏幕阅读器语音或计算后的视觉布局这些行为必须使用适当的 Electron 或人工验收方式验证。同时应避免向提交的套件中添加空示例、临时探针或镜像实现implementation-mirroring的测试。删除测试的准则删除一条测试必须有证据且证据必须属于以下四类之一测试已过时obsolete测试是空洞的vacuous即断言无法失败测试完全冗余fully redundant测试只是锁定了偶然的实现选择incidental implementation choice。在删除之前先明确它原本提供的保护或精确指出覆盖空缺。同时test/README.md 明确反对以下做法为散文prose、退役的迁移文件名或私有赋值计数保留源码字符串检查source-string checks源码检查仍然有价值的情况仅限于强制的导入边界、有文档记载的视觉/启动回归以及机器可读的打包或工作流契约。断言偏好与证据质量倾向断言以下可验证的结果而非实现细节公开结果public results持久化数据发出的事件emitted events渲染后的语义rendered semantics可恢复的错误recoverable errors。这一偏好与 docs/spec-driven-dev.md 中不要保留那些仅仅镜像私有控制流、断言偶然的调用顺序、通过 mock 复制实现或只为了提升覆盖率而存在的测试的约束一脉相承宁可不新增测试也不要新增一个低价值的、与实现耦合的测试。交付前的质量门禁在交接handoff之前必须按顺序运行pnpm run format pnpm run i18n pnpm run lint pnpm run typecheck以及相关的测试。这些门禁在 package.json 中均有对应实现format使用oxfmt .另有format:check用于只检查不改动i18n由i18n:validatescripts/validate-i18n.mjs与i18n-check -s zh-CN组成检查src/renderer/src/i18n的语言键一致性lint是三个步骤的组合lint:agent-cleanupscripts/agent-cleanup-guard.mjs、lint:alert-dialog-contractscripts/alert-dialog-contract-guard.mjs以及oxlint .typecheck分为typecheck:nodetsc -p tsconfig.node.json与typecheck:webvue-tsc -p tsconfig.app.json两段。有一个容易被忽略的坑需要特别注意应用的类型检查并不会自动类型检查每一个测试文件类型层面的断言type-only assertions需要显式的类型检查目标才能提供证据。这正是test:memory:typetypecheck-memory-tests.mjs存在的意义——内存测试的类型正确性需要单独验证。手工 deeplink 验证除自动化测试外test/README.md 还定义了手工验证 deeplink 的流程。在 DeepChat 运行时用浏览器打开 test/manual/deeplink-playground.html页面会为三类 deeplink 提供假的 payload 示例并允许浏览器唤起deepchat://协议部分环境会先弹出确认。三类 deeplink 及其在页面中的实现见 test/manual/deeplink-playground.html 的脚本部分deepchat://start唤起应用并把预置消息、模型或 mentions 带入新会话。payload 支持msg、model、system、mentions字段链接格式为deepchat://start?msg...model...deepchat://mcp/install安装 stdio / sse MCP 配置。payload 为mcpServers对象commandargs或urltype当前协议参数名是code值是对 payload JSON 做 Base64 编码后再 URL 编码的结果deepchat://provider/install导入 provider。payload 区分 built-in 与 custom 两种语义built-in 用id匹配并覆盖custom 用name type新增built-in 导入列表已排除acp它不属于settings-provider导入流。链接格式为deepchat://provider/install?v1dataBase64(JSON)。页面还内置了一个 provider 链接构造器builder可临时修改id / name / type / baseUrl / apiKey实时生成符合应用解析格式的 deeplink方便外部联调。小结从命令到策略的一体化测试体系DeepChat 的测试体系是命令矩阵 分层策略 契约守护的一体化工程命令层覆盖 main/renderer/memory/e2e 四大作用域并提供最小目标运行方式策略层强调保留真实域逻辑、替代昂贵边界、以契约为准治理层通过memory-test-scope.json、作用域校验脚本与严格的删除准则防止测试体系腐化交付层则以 format、i18n、lint、typecheck 四道门禁兜底。对参与 DeepChat 开发的工程师而言把 test/README.md 中的命令矩阵与准则内化就等于拿到了这套 Electron Vitest Vue Test Utils Playwright 混合测试栈的正确使用方式。【免费下载链接】deepchatDeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchat创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表