本文档介绍了 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
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 测试运行器包含一些特殊功能,可增强测试能力。
测试运行器通过测试上下文中的 mock 属性提供内置模拟功能。
来源: doc/api/test.md572-722 doc/api/test.md723-886
测试运行器支持快照测试,允许您将当前的测试输出与存储的参考值进行比较。
可以通过名称模式或使用 only 选项来过滤测试。
来源: doc/api/test.md216-272 doc/api/test.md285-320
测试运行器可以使用内置的报告器以不同的格式输出测试结果。
| 报告器 | 描述 | 输出格式 |
|---|---|---|
spec | 人类可读的分层格式(默认) | 带测试层级结构的文本 |
tap | 测试任何协议格式 | 符合 TAP 标准的文本 |
dot | 最小格式,用点表示通过的测试 | 带点的紧凑文本 |
junit | JUnit 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 进行持续集成,在不同的平台和配置上运行测试。
| 工作流 | 目的 | 平台 |
|---|---|---|
test-linux.yml | 在 Linux 上测试 | Ubuntu (x64, ARM64) |
test-macos.yml | 在 macOS 上测试 | macOS |
coverage-linux.yml | 在 Linux 上生成覆盖率 | Ubuntu |
coverage-windows.yml | 在 Windows 上生成覆盖率 | Windows |
linters.yml | 运行代码 linter | Ubuntu |
daily-wpt-fyi.yml | Web Platform Tests | Ubuntu |
来源: .github/workflows/test-linux.yml1-69 .github/workflows/test-macos.yml1-101 .github/workflows/coverage-linux.yml1-85 .github/workflows/coverage-windows.yml1-77
来源: .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 编写测试时,有几项最佳实践需要遵循:
before、after、beforeEach 和 afterEach 钩子来正确设置和清理资源。默认情况下,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}Node.js 拥有一个全面的测试和质量保证系统,其中包括一个强大的测试运行器、各种测试类别、对模拟和快照测试的支持以及健壮的持续集成基础设施。该系统有助于在多个平台和配置上维护 Node.js 代码库的高质量和稳定性。