Testing, mocks, and coverage

Build reliable tests with Deno.test, permissions, filters, coverage, and resource cleanup

Minimal test

import { assertEquals } from "jsr:@std/assert";

Deno.test("normalizes a user name", () => {
  assertEquals(" Ada ".trim(), "Ada");
});
deno test
deno test --filter "user"
deno test --watch

Deno 2.9 has snapshots on the test context with no extra import:

Deno.test("renders a card", async (t) => {
  await t.assertSnapshot(renderCard({ title: "Deno" }));
});

Create or refresh snapshots with deno test --update-snapshots and review the __snapshots__/*.snap diff. CI runs plain deno test and must never update expected output.

Tests are sandboxed too. Grant network or temporary-directory access only to the tests that need it; do not run the whole suite with -A because one integration test needs I/O.

Async cleanup

Deno.test("fetches health", async () => {
  const controller = new AbortController();
  try {
    // start resource, assert behavior
  } finally {
    controller.abort();
  }
});

Deno's sanitizers help detect leaked async operations and resources. Note the defaults: since Deno 2.8, only the exit sanitizer is on by default; the op and resource sanitizers are opt-in. Enable leak detection explicitly on the test or step that needs it instead of relying on defaults:

Deno.test({
  name: "closes every handle",
  sanitizeOps: true,
  sanitizeResources: true,
  fn: async () => {
    // ...
  },
});

Conversely, if a test intentionally keeps background work alive, disable the relevant sanitizer on that test with a note explaining why — never disable them globally.

Coverage

deno test --coverage=coverage
deno coverage --lcov --output=coverage.lcov coverage/

Coverage does not replace tests for failure paths, denied permissions, timeouts, and cancellation. CI should run at least fmt --check, lint, check, and test.

Large suites

deno test --changed=origin/main
deno test --shard=1/3
deno test --retry=2
deno test --repeats=3
deno test --trace-leaks

retry tolerates a known flaky failure and passes after one successful attempt; repeats requires every run to pass and helps expose instability. Do not let retries permanently hide a deterministic defect.

Official references: Testing, Coverage, and Mocking.

Type to search all documentation.