Angular 单元测试调试指南:用 ng test --debug 在 Node.js 与真实浏览器中定位问题测试
测试行为与预期不符时,调试的第一步往往是选择正确的运行环境:与浏览器渲染、浏览器专属 API 无关的问题,用 Node.js 环境调试通常最快;涉及真实渲染或浏览器 API 的行为,则应切换到真实浏览器调试。本文围绕 Angular 官方测试调试文档(adev/src/content/guide/testing/debugging.md)讲解 ng test --debug 标志在这两种场景下的完整用法,读完你可以在默认的 Node.js(Vitest)环境与真实浏览器模式下逐步执行并断点调试失败的 Angular 测试用例。
调试前:确认你的测试运行环境
新创建的 Angular CLI 项目默认以 Vitest 作为单元测试运行器,ng test 命令会先以 watch 模式构建应用,再启动 Vitest 运行器,并在你修改并保存文件后自动重新执行测试(详见 测试总览)。本文的调试文档主要面向这套 Vitest 默认环境;如果你的项目仍在使用 Karma 运行器,调试流程略有不同,详见下文「使用 Karma 时的浏览器调试」。
需要特别留意的环境差异:
- Node.js 环境(默认):Vitest 在 Node.js 中运行测试,并用
jsdom或happy-dom模拟浏览器 DOM,执行速度快,但并非真正的浏览器渲染。 - 真实浏览器环境(browser mode):需要额外安装浏览器提供者并在
angular.json中配置browsers选项,适用于依赖浏览器专属 API(如真实渲染)的用例,也用于调试。相关迁移与配置细节见 从 Karma 迁移到 Vitest 指南。
调试前建议先想清楚:问题是否由浏览器渲染或浏览器专属 API 引起?如果不是,优先选择 Node.js 环境调试,迭代成本最低。
在 Node.js 环境中调试
Node.js 环境调试是诊断与浏览器 API 或渲染无关问题的最快路径,例如断言逻辑错误、依赖注入失败、服务方法返回值不符合预期等。
步骤一:以调试模式启动测试
使用 ng test 命令的 --debug 标志启动:
ng test --debug
步骤二:理解调试模式的启动行为
加上 --debug 后,测试运行器会以调试模式启动,并在执行测试前等待一个调试器附加(attach)。这意味着终端不会立刻输出完整的测试结果,而是停在「等待调试器」的状态,直到你从外部接入调试器后,用例才会在受控的逐步执行中运行。
注意:
--debug与默认的 watch 行为、CI 环境下的单次运行模式配合使用时表现可能不同。若在 CI 上强制单次运行,通常会配合--no-watch与--no-progress(见 测试总览 的 CI 章节);而在本地调试时请保留交互式终端,以便观察运行器输出。
步骤三:附加你偏好的调试器
运行器就绪后会等待调试器接入,此时可以任选一种工具:
- VS Code 内置 Node.js 调试器:创建或使用已有的调试配置将调试器附加到测试进程,即可在测试文件中设置断点、查看调用栈与变量。
- Chrome DevTools for Node:通过 Node.js 的 inspector 机制连接调试端口,在浏览器式 DevTools 界面中单步调试。
接入成功后,配合你在 .spec.ts 测试文件或被测实现代码中设置的断点,逐步执行即可观察失败原因。测试运行器会继续以常规方式驱动用例执行,断点命中时进程会暂停供你检查。
适合在 Node.js 环境排查的典型问题
从源码结构可以推断,Node.js 环境适合排查纯逻辑类问题,包括但不限于:
TestBed装配错误、providers 缺失导致的注入失败;- 组件/指令/管道的纯逻辑断言不通过;
- 服务方法、HTTP 拦截行为等不依赖真实渲染的用例;
- 涉及异步时序(如
fakeAsync、tick、flushMicrotasks)的行为,可参考 Zone.js 测试工具 中对这些时钟工具语义的说明。
如需基于 DOM 结构编写调试用的查询与断言,可借助 TestBed 与 ComponentFixture 返回的 debugElement——它是测试与调试阶段窥探组件及其 DOM 的关键入口,相关用法见 测试工具 API 指南 的 DebugElement 小节。
在真实浏览器环境中调试
当问题与真实渲染、布局或浏览器专属 API 相关时,就需要在浏览器中调试。与 Node.js 环境相同,仍使用 ng test 加 --debug 标志,配合 Vitest 的 browser mode(浏览器模式)启动。
前提:为项目启用浏览器模式
在运行 ng test --debug 之前,项目必须已配置好浏览器模式,否则无法进入真实浏览器执行。依据 从 Karma 迁移到 Vitest 指南 的第 5 步,你需要:
-
安装一个浏览器提供者,可按下表选择:
提供者 覆盖浏览器 适用场景 @vitest/browser-playwrightChromium、Firefox、WebKit 常规真实浏览器测试与调试 @vitest/browser-webdriverioChrome、Firefox、Safari、Edge 需要 WebDriver 体系能力时 @vitest/browser-preview— WebContainer 类环境(如 StackBlitz),不适合 CI/CD 以 Playwright 为例:
npm install --save-dev @vitest/browser-playwright playwright -
在
angular.json的testtarget 中配置browsers选项:{ "projects": { "your-project-name": { "architect": { "test": { "builder": "@angular/build:unit-test", "options": { "browsers": ["chromium"] } } } } } }浏览器名称与所装提供者对应(如 Playwright 用
chromium,WebdriverIO 用chrome)。Headless(无头)模式会在CI环境变量被设置,或浏览器名称包含 "Headless"(如ChromeHeadless)时自动启用;否则测试以有头(headed)浏览器运行。调试时通常需要「有头」模式来观察浏览器窗口与 DevTools,因此请确保本地未设置CI,或显式使用不带Headless后缀的浏览器名。
调试会话流程
-
在配置好浏览器模式的项目中运行:
ng test --debug -
测试运行器以调试模式启动,并等待你打开浏览器的开发者工具(DevTools)。
-
在 DevTools 的 Sources 面板中找到对应的测试文件(可通过文件查找快捷键输入测试文件名定位),设置断点。
-
触发或重新运行测试,观察断点命中情况,逐步检查 DOM、样式与运行时状态。
该流程与 Node.js 调试的关键差异在于:断点所在的执行上下文是真实浏览器渲染管线,可以直观检查元素、样式计算与浏览器 API 的调用结果,更适合排查渲染类缺陷。
使用 Karma 时的浏览器调试
如果项目尚未迁移到 Vitest,仍在 Karma 指南 描述的 Karma + Jasmine 配置下,调试入口与 Vitest 不同,无需 --debug 标志,流程如下:
- 显示 Karma 浏览器窗口。
- 点击 DEBUG 按钮,在新标签页中重新运行测试。
- 打开浏览器开发者工具(Windows 下
Ctrl-Shift-I,macOS 下Command-Option-I)。 - 进入 Sources 面板,按
Control/Command-P后输入测试文件名以打开测试源码。 - 在测试中设置断点。
- 刷新浏览器,观察断点是否命中。
注意该文档中引用的截图资源(assets/images/guide/testing/ 目录)在当前仓库中未随文档一并提供,实际画面请以你的本地运行结果为准。
调试时的常见配置与注意事项
- 自定义测试文件范围:调试某类用例前,可通过
testtarget 的include/exclude选项收紧文件范围(默认include为['**/*.spec.ts', '**/*.test.ts']),减少无关用例的干扰,加速断点命中。 - 覆盖率与调试互斥:
coverage选项默认关闭;若曾开启覆盖率报告,可在调试时关闭以获得更快的启动速度。 - 自定义 Vitest 配置:需要更细粒度调试设置(如
test.environmentOptions、超时等)时,可通过runnerConfig指向自定义 Vitest 配置文件(详见 从 Karma 迁移到 Vitest 指南 的 Configuration 章节)。CLI 会覆盖其中的test.projects与test.include,以保证正常运行。 - 异步测试的断点策略:在断点处检查异步状态前,先弄清当前用例的异步模型。若是 Zone.js 风格(
fakeAsync/tick),虚拟时钟与真实时间的差异可能导致断点命中的时序与直觉不符,参见 Zone.js 测试工具;若已迁移到原生async与 Vitest fake timers,则按原生异步逻辑调试即可。
小结
调试 Angular 测试的核心决策是「选对执行环境」:
| 场景 | 推荐环境 | 启动方式 |
|---|---|---|
| 与浏览器无关的逻辑、断言、注入问题 | Node.js(Vitest 默认) | ng test --debug,附加 VS Code Node 调试器或 Chrome DevTools for Node |
| 涉及真实渲染或浏览器专属 API | 真实浏览器(Vitest browser mode) | 先配置 browsers,再 ng test --debug,在 DevTools 中断点 |
| 仍在用 Karma 的项目 | 真实浏览器 | 点击 Karma 窗口的 DEBUG 按钮后使用 DevTools |
ng test --debug 的本质是让运行器在启动后暂停,等待你主动附加调试器——掌握这一心智模型后,无论默认 Node.js 环境还是真实浏览器模式,你都能用熟悉的调试工具逐步定位失败用例。更多测试相关主题可继续阅读 测试总览 及其引出的组件、服务、指令、管道与覆盖率等专项指南。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00