Skip to content

Testing Guide

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

目录


测试架构

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

tests/
├── e2e/                           # E2E 集成测试(子进程运行真实 CLI)
│   ├── helpers.ts                 # runCli() 共享工具
│   ├── 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     # 输出格式(json/yaml/csv/md)
├── smoke/                         # 烟雾测试(仅定时 / 手动触发)
│   └── api-health.test.ts         # 外部 API 可用性检测
src/
├── *.test.ts                      # 单元测试(已有 8 个)
位置运行方式用途
单元测试src/**/*.test.tsnpx vitest run src/内部模块逻辑
E2E 测试tests/e2e/*.test.tsnpx vitest run tests/e2e/真实 CLI 命令执行
烟雾测试tests/smoke/*.test.tsnpx vitest run tests/smoke/外部 API 健康

当前覆盖范围

单元测试(8 个文件)

文件覆盖内容
browser.test.tsJSON-RPC、tab 管理、extension/standalone 模式切换
engine.test.ts命令发现与执行
registry.test.ts命令注册与策略分配
output.test.ts输出格式渲染
doctor.test.tsToken 诊断
coupang.test.ts数据归一化
pipeline/template.test.ts模板表达式求值
pipeline/transform.test.ts数据变换步骤

E2E 测试(~52 个用例)

文件覆盖站点/功能测试数
public-commands.test.tshackernews/top, v2ex/hot, v2ex/latest, v2ex/topic5
browser-public.test.tsbbc, bilibili×3, weibo, zhihu×2, reddit×2, twitter, xueqiu×2, reuters, youtube, smzdm, boss, ctrip, coupang, xiaohongshu, yahoo-finance, v2ex/daily21
browser-auth.test.tsbilibili/me,dynamic,favorite,history,following + twitter/bookmarks,timeline,notifications + v2ex/me,notifications + xueqiu/feed,watchlist + xiaohongshu/feed,notifications14
management.test.tslist×5 格式, validate×3 级别, verify, --version, --help, unknown cmd12
output-formats.test.tsjson, yaml, csv, md 格式验证5

烟雾测试

公开 API 可用性(hackernews, v2ex×2, v2ex/topic)+ 全站点注册完整性检查。


本地运行测试

前置条件

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

运行命令

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

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

# 单个测试文件
npx vitest run tests/e2e/management.test.ts

# 全部测试(单元 + E2E)
npx vitest run

# 烟雾测试
npx vitest run tests/smoke/

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

浏览器命令本地测试须知

  • opencli 通过 Browser Bridge 扩展连接已运行的 Chrome 浏览器
  • browser-public.test.ts 使用 tryBrowserCommand(),站点反爬导致空数据时 warn + pass
  • browser-auth.test.ts 验证 graceful failure(不 crash 不 hang 即通过)
  • 如需测试完整登录态,保持 Chrome 登录态并安装 Browser Bridge 扩展,手动跑对应测试

如何添加新测试

  1. 无需额外操作validate 测试会自动覆盖 YAML 结构验证
  2. 根据 adapter 类型,在对应文件加一个 it() block:
typescript
// 如果 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);
typescript
// 如果 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);
typescript
// 如果 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 添加测试。

新增内部模块

src/ 下对应位置创建 *.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触发条件内容
buildpush/PR to main,devtypecheck + build
unit-testpush/PR to main,dev单元测试,2 shard 并行
smoke-test每周一 08:00 UTC / 手动xvfb + real Chrome,外部 API 健康检查

e2e-headed.yml(E2E 测试)

Job触发条件内容
e2e-headedpush/PR to main,devxvfb + real Chrome,全部 E2E 测试

E2E 使用 browser-actions/setup-chrome 安装真实 Chrome,配合 xvfb-run 提供虚拟显示器,以 headed 模式运行浏览器。

Sharding

单元测试使用 vitest 内置 shard:

yaml
strategy:
  matrix:
    shard: [1, 2]
steps:
  - run: npx vitest run src/ --shard=${{ matrix.shard }}/2

浏览器模式

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

条件模式使用场景
扩展已安装Extension 模式本地用户,连接已登录的 Chrome
扩展未安装CLI 报错提示安装需要安装 Browser Bridge 扩展

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

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

站点兼容性

在 GitHub Actions 美国 runner 上,部分站点因地域限制或登录要求返回空数据。E2E 测试对这些站点使用 warn + pass 策略,不影响 CI 绿灯。

站点CI 状态限制原因
hackernews, bbc, v2ex✅ 返回数据无限制
yahoo-finance✅ 返回数据无限制
bilibili, zhihu, weibo, xiaohongshu⚠️ 空数据地域限制(中国站点)
reddit, twitter, youtube⚠️ 空数据需登录或 cookie
smzdm, boss, ctrip, coupang, xueqiu⚠️ 空数据地域限制 / 需登录

使用 self-hosted runner(国内服务器)可解决地域限制问题。

Released under the Apache-2.0 License.