Testing
Deno has a built-in test runner that you can use for testing JavaScript or TypeScript code.
Lets start with an example all_tests.js
import {assertEquals} from "https://deno.land/std@0.199.0/assert/mod.ts";
Deno.test("url test", ()=>{
const url = new URL("./foo.js", "https://deno.land")
assertEquals(url.href, "htts://deno.land/foo.js");
})
deno test all_tests.js
"Deno.test" function takes two parameters, 1. Test name 2. Callback function to execute
We can specify extra configurations as a new parameter in json format deno.json
{
"imports":{
"assertTest" : "https://deno.land/std@0.199.0/assert/mod.ts",
"asyncTest" : "https://deno.land/std@0.199.0/async/delay.ts",
"Postgres" : "https://deno.land/x/postgres@v0.15.0/mod.ts",
}
}
tests.js
import {assertEquals} from "assertTest";
Deno.test("hi there #1", ()=>{
const s = 1+2;
assertEquals(x, 3);
});
// Compact form: named function.
Deno.test(function helloWorld3() {
const x = 1 + 2;
assertEquals(x, 3);
});
// Longer form: test definition.
Deno.test({
name: "hello world #2",
fn: () => {
const x = 1 + 2;
assertEquals(x, 3);
},
});
// Similar to compact form, with additional configuration as a second argument.
Deno.test("hello world #4", { permissions: { read: true } }, () => {
const x = 1 + 2;
assertEquals(x, 3);
});
// Similar to longer form, with test function as a second argument.
Deno.test(
{ name: "hello world #5", permissions: { read: true } },
() => {
const x = 1 + 2;
assertEquals(x, 3);
},
);
// Similar to longer form, with a named test function as a second argument.
Deno.test({ permissions: { read: true } }, function helloWorld6() {
const x = 1 + 2;
assertEquals(x, 3);
});
Async Testing
import {delay} from "asyncTest";
Deno.test("async test", async () =>{
const x = 1+2;
await deplay(100);
if(x !== 3) throw Error("X should be 3");
});
Test Example
import { assertEquals } from "assertTest";
import { Client } from "Postgres";
interface User {
id: number;
name: string;
}
interface Book {
id: number;
title: string;
}
Deno.test("database", async (t) => {
const client = new Client({
user: "user",
database: "test",
hostname: "localhost",
port: 5432,
});
await client.connect();
// provide a step name and function
await t.step("insert user", async () => {
const users = await client.queryObject<User>(
"INSERT INTO users (name) VALUES ('Deno') RETURNING *",
);
assertEquals(users.rows.length, 1);
assertEquals(users.rows[0].name, "Deno");
});
// or provide a test definition
await t.step({
name: "insert book",
fn: async () => {
const books = await client.queryObject<Book>(
"INSERT INTO books (name) VALUES ('The Deno Manual') RETURNING *",
);
assertEquals(books.rows.length, 1);
assertEquals(books.rows[0].title, "The Deno Manual");
},
ignore: false,
// these default to the parent test or step's value
sanitizeOps: true,
sanitizeResources: true,
sanitizeExit: true,
});
// nested steps are also supported
await t.step("update and delete", async (t) => {
await t.step("update", () => {
// even though this test throws, the outer promise does not reject
// and the next test step will run
throw new Error("Fail.");
});
await t.step("delete", () => {
// ...etc...
});
});
// steps return a value saying if they ran or not
const testRan = await t.step({
name: "copy books",
fn: () => {
// ...etc...
},
ignore: true, // was ignored, so will return `false`
});
// steps can be run concurrently if sanitizers are disabled on sibling steps
const testCases = [1, 2, 3];
await Promise.all(testCases.map((testCase) =>
t.step({
name: `case ${testCase}`,
fn: async () => {
// ...etc...
},
sanitizeOps: false,
sanitizeResources: false,
sanitizeExit: false,
})
));
client.end();
});
Example output:
test database ...
test insert user ... ok (2ms)
test insert book ... ok (14ms)
test update and delete ...
test update ... FAILED (17ms)
Error: Fail.
at <stack trace omitted>
test delete ... ok (19ms)
FAILED (46ms)
test copy books ... ignored (0ms)
test case 1 ... ok (14ms)
test case 2 ... ok (14ms)
test case 3 ... ok (14ms)
FAILED (111ms)
Test steps must be awaited before the parent test/step function resolves or you will get a runtime error Test steps cannot be run concurrently unless sanitizers on a sibling step or parent test are disabled If nesting steps, ensure you specify a parameter for the parent step
Deno.test("test1", async ()=>{
await t.step("s1", async () =>{
await t.step("sub-step", ()=>{});
});
});
Last updated