首页
/ Supabase 仓库中 Vitest CLI 实战指南:命令、常用选项与 CI 分片策略全解析

Supabase 仓库中 Vitest CLI 实战指南:命令、常用选项与 CI 分片策略全解析

2026-09-05 16:06:40作者:宗隆裙

本文以 Supabase 开源仓库内置的 Vitest CLI 参考文档为骨架,完整梳理 Vitest 命令行接口(CLI)的命令体系、常用选项与 CI 分片策略,并结合该仓库中多个应用(Studio、Docs、WWW、UI 包)的真实测试脚本与配置文件,说明这些命令和选项在大型 pnpm + Turborepo monorepo 中的实际用法。读完本文,你既能快速掌握 Vitest CLI 的每个子命令与过滤、覆盖率、分片等关键参数的含义,也能学到一套可直接复用到 Supabase 这类 monorepo 中的测试执行与 CI 组织方式。

1. CLI 文档在 Supabase 仓库中的定位

该文档位于仓库的 Agent 技能目录 .agents/skills/vitest/references/core-cli.md,属于 Vitest 技能包(见 .agents/skills/vitest/SKILL.md)中"Core"部分的 CLI 参考页,基于 Vitest 3.x 于 2026-01-28 生成。它与同目录下的 core-configcore-test-apifeatures-filtering 等参考页共同构成 Vitest 的速查手册。

在 Supabase 仓库中,Vitest 是多个应用的单测执行器。根目录 package.json 通过 Turborepo 定义了按包过滤的测试入口:

{
  "scripts": {
    "test:docs": "turbo run test --filter=docs",
    "test:ui": "turbo run test --filter=ui",
    "test:ui-patterns": "turbo run test --filter=ui-patterns",
    "test:studio": "turbo run test --filter=studio",
    "test:studio:watch": "turbo run test --filter=studio -- watch"
  }
}

即根命令 turbo run test --filter=<包名> 最终落到各包 package.jsontest 脚本上,而各包的 test 脚本正是本文所讲的 Vitest CLI 命令组合。仓库运行环境要求(根 package.jsonengines 字段)为 Node >=22.13、pnpm 11.13

2. 命令体系:从 vitestvitest init

2.1 vitest:默认入口

裸命令 vitest 的行为取决于运行环境——开发环境进入 watch 模式,CI 环境(process.env.CI 已设置)自动切换为 run 模式

vitest                    # Watch mode in dev, run mode in CI
vitest foobar             # Run tests containing "foobar" in path
vitest basic/foo.test.ts:10  # Run specific test by file and line number

两个细节值得注意:

  • 位置参数支持"文件名包含"式模糊匹配(vitest foobar 匹配路径中含 foobar 的测试文件),也支持 文件路径:行号 的精确格式;
  • CI 自动检测正是 Supabase 仓库中大量配置生效的开关。例如 apps/studio/vitest.config.ts 中:
const IS_CI = !!process.env.CI
// ...
test: {
  // Retry flaky tests in CI only; failures locally should surface immediately.
  retry: IS_CI ? 2 : 0,
}

可以确认:Studio 包的配置刻意让本地失败立即暴露,而仅在 CI 中对 flaky 测试重试 2 次(对应 CLI 的 --retry 选项)。

2.2 vitest run:单次运行

显式以"运行一次后退出"的模式执行,是 CI 与提交前检查的推荐形式:

vitest run
vitest run --coverage

Supabase 仓库中多个包都遵循这一约定。例如 apps/www/package.jsonpackages/dev-tools/package.json

{ "test": "vitest --run" }        // apps/www(kebab-case 等价写法)
{ "test": "vitest run" }           // packages/dev-tools(子命令写法)

两种写法(vitest run 子命令与 vitest --run 标志)都用于保证"单次运行",文档在 Key Points 中特别强调了对 lint-staged 等 pre-commit 工具的重要性——否则钩子会卡在 watch 模式无法退出。

2.3 vitest watch:显式 watch 模式

vitest watch

与 2.1 中依赖环境推断不同,vitest watch 明确强制进入 watch 模式。仓库中 apps/studio/package.json 提供了典型的本地开发脚本:

{
  "scripts": {
    "test:watch": "vitest watch",
    "test": "vitest --run --coverage",
    "test:ui": "vitest --ui",
    "test:update": "vitest --run --update",
    "test:report": "open coverage/lcov-report/index.html"
  }
}

从源码结构看,Studio 包的日常测试闭环是:test:watch 开发调试 → test(等价于 vitest --run --coverage)提交前全量跑 → test:report 打开 lcov HTML 报告。其中 test:report 能打开 coverage/lcov-report/,正是因为 apps/studio/vitest.config.ts 的覆盖率配置声明了 reporter: ['text', 'text-summary', 'lcov'] 且限定 include: ['lib/**/*.ts']

2.4 vitest related:只跑与变更文件相关的测试

vitest related src/index.ts src/utils.ts --run

该命令执行"导入(或反被导入)指定文件"的测试集合,文档特别标注其典型搭档是 lint-staged:在 pre-commit 阶段只对被暂存文件影响的测试跑单测,兼顾速度与覆盖。结尾的 --run 同样是为了让钩子能单次运行后退出。

