mcpField
S
smoke-tests

smoke-tests

github.com/microsoft测试与质量194.4k72 次安装今天更新
代码仓库

关于 smoke-tests

smoke-tests 说明如何在 Electron、Web 和远程运行模式下执行及调试 VS Code 端到端冒烟测试,面向贡献者和 CI 维护者,涵盖筛选、追踪与分片。

主要功能

  1. 01编译后或直接运行冒烟测试
  2. 02选择 Electron、Web 或远程模式
  3. 03筛选套件并启用 Playwright 追踪
  4. 04按预计耗时拆分测试套件
  5. 05利用 CI 日志和截图排查失败

适用场景

  1. 01运行指定的端到端测试套件
  2. 02调查间歇性 CI 故障
  3. 03查看失败运行的追踪记录和日志

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/microsoft/vscode --skill smoke-tests

安装后在 Claude Code 中输入/smoke-tests确认已加载。

详细介绍

运行冒烟测试

冒烟测试位于 test/smoke/,用于通过端到端用户流程驱动完整的 VS Code 实例(Electron、Web 或远程)。

脚本

  • npm run smoketest — 先编译冒烟测试(test/smoke),然后运行。
  • npm run smoketest-no-compile — 运行已编译的冒烟测试。CI 会在显式编译步骤之后使用此命令。

这两个脚本都会将 -- 后的额外参数传递给运行器(test/smoke/test/index.js)。

常用选项

选项说明
-g <pattern>(别名为 -f)按测试/套件标题筛选(mocha grep)。
--build <path>使用打包后的构建版本,而不是从源码编译的开发构建版本。
--tracing捕获 Playwright 跟踪记录(并在失败时截取屏幕截图)。
--web运行浏览器冒烟测试,而不是 Electron 冒烟测试。
--headless使用无头浏览器(与 --web 搭配使用)。
--remote运行远程冒烟测试。
--shard <index>/<total>仅运行顶层套件中的一部分,例如 --shard 1/2。套件会根据预估时长均衡分配到各分片(参见 test/smoke/src/shard.ts);每个套件只会在一个分片中运行。
# Run everything (Electron, from source)
npm run smoketest

# Run only a subset of suites by name, with tracing (replace <suite name> with your suite, e.g. "Agents Window")
npm run smoketest -- -g "<suite name>" --tracing

# Run against a packaged build (CI style)
npm run smoketest-no-compile -- --tracing --build "/path/to/VSCode-darwin-arm64/Code - OSS.app"

-g 模式会匹配测试/套件标题。例如,-g "Agents Window" 会匹配全部三个 Agents Window 套件(Agents Window、Agents Window (local AgentHost) 和 Agents Window (local AgentHost, SDK sandbox));可使用能标识目标套件的任意子字符串。

只要有任何测试失败,运行器就会以非零代码退出,因此退出代码为 0 表示所有选定的测试均已通过。

PR CI 中的分片

GitHub PR 工作流会将 Electron 烟雾测试拆分为多个分片:.github/workflows/pr-linux-test.yml 和 pr-darwin-test.yml 中的 electron-smoke-1 和 electron-smoke-2 作业,以及 pr-win32-test.yml 中的 electron-smoke-1 到 electron-smoke-3 作业(其中第一个分片还会设置 WSL),会将 SMOKE_SHARD_INDEX/SMOKE_SHARD_TOTAL 环境变量作为 --shard 传给运行器。它们的报告名称为 <OS> / Electron-Smoke (shard 1/2) 和 <OS> / Electron-Smoke (shard 2/2),或者 Windows / Electron-Smoke (shard 1/3) 到 Windows / Electron-Smoke (shard 3/3)。在 Windows 上,远程烟雾测试也会在独立的 Windows / Remote (smoke) 作业中运行,与 Windows / Remote (integration) 并列。PR Gate 作业(pr-gate)会为工作流中的每个作业报告一个检查项,并在任何分片未成功时失败。如果 PR 仅修改烟雾测试无法读取的路径(参见 .github/actions/detect-changes/detect.ts),则会跳过这些分片,并且门禁检查会通过。要更改某个平台的分片数量,请在其工作流中添加或删除 electron-smoke-<index> 作业,并更新所有这些作业名称和环境变量中的分片编号。在每个分片的 smoke-test-runner.log 顶部附近,Running smoke test shard <index>/<total> 这一行会列出该分片运行的测试套件。

