菜单

测试与质量保证

相关源文件

本文档介绍了 Node.js 代码库中的测试和质量保证基础设施。它涵盖了测试运行器架构、测试方法以及确保 Node.js 质量和稳定性的持续集成系统。

有关 Node.js 应用程序内置测试运行器 API 的信息,请参阅测试运行器

测试运行器架构

Node.js 拥有一个强大的测试架构,它由多个组件协同工作,提供全面的测试覆盖。该架构包括测试工具、测试文件、测试报告器以及用于执行和报告测试结果的各种实用程序。

测试执行流程

来源:lib/internal/test_runner/runner.js1-980 lib/internal/test_runner/test.js1-250 lib/internal/test_runner/tests_stream.js1-100 lib/internal/main/test_runner.js1-25 lib/internal/test_runner/reporter/spec.js1-50 lib/internal/test_runner/reporter/tap.js1-30

测试类和组件

来源:lib/internal/test_runner/test.js261-500 lib/internal/test_runner/test.js501-750 lib/internal/test_runner/test.js751-1000 lib/internal/test_runner/runner.js175-250

测试类型和组织

Node.js 的测试根据其执行要求和资源使用情况分为不同的类别。

测试类别

类别描述执行模式位置
并行可并发运行的测试并发test/parallel/
顺序必须顺序运行的测试顺序test/sequential/
Pummel可能占用大量资源的压力测试顺序test/pummel/
互联网需要互联网连接的测试顺序test/internet/
Fixtures(夹具)测试的支撑文件和配置不适用test/fixtures/

来源:test/parallel/parallel.status1-130 test/sequential/sequential.status1-50 test/pummel/pummel.status1-25

测试状态文件

状态文件定义了测试在不同平台上的预期行为,标记测试为不稳定、已跳过或需要特殊处理。

状态文件示例条目

# https://github.com/nodejs/node/issues/52273
test-shadow-realm-gc: SKIP

# https://github.com/nodejs/node/issues/51862
test-fs-read-stream-concurrent-reads: PASS, FLAKY

来源:test/parallel/parallel.status1-50 test/sequential/sequential.status1-20 test/pummel/pummel.status1-20

测试运行器 API

Node.js 通过 node:test 模块提供内置测试运行器,支持使用各种样式和不同功能编写测试。

核心测试函数

功能描述
test(name, [options], fn)定义一个测试
describe(name, [options], fn)对相关测试进行分组(suite() 的别名)
it(name, [options], fn)定义一个测试(test() 的别名)
before(fn, [options])在当前上下文中所有测试之前运行
after(fn, [options])在当前上下文中所有测试之后运行
beforeEach(fn, [options])在当前上下文中每个测试之前运行
afterEach(fn, [options])在当前上下文中每个测试之后运行

来源:doc/api/test.md1-100 doc/api/test.md180-204 lib/internal/test_runner/harness.js360-380

测试生命周期和执行

来源:lib/internal/test_runner/test.js980-1100 doc/api/test.md30-92

特殊测试功能

Node.js 测试运行器包含一些特殊功能,可增强测试能力。

模拟(Mocking)

测试运行器通过测试上下文中的 mock 属性提供内置模拟功能。

来源: doc/api/test.md572-722 doc/api/test.md723-886

快照测试

测试运行器支持快照测试,允许您将当前的测试输出与存储的参考值进行比较。

来源: doc/api/test.md979-1037

过滤测试

可以通过名称模式或使用 only 选项来过滤测试。

来源: doc/api/test.md216-272 doc/api/test.md285-320

测试报告

测试运行器可以使用内置的报告器以不同的格式输出测试结果。

内置报告器

报告器描述输出格式
spec人类可读的分层格式(默认)带测试层级结构的文本
tap测试任何协议格式符合 TAP 标准的文本
dot最小格式,用点表示通过的测试带点的紧凑文本
junitJUnit XML 格式用于 CI 系统的 XML
lcov代码覆盖率报告格式用于代码覆盖率工具的 LCOV

来源: doc/api/test.md1040-1080 lib/internal/test_runner/utils.js124-152

报告器架构

来源: lib/internal/test_runner/reporter/spec.js1-50 lib/internal/test_runner/reporter/tap.js1-30 doc/api/test.md1092-1102

代码覆盖率

Node.js 支持代码覆盖率测量,以识别未经测试的代码路径。

可以使用 --experimental-test-coverage 标志收集覆盖率,并可以使用其他选项进行配置

  • --test-coverage-exclude:要排除文件的 Glob 模式
  • --test-coverage-include:要包含文件的 Glob 模式
  • --test-coverage-lines:必需的行覆盖率百分比
  • --test-coverage-functions:必需的函数覆盖率百分比
  • --test-coverage-branches:必需的分支覆盖率百分比

来源: doc/api/test.md515-557 lib/internal/test_runner/utils.js293-308

持续集成

Node.js 使用 GitHub Actions 进行持续集成,在不同的平台和配置上运行测试。

CI 工作流

工作流目的平台
test-linux.yml在 Linux 上测试Ubuntu (x64, ARM64)
test-macos.yml在 macOS 上测试macOS
coverage-linux.yml在 Linux 上生成覆盖率Ubuntu
coverage-windows.yml在 Windows 上生成覆盖率Windows
linters.yml运行代码 linterUbuntu
daily-wpt-fyi.ymlWeb Platform TestsUbuntu

来源: .github/workflows/test-linux.yml1-69 .github/workflows/test-macos.yml1-101 .github/workflows/coverage-linux.yml1-85 .github/workflows/coverage-windows.yml1-77

CI 流程

来源: .github/workflows/test-linux.yml1-20 .github/workflows/test-macos.yml1-20 .github/workflows/coverage-linux.yml1-20 .github/workflows/build-tarball.yml1-30

编写有效的测试

在为 Node.js 编写测试时,有几项最佳实践需要遵循:

  1. 使用适当的测试类别:根据测试的资源使用情况和需求,将其放置在正确的目录中。
  2. 在需要时将测试标记为 flaky:使用状态文件标记可能由于时序或其他非确定性因素而偶尔失败的测试。
  3. 明智地使用测试钩子:使用 beforeafterbeforeEachafterEach 钩子来正确设置和清理资源。
  4. 测试成功和失败的场景:确保测试涵盖正常操作和错误条件。
  5. 使用模拟对象:利用模拟工具将测试与外部依赖项隔离。

测试文件名约定

默认情况下,Node.js 将运行匹配以下模式的所有文件

  • **/*.test.{cjs,mjs,js}
  • **/*-test.{cjs,mjs,js}
  • **/*_test.{cjs,mjs,js}
  • **/test-*.{cjs,mjs,js}
  • **/test.{cjs,mjs,js}
  • **/test/**/*.{cjs,mjs,js}

TypeScript 文件也可以包含在测试中

  • **/test/**/*-test.{cts,mts,ts}
  • **/test/**/*.test.{cts,mts,ts}
  • **/test/**/*_test.{cts,mts,ts}

来源: doc/api/test.md463-477

结论

Node.js 拥有一个全面的测试和质量保证系统,其中包括一个强大的测试运行器、各种测试类别、对模拟和快照测试的支持以及健壮的持续集成基础设施。该系统有助于在多个平台和配置上维护 Node.js 代码库的高质量和稳定性。