Skip to content

Latest commit

 

History

History
252 lines (184 loc) · 10 KB

File metadata and controls

252 lines (184 loc) · 10 KB

Testing Guide

面向开发者和 AI Agent 的测试参考手册。

目录


测试架构

测试分为三层,全部使用 vitest 运行:

tests/
├── e2e/                           # E2E 集成测试(子进程运行真实 CLI)
│   ├── helpers.ts                 # runCli() / parseJsonOutput() 共享工具
│   ├── public-commands.test.ts    # 公开 API 命令
│   ├── browser-public.test.ts     # 浏览器命令(公开数据)
│   ├── browser-auth.test.ts       # 需登录命令(graceful failure)
│   ├── management.test.ts         # 管理命令(list / validate / verify / help)
│   └── output-formats.test.ts     # 输出格式校验
├── smoke/
│   └── api-health.test.ts         # 外部 API、adapter 定义、命令注册健康检查
src/
└── **/*.test.ts                   # 单元测试(当前 32 个文件)
位置 当前文件数 运行方式 用途
单元测试 src/**/*.test.ts 32 npx vitest run src/ 内部模块、pipeline、adapter 工具函数
E2E 测试 tests/e2e/*.test.ts 5 npx vitest run tests/e2e/ 真实 CLI 命令执行
烟雾测试 tests/smoke/*.test.ts 1 npx vitest run tests/smoke/ 外部 API 与注册完整性

当前覆盖范围

单元测试(32 个文件)

领域 文件
核心运行时与输出 src/browser.test.ts, src/browser/dom-snapshot.test.ts, src/build-manifest.test.ts, src/capabilityRouting.test.ts, src/doctor.test.ts, src/engine.test.ts, src/interceptor.test.ts, src/output.test.ts, src/plugin.test.ts, src/registry.test.ts, src/snapshotFormatter.test.ts
pipeline 与下载 src/download/index.test.ts, src/pipeline/executor.test.ts, src/pipeline/template.test.ts, src/pipeline/transform.test.ts
站点 / adapter 逻辑 src/clis/apple-podcasts/commands.test.ts, src/clis/apple-podcasts/utils.test.ts, src/clis/bloomberg/utils.test.ts, src/clis/chaoxing/utils.test.ts, src/clis/coupang/utils.test.ts, src/clis/google/utils.test.ts, src/clis/grok/ask.test.ts, src/clis/twitter/timeline.test.ts, src/clis/weread/utils.test.ts, src/clis/xiaohongshu/creator-note-detail.test.ts, src/clis/xiaohongshu/creator-notes-summary.test.ts, src/clis/xiaohongshu/creator-notes.test.ts, src/clis/xiaohongshu/search.test.ts, src/clis/xiaohongshu/user-helpers.test.ts, src/clis/xiaoyuzhou/utils.test.ts, src/clis/youtube/transcript-group.test.ts, src/clis/zhihu/download.test.ts

这些测试覆盖的重点包括:

  • Browser Bridge、DOM snapshot、interceptor、capability routing
  • manifest 生成、命令发现、插件安装与注册表
  • 输出格式渲染与 snapshot formatting
  • pipeline 模板求值、执行器与变换步骤
  • 各站点 adapter 的数据归一化、参数处理与容错逻辑

E2E 测试(5 个文件)

文件 当前覆盖范围
tests/e2e/public-commands.test.ts bloombergapple-podcastshackernewsv2exxiaoyuzhougoogle suggest 等公开命令
tests/e2e/browser-public.test.ts bbcbloombergbilibiliweibozhihureddittwitterxueqiureutersyoutubesmzdmbossctripcoupangxiaohongshugoogleyahoo-financev2ex daily
tests/e2e/browser-auth.test.ts bilibilitwitterv2exxueqiulinux-doxiaohongshu 的需登录命令 graceful failure
tests/e2e/management.test.ts listvalidateverify--version--help、unknown command
tests/e2e/output-formats.test.ts json / yaml / csv / md 输出格式校验
tests/e2e/plugin-management.test.ts plugin install / list / update / uninstall 全生命周期

烟雾测试(1 个文件)

文件 当前覆盖范围
tests/smoke/api-health.test.ts hackernewsv2ex 公开 API 可用性,validate 全量 adapter 校验,以及命令注册表基础完整性

快速核对命令

需要刷新测试清单时,直接以仓库文件为准:

find src -name '*.test.ts' | sort
find tests/e2e -name '*.test.ts' | sort
find tests/smoke -name '*.test.ts' | sort

本地运行测试

前置条件

npm ci                # 安装依赖
npm run build         # 编译(E2E / smoke 测试需要 dist/main.js)

运行命令

# 全部单元测试
npx vitest run src/

# 全部 E2E 测试(会真实调用外部 API / 浏览器)
npx vitest run tests/e2e/

# 全部 smoke 测试
npx vitest run tests/smoke/

# 单个测试文件
npx vitest run src/clis/apple-podcasts/commands.test.ts
npx vitest run tests/e2e/management.test.ts

# 全部测试
npx vitest run

# watch 模式(开发时推荐)
npx vitest src/

浏览器命令本地测试须知

  • opencli 通过 Browser Bridge 扩展连接已运行的 Chrome 浏览器
  • E2E 测试通过 tests/e2e/helpers.ts 里的 runCli() 调用已构建的 dist/main.js
  • browser-public.test.ts 使用 tryBrowserCommand(),站点反爬或地域限制导致空数据时会 warn + pass
  • browser-auth.test.ts 验证 graceful failure,重点是不 crash、不 hang、错误信息可控
  • 如需测试完整登录态,保持 Chrome 登录态并安装 Browser Bridge 扩展,再手动运行对应测试

如何添加新测试

新增 YAML Adapter(如 src/clis/producthunt/trending.yaml

  1. opencli validate 的 E2E / smoke 测试会覆盖 adapter 结构校验
  2. 根据 adapter 类型,在对应测试文件补一个 it() block
// 如果 browser: false(公开 API)→ tests/e2e/public-commands.test.ts
it('producthunt trending returns data', async () => {
  const { stdout, code } = await runCli(['producthunt', 'trending', '--limit', '3', '-f', 'json']);
  expect(code).toBe(0);
  const data = parseJsonOutput(stdout);
  expect(Array.isArray(data)).toBe(true);
  expect(data.length).toBeGreaterThanOrEqual(1);
  expect(data[0]).toHaveProperty('title');
}, 30_000);
// 如果 browser: true 但可公开访问 → tests/e2e/browser-public.test.ts
it('producthunt trending returns data', async () => {
  const data = await tryBrowserCommand(['producthunt', 'trending', '--limit', '3', '-f', 'json']);
  expectDataOrSkip(data, 'producthunt trending');
}, 60_000);
// 如果 browser: true 且需登录 → tests/e2e/browser-auth.test.ts
it('producthunt me fails gracefully without login', async () => {
  await expectGracefulAuthFailure(['producthunt', 'me', '-f', 'json'], 'producthunt me');
}, 60_000);

新增管理命令(如 opencli export

tests/e2e/management.test.ts 添加测试;如果新命令会影响输出格式,也同步补 tests/e2e/output-formats.test.ts

新增内部模块

在对应源码旁创建 *.test.ts,优先和被测模块放在同一目录下,便于发现与维护。

决策流程图

新增功能 → 是内部模块? → 是 → src/ 下加 *.test.ts
                ↓ 否
         是 CLI 命令? → browser: false? → tests/e2e/public-commands.test.ts
                              ↓ true
                        公开数据? → tests/e2e/browser-public.test.ts
                              ↓ 需登录
                        tests/e2e/browser-auth.test.ts

CI/CD 流水线

ci.yml

Job 触发条件 内容
build push/PR 到 main,dev tsc --noEmit + npm run build
unit-test push/PR 到 main,dev Node 2022 双版本运行 src/ 单元测试,按 2 shard 并行
smoke-test scheduleworkflow_dispatch 安装真实 Chrome,xvfb-run 执行 tests/smoke/

e2e-headed.yml

Job 触发条件 内容
e2e-headed push/PR 到 main,dev,或手动触发 安装真实 Chrome,xvfb-run 执行 tests/e2e/

E2E 与 smoke 都使用 ./.github/actions/setup-chrome 准备真实 Chrome,并通过 OPENCLI_BROWSER_EXECUTABLE_PATH 注入浏览器路径。

Sharding

单元测试使用 vitest 内置 shard,并在 Node 20 / 22 两个版本上运行:

strategy:
  matrix:
    node-version: ['20', '22']
    shard: [1, 2]
steps:
  - run: npx vitest run src/ --reporter=verbose --shard=${{ matrix.shard }}/2

浏览器模式

opencli 通过 Browser Bridge 扩展连接浏览器:

条件 模式 使用场景
扩展已安装 / 已连接 Extension 模式 本地用户,连接已登录的 Chrome
无扩展 token CLI 自行拉起浏览器 CI、无登录态或纯自动化场景

CI 中使用 OPENCLI_BROWSER_EXECUTABLE_PATH 指定真实 Chrome 路径:

env:
  OPENCLI_BROWSER_EXECUTABLE_PATH: ${{ steps.setup-chrome.outputs.chrome-path }}

站点兼容性

GitHub Actions 的美国 runner 上,部分站点会因为地域限制、登录要求或反爬而返回空数据。当前 E2E 对这些场景采用 warn + pass 策略,避免偶发站点限制把整条 CI 打红。

站点 CI 表现 常见原因
hackernewsbbcv2exbloomberg 通常返回数据 公开接口或公开页面
yahoo-financegoogle 通常返回数据 页面公开,但仍可能受限流影响
bilibilizhihuweiboxiaohongshuxueqiu 容易空数据 地域限制、反爬、登录要求
reddittwitteryoutube 容易空数据 登录态、cookie、机器人检测
smzdmbossctripcoupanglinux-do 结果波动较大 地域限制、风控或页面结构变动

如果需要更稳定的浏览器 E2E 结果,优先使用具备目标站点网络可达性的 self-hosted runner。