2.5 vitest bench:只跑基准测试

vitest bench

独立于普通测试执行 bench 套件,避免基准测试拖慢常规 vitest run 的反馈周期。

2.6 vitest list:只列出、不执行

vitest list                    # List test names
vitest list --json             # Output as JSON
vitest list --filesOnly        # List only test files

list 命令在 CI 编排与工具链集成中非常实用:--json 输出可被脚本消费以生成测试清单或分片计划;--filesOnly 则用于快速清点测试文件分布,例如确认 apps/docs/vitest.config.tsexclude: ['examples/**/*', '**/node_modules/**'] 生效后的文件集合。

2.7 vitest init:初始化项目

vitest init browser            # Set up browser testing

用于在新项目中生成基础测试脚手架(如 browser 模式);对已经落地 Vitest 的成熟仓库,init 主要价值是参考其生成的配置形态。

3. 常用选项速查(含仓库佐证)

文档给出的常见选项按用途分组如下,本文在每组后补充了 Supabase 仓库中的实际用法佐证:

# Configuration
--config <path>           # Path to config file
--project <name>          # Run specific project

# Filtering
--testNamePattern, -t     # Run tests matching pattern
--changed                 # Run tests for changed files
--changed HEAD~1          # Tests for last commit changes

# Reporters
--reporter <name>         # default, verbose, dot, json, html
--reporter=html --outputFile=report.html

# Coverage
--coverage                # Enable coverage
--coverage.provider v8    # Use v8 provider
--coverage.reporter text,html

# Execution
--shard <index>/<count>   # Split tests across machines
--bail <n>                # Stop after n failures
--retry <n>               # Retry failed tests n times
--sequence.shuffle        # Randomize test order

# Watch mode
--no-watch                # Disable watch mode
--standalone              # Start without running tests

# Environment
--environment <env>       # jsdom, happy-dom, node
--globals                 # Enable global APIs

# Debugging
--inspect                 # Enable Node inspector
--inspect-brk             # Break on start

# Output
--silent                  # Suppress console output
--no-color                # Disable colors

3.1 过滤类:-t / --testNamePattern 的真实用例

apps/docs/package.json 中的 smoke 测试脚本是一个教科书级示例:

{
  "scripts": {
    "test": "pnpm supabase start && pnpm run test:local && pnpm supabase stop",
    "test:local": "vitest --exclude \"**/*.smoke.test.ts\"",
    "test:local:unwatch": "vitest --exclude \"**/*.smoke.test.ts\" --run",
    "test:smoke": "pnpm run codegen:references && vitest -t \"prod smoke test\""
  }
}

test:smoke-t "prod smoke test" 按测试名模式只跑 smoke 用例;test:local--exclude 把需要真实环境的 smoke 文件排除在本地单测之外,而 test:local:unwatch 再追加 --run 得到"排除 smoke 的单次运行"。这说明 CLI 标志与配置文件选项(如 apps/docs/vitest.config.ts 中的 setupFilesglobalSetupexclude)可以叠加组合:配置定基线,CLI 标志做增量调整。

3.2 执行类:--retry 与环境差异

--retry <n> 在 Studio 包通过 retry: IS_CI ? 2 : 0(见 apps/studio/vitest.config.ts)体现为"CI 重试、本地零容忍"的策略,与文档 Key Points 中"watch 模式是开发默认、CI 自动切 run 模式"的设计哲学一致:本地求快求真,CI 求稳。

3.3 环境与全局 API:--environment / --globals

Studio 与 UI 包均为 React 组件测试,配置中显式声明了 environment: 'jsdom'(见 apps/studio/vitest.config.tspackages/ui/vitest.config.ts),Studio 还同时开启 globals: true 以省略 import { describe, it, expect }--environment 标志的价值在于临时覆盖配置——例如想对某个用例切换到 node 环境验证时不必改配置文件。

3.4 调试与输出:--inspect / --silent

--inspect--inspect-brk 用于把 Node inspector 挂到测试进程上排查挂死、内存问题;--silent 抑制测试内 console 输出,便于在 CI 中聚焦失败信息。文档同时指出布尔选项支持 --no- 前缀取反(如 --no-watch--no-color),且驼峰与 kebab-case 双写法通用(--testTimeout--test-timeout)——仓库脚本中两种风格都有出现(vitest --run --coveragevitest list --filesOnly 即为证)。

4. package.json Scripts 的组织范式

文档给出的最小脚本集:

{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:ui": "vitest --ui",
    "coverage": "vitest run --coverage"
  }
}

对照 Supabase 仓库,各包在"watch/单次/UI/覆盖率"四个维度上都给出了实现,例如:

test 本地 watch 其他
apps/studio vitest --run --coverage vitest watch test:uitest:updatevitest --run --update)、test:report
apps/www vitest --run vitest watch
packages/ui vitest
packages/dev-tools vitest run vitest