部分分片安排与工作流相互关联,test/smoke/src/shard.ts 中对此进行了编码:

  • WSL: WSL Dev Container 测试套件固定在分片 1 中,且 pr-win32-test.yml 仅在分片 1 中配置 WSL。请确保在每个分片中都设置 VSCODE_SMOKE_TEST_WSL_REQUIRED,这样所有分片注册的测试套件相同,计算出的拆分也相同。在 Windows 上,分片 1 使用 1ES 池,而不是较大型的 vscode-large-runners-windows-8-core 运行器:在 WSL2 配置发行版时,GitHub 托管的 Windows 运行器偶尔会冻结(actions/runner-images#14938),导致检查项待处理约 45 分钟,直到 GitHub 报告与运行器失去通信。
  • WSL 版本: Agent 使用的 Windows Server 2022 映像仅包含内置 WSL,因此配置时会安装固定在 build/checksums/wsl.txt 中的 WSL 版本(参见 build/azure-pipelines/common/wsl.psm1)。要更新版本,请将较新版 wsl.<version>.x64.msi 的 SHA256 和文件名填入此处;较新版本可从 microsoft/WSL releases 获取。安装程序会按该文件缓存;pr-node-modules.yml 会在 main 上填充 GitHub 缓存。
  • macOS 代理运行: 在 macOS 上,PAC 代理的 Agents Window 测试仅在最后一个分片中运行,因此负载均衡器会在该分片中为其预留时间。

每个分片都必须注册相同的测试套件,否则某些套件可能被跳过或运行两次。不要让测试套件的注册依赖于各分片之间不同的任何因素。

运行结束时,运行器会按耗时从长到短打印每个顶层测试套件的耗时。添加的烟雾测试套件如果比启动应用的时间(约 20 秒)长得多,或者打印的耗时与 test/smoke/src/shard.ts 中的 suiteDurations 不符,请更新该表,以保持各分片负载均衡。

暂时循环运行测试套件,以排查 CI 中的不稳定测试

当烟雾测试仅在 CI 中间歇性失败时,一种实用方法是暂时连续多次运行可疑的测试套件,并在首次失败时停止。这样可以在真实 CI 环境中复现不稳定问题并捕获跟踪记录和屏幕截图,而不必等待它在无关 PR 中自然再次出现。

这是一种调试辅助方法,不是永久性的 CI 测试配置:

  • 在临时分支上添加循环,推送并让 CI 运行。反复尝试,直到复现问题(然后修复不稳定问题)。
  • 合并前移除循环——如果保留,每个平台的每次运行都会多花约 1 小时。
  • 这并不局限于某个特定测试套件。将 -g 筛选器指向你正在调查的测试套件(以下示例使用 "Agents Window",请替换为你自己的测试套件)。
添加位置

将循环放在现有的 Electron 烟雾测试步骤旁边,并使用相同的条件进行门控;在出现此间歇性故障的平台对应的测试步骤中添加。在分片运行的 GitHub PR 工作流中,还要像下面的示例一样,将其限制为单个分片,以免每个分片都运行:

GitHub PR 工作流(从源代码运行,不带 --build):

  • .github/workflows/pr-linux-test.yml(bash;设置 DISPLAY: ":10")
  • .github/workflows/pr-darwin-test.yml(bash;不设置 DISPLAY)
  • .github/workflows/pr-win32-test.yml(PowerShell)

Azure DevOps 测试步骤(通过 --build 对打包后的构建运行):

  • build/azure-pipelines/linux/steps/product-build-linux-test.yml
  • build/azure-pipelines/darwin/steps/product-build-darwin-test.yml
  • build/azure-pipelines/win32/steps/product-build-win32-test.yml
形式

循环运行 N 次(例如 20 次),首次运行失败时立即中止。设置充足的超时时间——连续运行 N 次每次约 3 分钟的测试套件,大约需要一小时。

Bash(Linux/macOS):

# TEMPORARY: loop the suite to reproduce a flaky failure. Remove before merge.
# Replace <suite name> with the suite you're investigating (e.g. "Agents Window").
- name: 🧪 Smoke test flakiness probe (TEMPORARY)
  if: ${{ env.ELECTRON_TESTS == 'true' && env.SMOKE_TESTS == 'true' && env.SMOKE_SHARD_INDEX == '1' }}
  timeout-minutes: 60
  run: |
    for i in $(seq 1 20); do
      echo "::group::Smoke probe run $i/20"
      npm run smoketest-no-compile -- --tracing -g "<suite name>" || { echo "::error::Smoke test failed on run $i/20"; exit 1; }
      echo "::endgroup::"
    done

PowerShell(Windows)会在每次运行后检查 $LASTEXITCODE,失败时执行 exit 1。AzDO 变体使用 set -e(bash)/$LASTEXITCODE(pwsh)来快速失败,并追加 --build "<packaged app path>"。

为何快速失败

该循环用于探测:首次失败就是信号。立即停止可以保留失败运行的跟踪记录/屏幕截图(位于 logs 构建产物中),并避免浪费约一小时的 Agent 时间,去完成一个已经证实存在间歇性故障的运行。

调试 CI 烟雾测试失败

两个 CI 系统都会将烟雾测试运行器按平台生成的日志(.build/logs 目录)发布为可下载的构建产物。两个系统中的构建产物内部布局相同,只有构建产物名称和下载工具不同。

下载日志构建产物
GitHub Actions

GitHub PR 工作流会将构建产物上传为 logs-<os>-<arch>-<suite>-<attempt>,其中 <os> 为 linux / macos / windows,<suite> 用于标识作业(例如 electron、browser、remote,或第一个 Electron 烟雾测试分片的 electron-smoke-shard1),<attempt> 是运行尝试次数(例如 logs-macos-arm64-electron-smoke-shard1-1)。

运行 ID 是运行/作业 URL 中的数字——对于 …/actions/runs/<run-id>/job/<job-id>,使用 <run-id>。使用 gh CLI 下载:

# A specific artifact into ./logs
gh run download <run-id> -n logs-<os>-<arch>-<suite>-<attempt> -D ./logs

# Or every artifact from the run
gh run download <run-id>

gh run view <run-id> 会列出该运行的作业/构建产物;浏览器中的运行摘要页面底部也有 Artifacts 部分。

Azure DevOps

构建产物名称取决于生成它的管道:

  • 产品构建(product-build-<os>.yml):logs-<os>-<arch>-<attempt>——不包含套件字段,例如 logs-macos-arm64-1。
  • 拆分套件的 CI 构建(product-build-<os>-ci.yml):logs-<os>-<arch>-<suite>-<attempt>——<suite> 字段是 lower(VSCODE_TEST_SUITE)(例如 electron),因此名称为 logs-macos-arm64-electron-1(与 GitHub 的格式相同)。

<os> 为 linux / macos / windows,<arch> 为 x64 / arm64,<attempt> 为 $(System.JobAttempt)。使用 Azure CLI 下载:

az pipelines runs artifact download \
  --org <ORG_URL> --project <PROJECT_NAME> \
  --run-id <BUILD_ID> --artifact-name <artifact-name> \
  --path ./logs

对于 VS Code 构建,使用 --org https://dev.azure.com/monacotools --project Monaco;查阅 azure-pipelines 技能以了解如何查找 <BUILD_ID>。

产物内容

在 smoke-tests-<suite>/ 下(smoke-tests-electron/、smoke-tests-browser/ 或 smoke-tests-remote/,与运行的套件对应):

  • smoke-test-runner.log — mocha 驱动程序输出;对于使用模拟 LLM 服务的套件,还包含详细的请求/响应正文(查找 request body:)。Copilot CLI / Copilot 会话失败时,该文件还会附带截取的 Copilot 运行时日志末尾部分(见下文)。
  • <N>_suite_<Suite_Name>/copilot-runtime-logs/process-*.log — Copilot 运行时(@github/copilot CLI)进程日志,在 Copilot 运行时会话失败时由 dumpFailureDiagnostics 捕获。发生挂起或出现 “Timed out waiting for response” 时,请先检查这些日志:它们记录了 SDK/CLI 自身的操作情况(启动、身份验证、模型请求、轮次生命周期,以及任何 panic / 乱序事件 / 协议错误),能解释仅凭测试错误无法说明的超时情况。Agent Host 会话(Agents Window / 本地 AgentHost)会以 trace 级别记录完整的日志运行内容(chat.agentHost.copilotSdk.logLevel)。Chat Sessions 编辑器(Copilot CLI / Claude)和 Local 会话会在进程内运行 SDK,此处仅记录最精简的启动日志(Server started, waiting for requests)——足以判断运行时是否已启动;其详细的模型/轮次诊断信息请查看下文的 GitHub Copilot Chat.log。(Claude / Codex 会话使用不同的运行时,因此不会记录在此处。)
  • <N>_suite_<Suite_Name>/window2/exthost/<extension>/…log — 每个套件对应的扩展宿主日志(例如 GitHub.copilot-chat/GitHub Copilot Chat.log)。许多诊断信息受某项设置控制,该设置由套件在 before 钩子中启用;如果缺少预期的日志行,请检查套件的设置。
  • <N>_suite_<Suite_Name>/playwright-screenshot-*.png — 测试失败时捕获的最后一帧截图(仅当套件使用 --tracing 运行时才会生成)。

<Suite_Name> 是 mocha 套件标题,其中的非单词字符已替换为 _。另请参阅 code-oss-logs 技能。

与其他测试类型的区别

  • 单元测试(.test.ts)→ scripts/test.sh / runTests 工具(参见 unit-tests 技能)。
  • 集成测试(.integrationTest.ts + 扩展测试)→ scripts/test-integration.sh(参见 integration-tests 技能)。
  • 冒烟测试(test/smoke/)→ npm run smoketest — 完整的端到端 UI 流程。

评论

支持 Markdown