Testing
Robust testing and benchmarking capabilities to ensure code quality and performance.
Eg Deno.test, Deno.bench
Functions
Register a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
Interfaces
Context that is passed to a benchmarked function. The instance is shared between iterations of the benchmark. Its methods can be used for example to override of the measured portion of the function.
The interface for defining a benchmark test using Deno.bench.
Context that is passed to a testing function, which can be used to either gain information about the current test, or register additional test steps within the current test.
Variables
Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
function Deno.bench
Overload 1
#bench(b: BenchDefinition): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench({
name: "example test",
fn() {
assertEquals("world", "world");
},
});
Deno.bench({
name: "example ignored test",
ignore: Deno.build.os === "windows",
fn() {
// This test is ignored only on Windows machines
},
});
Deno.bench({
name: "example async test",
async fn() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
});
Parameters #
Return Type #
void Overload 2
#bench(name: string,fn: (b: BenchContext) => void | Promise<void>,): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench("My test description", () => {
assertEquals("hello", "hello");
});
Deno.bench("My async test description", async () => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
});
Parameters #
#name: string #fn: (b: BenchContext) => void | Promise<void> Return Type #
void Overload 3
#bench(fn: (b: BenchContext) => void | Promise<void>): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench(function myTestName() {
assertEquals("hello", "hello");
});
Deno.bench(async function myOtherTestName() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
});
Parameters #
#fn: (b: BenchContext) => void | Promise<void> Return Type #
void Overload 4
#bench(name: string,options: Omit<BenchDefinition, "fn" | "name">,fn: (b: BenchContext) => void | Promise<void>,): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench(
"My test description",
{ permissions: { read: true } },
() => {
assertEquals("hello", "hello");
}
);
Deno.bench(
"My async test description",
{ permissions: { read: false } },
async () => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
);
Parameters #
#name: string #options: Omit<BenchDefinition, "fn" | "name"> #fn: (b: BenchContext) => void | Promise<void> Return Type #
void Overload 5
#bench(options: Omit<BenchDefinition, "fn">,fn: (b: BenchContext) => void | Promise<void>,): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench(
{ name: "My test description", permissions: { read: true } },
() => {
assertEquals("hello", "hello");
}
);
Deno.bench(
{ name: "My async test description", permissions: { read: false } },
async () => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
);
Parameters #
#options: Omit<BenchDefinition, "fn"> #fn: (b: BenchContext) => void | Promise<void> Return Type #
void Overload 6
#bench(options: Omit<BenchDefinition, "fn" | "name">,fn: (b: BenchContext) => void | Promise<void>,): voidRegister a benchmark test which will be run when deno bench is used on
the command line and the containing module looks like a bench module.
If the test function (fn) returns a promise or is async, the test runner
will await resolution to consider the test complete.
import { assertEquals } from "jsr:@std/assert";
Deno.bench(
{ permissions: { read: true } },
function myTestName() {
assertEquals("hello", "hello");
}
);
Deno.bench(
{ permissions: { read: false } },
async function myOtherTestName() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
);
Parameters #
#options: Omit<BenchDefinition, "fn" | "name"> #fn: (b: BenchContext) => void | Promise<void> Return Type #
void interface Deno.BenchContext
Context that is passed to a benchmarked function. The instance is shared between iterations of the benchmark. Its methods can be used for example to override of the measured portion of the function.
Properties #
Methods #
Restarts the timer for the bench measurement. This should be called after doing setup work which should not be measured.
Warning: This method should not be used for benchmarks averaging less than 10μs per iteration. In such cases it will be disabled but the call will still have noticeable overhead, resulting in a warning.
Deno.bench("foo", async (t) => {
const data = await Deno.readFile("data.txt");
t.start();
// some operation on `data`...
});
End the timer early for the bench measurement. This should be called before doing teardown work which should not be measured.
Warning: This method should not be used for benchmarks averaging less than 10μs per iteration. In such cases it will be disabled but the call will still have noticeable overhead, resulting in a warning.
Deno.bench("foo", async (t) => {
using file = await Deno.open("data.txt");
t.start();
// some operation on `file`...
t.end();
});
interface Deno.BenchDefinition
The interface for defining a benchmark test using Deno.bench.
Properties #
#fn: (b: BenchContext) => void | Promise<void> The test function which will be benchmarked.
Group name for the benchmark.
Grouped benchmarks produce a group time summary, where the difference in performance between each test of the group is compared.
Benchmark should be used as the baseline for other benchmarks.
If there are multiple baselines in a group, the first one is used as the baseline.
If at least one bench has only set to true, only run benches that have
only set to true and fail the bench suite.
#sanitizeExit: boolean = true Ensure the bench case does not prematurely cause the process to exit,
for example via a call to Deno.exit.
#permissions: PermissionOptions = "inherit" Specifies the permissions that should be used to run the bench.
Set this to "inherit" to keep the calling thread's permissions.
Set this to "none" to revoke all permissions.
interface Deno.DenoTest
Call Signatures #
(t: TestDefinition): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required.
import { assertEquals } from "jsr:@std/assert";
Deno.test({
name: "example test",
fn() {
assertEquals("world", "world");
},
});
Deno.test({
name: "example ignored test",
ignore: Deno.build.os === "windows",
fn() {
// This test is ignored only on Windows machines
},
});
Deno.test({
name: "example async test",
async fn() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
});
(name: string,fn: (t: TestContext) => void | Promise<void>,): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required.
import { assertEquals } from "jsr:@std/assert";
Deno.test("My test description", () => {
assertEquals("hello", "hello");
});
Deno.test("My async test description", async () => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
});
(fn: (t: TestContext) => void | Promise<void>): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required. Declared function must have a name.
import { assertEquals } from "jsr:@std/assert";
Deno.test(function myTestName() {
assertEquals("hello", "hello");
});
Deno.test(async function myOtherTestName() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
});
(name: string,options: Omit<TestDefinition, "fn" | "name">,fn: (t: TestContext) => void | Promise<void>,): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required.
import { assert, fail, assertEquals } from "jsr:@std/assert";
Deno.test("My test description", { permissions: { read: true } }, (): void => {
assertEquals("hello", "hello");
});
Deno.test("My async test description", { permissions: { read: false } }, async (): Promise<void> => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
});
(options: Omit<TestDefinition, "fn" | "name">,fn: (t: TestContext) => void | Promise<void>,): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required.
import { assertEquals } from "jsr:@std/assert";
Deno.test(
{
name: "My test description",
permissions: { read: true },
},
() => {
assertEquals("hello", "hello");
},
);
Deno.test(
{
name: "My async test description",
permissions: { read: false },
},
async () => {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
},
);
(options: Omit<TestDefinition, "fn">,fn: (t: TestContext) => void | Promise<void>,): void Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required. Declared function must have a name.
import { assertEquals } from "jsr:@std/assert";
Deno.test(
{ permissions: { read: true } },
function myTestName() {
assertEquals("hello", "hello");
},
);
Deno.test(
{ permissions: { read: false } },
async function myOtherTestName() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
},
);
Methods #
#ignore(t: Omit<TestDefinition, "ignore">): void Shorthand property for ignoring a particular test case.
#ignore(name: string,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for ignoring a particular test case.
#ignore(fn: (t: TestContext) => void | Promise<void>): void Shorthand property for ignoring a particular test case.
#ignore(name: string,options: Omit<TestDefinition, "fn"
| "name"
| "ignore">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for ignoring a particular test case.
#ignore(options: Omit<TestDefinition, "fn"
| "name"
| "ignore">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for ignoring a particular test case.
#ignore(options: Omit<TestDefinition, "fn" | "ignore">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for ignoring a particular test case.
#only(t: Omit<TestDefinition, "only">): void Shorthand property for focusing a particular test case.
#only(name: string,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for focusing a particular test case.
#only(fn: (t: TestContext) => void | Promise<void>): void Shorthand property for focusing a particular test case.
#only(name: string,options: Omit<TestDefinition, "fn"
| "name"
| "only">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for focusing a particular test case.
#only(options: Omit<TestDefinition, "fn"
| "name"
| "only">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for focusing a particular test case.
#only(options: Omit<TestDefinition, "fn" | "only">,fn: (t: TestContext) => void | Promise<void>,): void Shorthand property for focusing a particular test case.
Register a function to be called before all tests in the current scope.
These functions are run in FIFO order (first in, first out).
If an exception is raised during execution of this hook, the remaining beforeAll hooks will not be run.
Deno.test.beforeAll(() => {
// Setup code that runs once before all tests
console.log("Setting up test suite");
});
#beforeEach(fn: () => void | Promise<void>): void Register a function to be called before each test in the current scope.
These functions are run in FIFO order (first in, first out).
If an exception is raised during execution of this hook, the remaining hooks will not be run and the currently running test case will be marked as failed.
Deno.test.beforeEach(() => {
// Setup code that runs before each test
console.log("Setting up test");
});
Register a function to be called after each test in the current scope.
These functions are run in LIFO order (last in, first out).
If an exception is raised during execution of this hook, the remaining hooks will not be run and the currently running test case will be marked as failed.
Deno.test.afterEach(() => {
// Cleanup code that runs after each test
console.log("Cleaning up test");
});
Register a function to be called after all tests in the current scope have finished running.
These functions are run in the LIFO order (last in, first out).
If an exception is raised during execution of this hook, the remaining afterAll hooks will not be run.
Deno.test.afterAll(() => {
// Cleanup code that runs once after all tests
console.log("Cleaning up test suite");
});
Configure sanitizers at the module level. This overrides CLI flags and
config file settings, but can still be overridden per-test via
sanitizeOps / sanitizeResources in test options.
Should be called at the top of the module, before any Deno.test()
registrations — each call sets the defaults that subsequently registered
tests inherit, so tests registered before the call use the previous
defaults.
// Enable both sanitizers for all tests in this file
Deno.test.sanitizer({ ops: true, resources: true });
Deno.test("my test", () => {
// This test will have ops and resources sanitizers enabled
});
Deno.test({
name: "override per-test",
sanitizeOps: false,
fn() {
// This test opts out of ops sanitizer
},
});
interface Deno.TestContext
Context that is passed to a testing function, which can be used to either gain information about the current test, or register additional test steps within the current test.
Properties #
Methods #
#step(definition: TestStepDefinition): Promise<boolean> Run a sub step of the parent test or step. Returns a promise that resolves to a boolean signifying if the step completed successfully.
The returned promise never rejects unless the arguments are invalid.
If the test was ignored the promise returns false.
Deno.test({
name: "a parent test",
async fn(t) {
console.log("before the step");
await t.step({
name: "step 1",
fn(t) {
console.log("current step:", t.name);
}
});
console.log("after the step");
}
});
#step(name: string,fn: (t: TestContext) => void | Promise<void>,): Promise<boolean> Run a sub step of the parent test or step. Returns a promise that resolves to a boolean signifying if the step completed successfully.
The returned promise never rejects unless the arguments are invalid.
If the test was ignored the promise returns false.
Deno.test(
"a parent test",
async (t) => {
console.log("before the step");
await t.step(
"step 1",
(t) => {
console.log("current step:", t.name);
}
);
console.log("after the step");
}
);
#step(fn: (t: TestContext) => void | Promise<void>): Promise<boolean> Run a sub step of the parent test or step. Returns a promise that resolves to a boolean signifying if the step completed successfully.
The returned promise never rejects unless the arguments are invalid.
If the test was ignored the promise returns false.
Deno.test(async function aParentTest(t) {
console.log("before the step");
await t.step(function step1(t) {
console.log("current step:", t.name);
});
console.log("after the step");
});
interface Deno.TestDefinition
Properties #
#fn: (t: TestContext) => void | Promise<void> If truthy the current test step will be ignored.
It is a quick way to skip over a step, but also can be used for conditional logic, like determining if an environment feature is present.
If at least one test has only set to true, only run tests that have
only set to true and fail the test suite.
#sanitizeOps: boolean = false Check that the number of async completed operations after the test step is the same as number of dispatched operations. This ensures that the code tested does not start async operations which it then does not await. This helps in preventing logic errors and memory leaks in the application code.
Can also be enabled globally with the --sanitize-ops CLI flag,
the DENO_TEST_SANITIZE_OPS=1 environment variable, or the
test.sanitizeOps option in deno.json. Can be set per-module
with Deno.test.sanitizer.
#sanitizeResources: boolean = false Ensure the test step does not "leak" resources - like open files or network connections - by ensuring the open resources at the start of the test match the open resources at the end of the test.
Can also be enabled globally with the --sanitize-resources CLI flag,
the DENO_TEST_SANITIZE_RESOURCES=1 environment variable, or the
test.sanitizeResources option in deno.json. Can be set per-module
with Deno.test.sanitizer.
#sanitizeExit: boolean = true Ensure the test case does not prematurely cause the process to exit,
for example via a call to Deno.exit.
#permissions: PermissionOptions = "inherit" Specifies the permissions that should be used to run the test.
Set this to "inherit" to keep the calling runtime permissions, set this
to "none" to revoke all permissions, or set a more specific set of
permissions using a PermissionOptionsObject.
interface Deno.TestStepDefinition
Properties #
#fn: (t: TestContext) => void | Promise<void> The test function that will be tested when this step is executed. The function can take an argument which will provide information about the current step's context.
If truthy the current test step will be ignored.
This is a quick way to skip over a step, but also can be used for conditional logic, like determining if an environment feature is present.
#sanitizeOps: boolean Check that the number of async completed operations after the test step is the same as number of dispatched operations. This ensures that the code tested does not start async operations which it then does not await. This helps in preventing logic errors and memory leaks in the application code.
Defaults to the parent test or step's value.
#sanitizeResources: boolean Ensure the test step does not "leak" resources - like open files or network connections - by ensuring the open resources at the start of the step match the open resources at the end of the step.
Defaults to the parent test or step's value.
#sanitizeExit: boolean Ensure the test step does not prematurely cause the process to exit,
for example via a call to Deno.exit.
Defaults to the parent test or step's value.
variable Deno.test
Register a test which will be run when deno test is used on the command
line and the containing module looks like a test module.
fn can be async if required.
Tests are discovered before they are executed, so registrations must happen
at module load time.
Nested Deno.test() calls are not supported.
Use t.step() for nested tests.
import { assertEquals } from "jsr:@std/assert";
Deno.test({
name: "example test",
fn() {
assertEquals("world", "world");
},
});
Deno.test({
name: "example ignored test",
ignore: Deno.build.os === "windows",
fn() {
// This test is ignored only on Windows machines
},
});
Deno.test({
name: "example async test",
async fn() {
const decoder = new TextDecoder("utf-8");
const data = await Deno.readFile("hello_world.txt");
assertEquals(decoder.decode(data), "Hello world");
}
});