Skip to content

/commands/deno/deno-test

deno test: run tests in Deno and filter a single test

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
Deno
versions
Deno 2.x
os
any

deno test finds the test files in the current folder and its subfolders, type-checks them and runs every Deno.test() case, then prints a summary and exits with code 1 if any test failed. No test framework has to be installed: the runner, assertions (@std/assert from JSR) and coverage are part of Deno. deno test --filter "name" runs only the tests whose name matches.

Write and run tests

bash
cat > math.ts <<'EOF'
export const add = (a: number, b: number): number => a + b;
EOF
cat > math_test.ts <<'EOF'
import { add } from "./math.ts";

Deno.test("add returns the sum", () => {
  if (add(1, 2) !== 3) throw new Error("expected 3");
});

Deno.test("add handles negatives", () => {
  if (add(-2, 2) !== 1) throw new Error("expected 1");
});
EOF
export NO_COLOR=1
npx --yes deno@2 test 2>&1 | sed -E 's/ \([0-9.]+(µs|ms|s)\)//; /^    at /d'
exit "${PIPESTATUS[0]}"

Output · exit 1

Check math_test.ts
running 2 tests from ./math_test.ts
add returns the sum ... ok
add handles negatives ... FAILED

 ERRORS

add handles negatives => ./math_test.ts:7:6
error: Error: expected 1
  if (add(-2, 2) !== 1) throw new Error("expected 1");
                              ^

 FAILURES

add handles negatives => ./math_test.ts:7:6

FAILED | 1 passed | 1 failed

error: Test failed

The second test is wrong on purpose. Deno prints each test with ok or FAILED, then an ERRORS section with the thrown error and its location, a FAILURES list and the totals; the command exits with code 1. The example runs Deno through npx deno@2 so it needs only Node.js; with Deno installed the command is just deno test.

Run one test with --filter

bash
cat > math_test.ts <<'EOF'
Deno.test("add returns the sum", () => {});
Deno.test("add handles negatives", () => {});
Deno.test("subtract", () => {});
EOF
export NO_COLOR=1
npx --yes deno@2 test --filter "negatives" 2>&1 | sed -E 's/ \([0-9.]+(µs|ms|s)\)//'

Output

Check math_test.ts
running 1 test from ./math_test.ts
add handles negatives ... ok

ok | 1 passed | 0 failed | 2 filtered out

Tests that do not match are counted as filtered out, not as passed. Use --filter "/^add/" for a regular expression.

Common options

CommandWhat it does
deno testRun every test file under the current folder
deno test src/math_test.tsRun one file (or pass a folder)
deno test --filter "name"Only tests whose name contains the text; /regex/ for a pattern
deno test --allow-read --allow-netGrant permissions; tests start with none, like deno run
deno test --watchRe-run tests when files change
deno test --coverage=covCollect coverage, then show it with deno coverage cov
deno test --fail-fastStop after the first failing test
deno test --parallelRun test files in parallel worker processes
deno test --no-checkSkip type-checking to start faster
deno test --docAlso evaluate code blocks in JSDoc comments and Markdown files

Pitfalls

  • Permissions. A test that reads a file or opens a socket fails with NotCapable unless you pass the matching --allow-* flag; see Requires read access.
  • Type errors stop the run. deno test type-checks local test files first, so a type error fails before any test runs. --no-check skips it, at the cost of catching those errors later.
  • Leaks. Deno checks that each test closes the timers, files and network resources it opens, and fails the test with a leak report when it does not. Await your promises and close what you open.
  • File names. A file called math.spec.ts is not picked up automatically; name it math_test.ts or math.test.ts, or pass it explicitly.

How to confirm it worked

The last line shows ok or FAILED with the number of passed, failed and filtered tests, and echo $? after the command prints 0 only when every test passed. In CI, that exit code is all you need. Format and lint checks fit in the same job: deno fmt --check and deno lint.

FAQ

Why does deno test fail with a permission error when deno run works?

Tests run with no permissions unless you grant them, exactly like deno run. If the command you use for the program has --allow-read or --allow-net, add the same flags to deno test, or set permissions for one test with the permissions option of Deno.test.

How do I run only one test?

Pass --filter with the test name, or a /regex/ between slashes. For a temporary focus inside the file, use Deno.test.only or Deno.test({ only: true, ... }); deno test then reports a failure at the end so the focus is not committed by accident.

Where does deno test look for test files?

Without arguments it searches the current folder recursively for files named *_test, *.test or test with a .ts, .tsx, .mts, .js, .mjs, .jsx or .cjs extension. Pass files or folders to limit it, and use the test.include and test.exclude keys of deno.json to change the defaults.

Sources