OpenProgram 测试系统

本页定义测试分类、目录、依赖边界、执行命令和 CI 职责。测试层级由运行时依赖决定,产品域沿用 openprogram/ 的模块名称。结构迁移不改变产品行为;测试发现的真实产品缺陷按独立批次修复和验证。

1. 当前实现与已验证差距

Python 规模383 个 tracked Python 测试文件,约 10.5 万行。大部分集中在 tests/unit,但其中包含 HTTP client、subprocess、临时状态库和真实线程。
共享状态tests/conftest.py 在 collection 阶段修改代理、HOME 和多个进程全局对象。临时 HOME 未自动删除,局部状态恢复依赖全局 autouse fixture。
并发与等待测试中存在固定 time.sleep,部分测试替换全局 threading.Thread。这会影响 pytest-xdist 的控制线程和失败诊断。
仓库扫描部分检查通过 Path.rglob 扫描工作目录,会包含 ignored Finder 副本和嵌套 application repository,因此相同 commit 可产生不同结果。
JavaScriptCLI 已使用 Vitest;Web 主要使用读取源代码后执行正则断言的脚本;desktop 主要使用 Node VM 和 fake Electron,CI 只执行其中一个脚本。
CIPython matrix 排除 integration;未执行 Ruff、CLI test/build 和完整 desktop checks;Web 构建与 Python frontend integration fixture 没有统一契约。

2. 参考框架及职责边界

参考信息来自各项目官方文档。仓库继续使用现有工具;本设计不增加新的通用 test runner。

工具采用能力未提供的能力OpenProgram 处理方式
pytestPython discovery、fixture、marker、warning 和 xfail 策略不执行 JavaScript,也不保证 fixture 自身具备进程隔离负责 Python contracts、unit、component、integration、e2e 和 live
pytest-xdist多进程分发不能修复全局状态、后台线程或不安全 monkeypatch隔离问题修复并重复验证后,只启用固定 worker 数
node:testNode 22 内置断言、test 和 mock不提供真实 DOM 和浏览器交互用于 Web 纯 TypeScript/JavaScript 逻辑,避免新增依赖
VitestCLI 已有的 TypeScript test runner不覆盖 Python worker 和真实浏览器仅保留在 CLI,不在 Web 再安装一份
Playwright真实浏览器、用户可见行为和跨页面状态不替代 unit/component 测试复用 Python browser extra,使用 Playwright 管理的 Chromium
GitHub Actions版本矩阵、job 隔离和 required checks不定义测试语义按测试层级拆分 jobs,使用相同的本地命令

3. 目标结构

tests/
  contracts/{repository,security}/
  unit/<product-domain>/
  component/<product-domain>/
  integration/<product-domain>/
  e2e/{agent,context,web}/
  live/{providers,channels}/
  support/
  conftest.py
层级允许依赖禁止依赖默认执行
contractsAST、tracked files、manifest、registry、schema外部服务;用源码文本代替行为断言每次 PR
unit内存对象、纯函数、局部 fake、单模块使用的隔离临时文件;生产模块内部受控且可清理的线程资源TestClient、socket、subprocess、测试代码直接创建的真实后台线程或线程池、固定 sleepPython 3.11/3.12/3.13
componenttmp_path、临时 SQLite、TestClient、fake provider、受控线程外部网络和真实凭证Python 3.12
integrationloopback HTTP/WS、真实 subprocess、多个生产模块外部服务Python 3.12
e2e公开 CLI、真实 worker、构建后的 Web、浏览器开发者真实 HOME 和预先存在的构建产物专用 CI job
live真实 provider、channel、远端服务普通 PR required checks手动或定时

同一测试符合多个层级时,按依赖最强的层级分类。目录最多使用“层级/产品域”两级。marker 只描述执行能力:slowbrowsersandboxlive;不重复声明目录已经表达的层级。

4. 执行和状态隔离

5. Web、CLI 与 desktop