可见仓库实际做法比文档模板更细:把"默认带覆盖率的 CI 跑法"直接放进 test(供 Turborepo 的 turbo run test --filter=studio 聚合调用),把"带 UI 的可视化运行"与"快照更新"拆成独立脚本,避免开发者手敲长串标志。根目录 package.jsontest:studio:watchturbo run test --filter=studio -- watch)还展示了 Turborepo 语法:-- 之后的参数会透传给目标包的 test 脚本,从而临时切换到 watch 参数。

5. CI 分片(Sharding):文档方案与仓库实践

5.1 文档给出的标准分片流程

将测试切分到多台机器并行,最后合并报告:

# Machine 1
vitest run --shard=1/3 --reporter=blob

# Machine 2
vitest run --shard=2/3 --reporter=blob

# Machine 3
vitest run --shard=3/3 --reporter=blob

# Merge reports
vitest --merge-reports --reporter=junit

要点:每台机器用 --shard=index/count 声明自己在分片矩阵中的位置,并以 blob reporter 产出可合并的中间报告;聚合端用 --merge-reports 把所有分片的 blob 汇总为最终报告(示例输出为 junit)。

5.2 仓库中同构的 CI 实践

从源码结构看,Supabase 仓库的 e2e CI 采用了与上述文档完全同构的"分片 + blob + merge"三件套,见 .github/workflows/studio-e2e-test.yml

strategy:
  matrix:
    shardIndex: [1, 2]
    shardTotal: [2]
# ...
run: PWTEST_SHARD_WEIGHTS=62:38 pnpm e2e --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}

工作流中包含独立的 merge-reports job 聚合各分片结果,并用 blob-report-<framework>-<shardIndex> 命名的工件传递中间报告。虽然该流水线分片的是 Playwright e2e 套件,但其"矩阵分片 → 每片产出 blob 工件 → 独立 job 合并"的架构与 vitest run --shard=n/m --reporter=blob + vitest --merge-reports 的方案一一对应。可以推断:在 Studio 这类测试量大的包上,Vitest 单测分片若需横向扩展,可直接套用文档中的标准写法,与现有 CI 的分片/合并习惯保持一致。

6. Watch 模式快捷键与关键行为要点

6.1 键盘快捷键

进入 watch 模式后按以下键与测试会话交互:

按键 作用
a 运行全部测试(清除过滤)
f 只运行上次失败的测试
u 更新快照
p 按文件名模式过滤
t 按测试名模式过滤
q 退出

这套快捷键与 CLI 的过滤选项形成对应关系:p 对应路径过滤,t 对应 --testNamePatternu 等价于 --update(Studio 包的 test:update 脚本即其一次性版本)。

6.2 Key Points 汇总

文档结尾的四条行为要点是使用 CLI 前必须建立的心智模型,本文结合仓库给出印证:

  1. Watch 是开发默认、CI 是 run 模式——由 process.env.CI 驱动。Supabase 的 CI 侧脚本(如 apps/studio/package.jsontest:ci)仍显式写出 vitest --run --coverage,双保险确保流水线行为确定;
  2. --run 对 pre-commit 工具至关重要——保证 lint-staged 等钩子单次运行后能退出;
  3. 驼峰与 kebab-case 参数等价--testTimeout--test-timeout)——仓库脚本两种风格混用而互不影响;
  4. 布尔选项支持 --no- 取反——如 --no-watch--no-color,可临时压住配置或默认行为。

7. 在 Supabase 仓库中上手 Vitest CLI 的操作路径

结合仓库结构,推荐的实操路径如下(均为只读/运行类操作,环境前提:Node >=22.13、pnpm 11.13,依赖用 pnpm install 安装):

  1. 单包本地调试:进入目标包(如 apps/studio)后 pnpm test:watch,用 f/p/t 快捷键收敛到失败用例;
  2. 单包提交前验证pnpm test(Studio 包即 vitest --run --coverage),失败快照用 pnpm test:updatevitest --run --update)批量更新后人工复核;
  3. 按名/按文件过滤vitest -t "prod smoke test" 复刻 apps/docs 的 smoke 用法;vitest 关键字 做路径模糊匹配;
  4. 清点与工具化vitest list --filesOnlyvitest list --json 生成测试清单供脚本消费;
  5. 从仓库根聚合运行pnpm test:studio / pnpm test:ui 走 Turborepo 过滤链路,适合改动跨包依赖(如 packages/ui)后的回归验证;
  6. 深入配置:CLI 选项之外,各包的 vitest.config.ts(如 apps/studio/vitest.config.tspackages/ui/vitest.config.ts)定义了 setupFilesenvironmentcoverage.include 等基线,CLI 标志在其上做临时覆盖。

需要说明的适用边界:本文的 CLI 参考基于 Vitest 3.x(技能包于 2026-01-28 生成),标志语义以该版本为准;仓库内部分 test 脚本(如 apps/docs)会先拉起本地 Supabase 环境(pnpm supabase start)再执行 vitest,此类组合脚本依赖仓库根 package.json 中的 setup:cli 类基础设施,脱离仓库环境时不能直接照搬。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
588
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
906
1.83 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
891
5.79 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.53 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.34 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
988
506
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384