Skip to main content
On this page

测试清理器

deno test 运行器提供了多个清理器, 用于捕获测试中 assertion 无法发现的异常行为:泄漏的异步 操作、未关闭的资源以及意外的进程退出。

资源清理器 Jump to heading

资源清理器会确保测试期间创建的所有 I/O 资源都已关闭, 以防止泄漏。

I/O 资源包括例如 Deno.FsFile 句柄、 网络连接、fetch 响应体、计时器,以及其他 不会被自动垃圾回收的资源。

你应该在完成使用后始终关闭资源。例如,关闭文件:

const file = await Deno.open("hello.txt");
// 对文件执行一些操作
file.close(); // <- 使用完文件后始终关闭它

关闭网络连接:

const conn = await Deno.connect({ hostname: "example.com", port: 80 });
// 对连接执行一些操作
conn.close(); // <- 使用完连接后始终关闭它

关闭 fetch 响应体:

const response = await fetch("https://example.com");
// 对响应执行一些操作
await response.body?.cancel(); // <- 如果没有以其他方式消费它,使用完后始终取消响应体

从 Deno 2.8 开始,此清理器默认关闭。你可以通过 sanitizeResources: true 启用它,或使用 全局启用清理器 中描述的全局机制之一。

Deno.test({
  name: "不允许泄漏",
  async fn() {
    using file = await Deno.open("hello.txt");
    // ...
  },
  sanitizeResources: true,
});

异步操作清理器 Jump to heading

异步操作清理器会确保测试中启动的所有异步操作都在 测试结束前完成。这一点很重要,因为如果某个异步 操作没有被 await,测试会在该操作完成前结束, 即使该操作实际上可能已经失败,测试也会被标记为成功。

你应该在测试中始终 await 所有异步操作。例如:

Deno.test({
  name: "异步操作测试",
  async fn() {
    await new Promise((resolve) => setTimeout(resolve, 1000));
  },
});

从 Deno 2.8 开始,此清理器默认关闭。你可以通过 sanitizeOps: true 启用它,或使用下面描述的全局机制之一。

Deno.test({
  name: "不允许泄漏的操作",
  async fn() {
    await someAsyncWork();
  },
  sanitizeOps: true,
});

全局启用清理器 Jump to heading

如果你想要 pre-2.8 的行为(对每个测试都开启资源和操作清理器), 可以在以下五个作用域中的任意一个重新启用它们。更高优先级的设置 会覆盖更低优先级的设置。

  1. 按测试(最高优先级):

    Deno.test({
      name: "严格模式",
      sanitizeOps: true,
      sanitizeResources: true,
      fn() {/* … */},
    });
    
  2. 按模块,使用 Deno.test.sanitizer()

    Deno.test.sanitizer({ ops: true, resources: true });
    
    Deno.test("使用模块级清理器", () => {/* … */});
    
  3. CLI 标志--sanitize-ops--sanitize-resources

  4. 环境变量DENO_TEST_SANITIZE_OPS=1DENO_TEST_SANITIZE_RESOURCES=1

  5. deno.json(最低优先级):

    {
      "test": {
        "sanitizeOps": true,
        "sanitizeResources": true
      }
    }
    

退出清理器 Jump to heading

退出清理器会确保被测试的代码不会调用 Deno.exit(),因为这可能会造成测试成功的假象。

此清理器默认启用,但可以通过 sanitizeExit: false 关闭。

Deno.test({
  name: "错误的成功",
  fn() {
    Deno.exit(0);
  },
  sanitizeExit: false,
});

// 这个测试永远不会运行,因为进程会在“错误的成功”测试期间退出
Deno.test({
  name: "失败的测试",
  fn() {
    throw new Error("这个测试失败了");
  },
});

Did you find what you needed?

编辑此页面
Privacy policy