现有检查目标判定
Web security/architecture source checkweb/scripts/check-*.mjs只有源代码结构本身属于契约时保留
Web pure helper behaviorweb/tests/*.test.mjs + node:test直接 import 并断言输入输出
Web user interactiontests/e2e/web + Playwright操作构建后的页面并观察公开行为
CLI TypeScript现有 VitestCI 执行 typecheck、test、build
desktop VM/fake Electrondesktop component checksCI 执行完整 npm run check
真实 Electronrelease e2e初始重构不新增打包测试基础设施

6. CI 数据流

Python 命令使用 uv run --locked。矩阵关闭 fail-fast,避免一个版本失败后取消其他结果。普通 PR 不执行 live。所有 CI 命令同时写入贡献文档。

7. 采用、调整与拒绝

状态决定边界
采用层级优先目录、产品域二级目录、strict markers、strict xfail、固定 worker 数、Playwright-managed Chromium迁移时保持测试语义和数量
调整保留必要的 Web source contracts,同时把纯逻辑迁移到 node:test不一次性重写全部 Web checks
调整初期只生成 coverage 报告稳定后依据实测数据设置阈值
拒绝新增 tox/nox、在 Web 再安装 Vitest、-n auto、全局任意覆盖率阈值现有工具已经覆盖需求,或当前状态不具备稳定并行条件
排除Windows-specific 测试、打包和兼容性;keyring/Credential Manager不属于本次测试系统重构

8. 验收标准

9. 实现状态

工作项状态完成证据
设计与基线已完成设计、站点构建、链接检查、clean-checkout baseline 和两阶段独立审查
输入枚举与共享状态已完成Git-owned 输入枚举、临时 HOME 清理、局部 fixture、线程与 TLS 资源回收;专项及 unit 回归、独立规格和质量审查通过
Python 目录迁移已完成目录与 marker 迁移完成;HTTP inventory 重复实现、agentic context 结构契约误报和 retry 测试隔离问题已修复;最终 required suite 为 5356 passed、10 skipped、1 xfailed,独立规格与质量审查通过
Web/CLI/desktop已完成Web pure helper 使用 node:test,component 与 built-Web/browser e2e 分离;当前 Scheduler view-model 为 4 个 Node 单元测试,Web check/build、CLI typecheck/Vitest/build、desktop check 与独立审查通过
CI 与贡献文档已完成十类独立 CI 结果、三版本 unit matrix、locked uv、非 browser e2e、完整 Web/CLI/desktop/browser 命令与贡献文档 contract;独立审查通过
等待、并发与大文件已完成结构契约覆盖资源导入、固定等待与全局线程类替换;unit autouse guard 检查测试直接创建线程/线程池、固定等待、生产资源 teardown 和全局状态恢复;5 个真实 runner/threadpool 文件共 104 个测试迁至 component;最终 required suite 为 5370 passed、10 skipped、2 deselected、1 xfailed
覆盖率和最终验证已完成API-key CLI unit 已隔离远程模型列表获取;Python 3.12 串行 unit branch-mode coverage 重复基线为 42.267228%,CI 先生成并上传 XML artifact,再以 6 位精度执行 40% floor;固定 -n 4 required selection 连续三次为 5370 passed、10 skipped、1 xfailed、0 worker crash;最终 Python、JavaScript、browser、docs、example、Desktop 目录包和静态检查门禁全部通过

10. 完善计划与实施记录

以下批次依次完成。每批先用公开或共享边界复现失败,再修复最小共享根因,执行专项与受影响测试,完成独立规格审查和质量审查后提交。前一批未通过审查时不开始下一批。

批次范围排除门禁状态
required suite 归零移除未被注册表使用的旧 channel 实现;修正 @function / @agentic_function 结构契约误报;隔离 retry 测试状态不改变受管理 channel 实现和公开 API4 个失败节点专项通过;最终 required suite 为 5356 passed、10 skipped、1 xfailed;独立规格与质量审查通过已完成
结构与等待契约识别别名资源导入、线程类替换和非零异步等待;运行时拦截测试直接创建线程或线程池;迁移或改写实际违规测试不实现 Python 控制流解释器,不按文件行数机械拆分测试结构与运行时契约通过;unit 为 2434 passed、3 skipped;5 个迁移 component 文件为 104 passed;独立规格和质量审查通过已完成
覆盖率门禁记录精确 branch baseline;设置防回退阈值;只补关键未覆盖分支不追求任意高覆盖率数字,不为覆盖率复制断言隔离 Python 3.12.13 locked 环境连续两次均为 unit 2434 passed、3 skipped,branch-mode baseline 42.267228%;6 位精度的 40% floor 通过,43% 对照以退出码 2 失败;XML 在 floor 前上传,CI contract 通过已完成
JavaScript 依赖风险分别审计 Web、CLI、desktop;升级可兼容依赖并验证 lockfile不执行 npm audit fix --force,不引入新 runner兼容升级后 Web 从 8 high 降至 5 high,CLI 从 4 high + 1 moderate 降至 1 moderate,desktop 从 5 high + 2 moderate 降至 2 high;剩余项分别要求 Next/eslint-config-next 16、esbuild 0.28、Electron 43 的独立兼容迁移;三个 workspace 的 npm ci 与既有 check/test/typecheck/build 全部通过已完成
最终集成合入最新 main,执行 Python、Web、CLI、desktop、browser、docs、examples 和 diff/status 门禁不覆盖主工作区未提交修改,不远程 push串行 required suite 为 5370 passed、10 skipped、2 deselected、1 xfailed;固定 -n 4 连续三次均为 5370 passed、10 skipped、1 xfailed、0 worker crash;非 browser e2e 4 passed、2 deselected;unit coverage 两次为 42.267228%;Web 4 tests/typecheck/check/build、CLI 140 passed + 2 skipped/typecheck/build、desktop check 与 dist:dir、browser 2 passed、docs build/landing/0 broken links、example、Ruff 与 diff-check 全部通过;最终候选独立规格和质量审查通过,工作树 clean已完成