菜单

测试框架

相关源文件

测试框架提供了 Deno 内置的测试运行器功能,包括测试发现、执行、过滤和报告。该系统使开发者能够使用 Deno.test() API 调用编写和运行测试,并通过 deno test 命令或 IDE 集成执行它们。

有关基准测试的信息,请参阅 基准测试。有关 CLI 命令处理的信息,请参阅 命令处理

系统架构

测试框架由几个相互连接的组件组成,它们在 CLI 和语言服务器协议 (LSP) 环境中处理测试发现、执行和报告。

测试框架核心架构

来源:cli/tools/test/mod.rs1-100 cli/ops/testing.rs24-43 cli/lsp/testing/server.rs47-61

测试发现与注册

测试发现通过两种主要机制进行:用于 LSP 集成的静态 AST 分析和 JavaScript 执行期间的动态注册。

静态发现(LSP)

LSP 系统使用 AST 解析来发现测试而无需执行代码,从而实现 IDE 功能,如测试探索和调试。

静态测试发现流程

TestCollector 实现 Visit trait 以遍历 AST 节点并识别测试模式

  • 直接调用Deno.test("name", fn)
  • 对象语法Deno.test({ name: "test", fn: () => {} })
  • 解构导入const { test } = Deno; test("name", fn)
  • 测试步骤:测试函数内的 t.step("step name", fn)

来源:cli/lsp/testing/collectors.rs445-467 cli/lsp/testing/collectors.rs470-553

动态注册(运行时)

在测试执行期间,JavaScript Deno.test() 调用通过 Rust ops 进行注册,创建包含测试元数据的 TestDescription 对象。

动态测试注册

来源:cli/ops/testing.rs92-131 cli/tools/test/mod.rs280-291

测试执行管道

测试执行遵循多阶段管道,处理测试发现、过滤、工作区创建和结果收集。

执行流程

测试执行管道

来源:cli/tools/test/mod.rs855-880 cli/tools/test/mod.rs650-701

测试事件系统

该框架使用事件驱动的架构来在工作区和主线程之间通信测试进度和结果。

事件类型目的数据
TestEvent::Register测试发现TestDescriptions
TestEvent::Plan执行计划带有总数的 TestPlan
TestEvent::Wait测试开始test_id
TestEvent::Result测试完成带有时间的 TestResult
TestEvent::StepRegister测试步骤发现TestStepDescription
TestEvent::StepResult步骤完成TestStepResult
TestEvent::UncaughtError运行时错误JsError 详情

来源:cli/tools/test/mod.rs510-530 cli/tools/test/channel.rs1-50

权限管理

测试框架实现了复杂的权限管理,允许测试在保持安全隔离的同时以提升或受限的权限运行。

权限操作

权限声明/恢复周期

权限系统使用基于令牌的方法,其中 op_pledge_test_permissions 返回一个 UUID 令牌,该令牌必须提供给 op_restore_test_permissions 以防止权限升级攻击。

来源:cli/ops/testing.rs48-86 deno_runtime/permissions.rs

资源和 Op 清理

Deno 的测试框架包含内置的清理程序,可检测资源泄漏和挂起的异步操作,以确保测试隔离并防止测试不稳定。

清理程序架构

清理程序检测流程

清理程序通过以下方式工作:

  1. 捕获测试执行前的运行时活动
  2. 运行测试函数
  3. 等待异步操作稳定(最多 MAX_SANITIZER_LOOP_SPINS
  4. 计算运行时状态的差异
  5. 过滤掉可接受的顶级操作
  6. 将任何剩余的泄漏报告为测试失败

来源:cli/tools/test/mod.rs1176-1233 cli/tools/test/mod.rs118-173

测试过滤和选择

该框架提供多种过滤运行哪些测试的机制,支持 CLI 参数和编程选择。

筛选类型

测试过滤机制

TestFilter::includes() 方法按顺序应用过滤器

  1. 子字符串匹配(如果指定)
  2. 正则表达式匹配(如果指定)
  3. 包含列表验证(如果指定)
  4. 排除列表验证
  5. “仅”测试优先级

来源:cli/tools/test/mod.rs176-225 cli/lsp/testing/execution.rs134-157

LSP 集成

语言服务器协议集成使得 IDE 可以进行测试发现、执行和调试,而无需完全调用 CLI。

LSP 测试服务器

LSP 测试集成架构

TestServer 维护两个后台线程:

  • 更新线程:监控文档更改并执行静态测试发现
  • 运行线程:执行测试运行并报告进度

来源:cli/lsp/testing/server.rs62-208 cli/lsp/testing/execution.rs159-190

测试步骤框架

测试步骤提供分层测试组织,允许测试包含具有独立通过/失败状态和计时信息的子测试。

步骤注册和执行

测试步骤层级

测试步骤维护与其父测试和根测试的引用,从而实现正确的嵌套和结果聚合。失败的步骤会导致其父测试失败,但步骤失败与测试失败是分开报告的。

来源:cli/ops/testing.rs142-172 cli/tools/test/mod.rs475-493

报告和输出

测试框架支持多种输出格式和报告机制,以满足不同的用例。

报告器类型

报告器目的输出格式
PrettyTestReporter人类可读的 CLI 输出彩色终端文本
DotTestReporter最小化的进度指示每个测试一个字符
JunitTestReporterCI/CD 集成JUnit XML 格式
TapTestReporterTAP 协议兼容TAP 格式输出
CompoundTestReporter多输出组合多个报告器

报告器系统使用 TestReporter trait 来标准化不同输出类型的格式。报告器接收 TestEvent 消息,并根据其特定要求进行格式化。

来源:cli/tools/test/reporters/mod.rs1-50 cli/tools/test/mod.rs606-648