A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://docs.deno.com/runtime/fundamentals/testing/ below:

Testing

Deno provides a built-in test runner for writing and running tests in both JavaScript and TypeScript. This makes it easy to ensure your code is reliable and functions as expected without needing to install any additional dependencies or tools. The deno test runner allows you fine-grained control over permissions for each test, ensuring that code does not do anything unexpected.

In addition to the built-in test runner, you can also use other test runners from the JS ecosystem, such as Jest, Mocha, or AVA, with Deno. We will not cover these in this document however.

Writing Tests Jump to heading#

To define a test in Deno, you use the Deno.test() function. Here are some examples:

my_test.ts

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

Deno.test("simple test", () => {
  const x = 1 + 2;
  assertEquals(x, 3);
});

import { delay } from "jsr:@std/async";

Deno.test("async test", async () => {
  const x = 1 + 2;
  await delay(100);
  assertEquals(x, 3);
});

Deno.test({
  name: "read file test",
  fn: () => {
    const data = Deno.readTextFileSync("./somefile.txt");
    assertEquals(data, "expected content");
  },
});

If you prefer a "jest-like" expect style of assertions, the Deno standard library provides an expect function that can be used in place of assertEquals:

my_test.ts

import { expect } from "jsr:@std/expect";
import { add } from "./add.js";

Deno.test("add function adds two numbers correctly", () => {
  const result = add(2, 3);
  expect(result).toBe(5);
});
Running Tests Jump to heading#

To run your tests, use the deno test subcommand.

If run without a file name or directory name, this subcommand will automatically find and execute all tests in the current directory (recursively) that match the glob {*_,*.,}test.{ts, tsx, mts, js, mjs, jsx}.


deno test


deno test util/


deno test my_test.ts


deno test --parallel


deno test my_test.ts -- -e --foo --bar



deno test --allow-read=. my_test.ts
Test Steps Jump to heading#

Deno also supports test steps, which allow you to break down tests into smaller, manageable parts. This is useful for setup and teardown operations within a test:

Deno.test("database operations", async (t) => {
  using db = await openDatabase();
  await t.step("insert user", async () => {
    
  });
  await t.step("insert book", async () => {
    
  });
});
Command line filtering Jump to heading#

Deno allows you to run specific tests or groups of tests using the --filter option on the command line. This option accepts either a string or a pattern to match test names. Filtering does not affect steps; if a test name matches the filter, all of its steps are executed.

Consider the following tests:

Deno.test("my-test", () => {});
Deno.test("test-1", () => {});
Deno.test("test-2", () => {});
Filtering by string Jump to heading#

To run all tests that contain the word "my" in their names, use:

deno test --filter "my" tests/

This command will execute my-test because it contains the word "my".

Filtering by Pattern Jump to heading#

To run tests that match a specific pattern, use:

deno test --filter "/test-*\d/" tests/

This command will run test-1 and test-2 because they match the pattern test-* followed by a digit.

To indicate that you are using a pattern (regular expression), wrap your filter value with forward slashes /, much like JavaScript’s syntax for regular expressions.

Including and excluding test files in the configuration file Jump to heading#

You can also filter tests by specifying paths to include or exclude in the Deno configuration file.

For example, if you want to only test src/fetch_test.ts and src/signal_test.ts and exclude everything in out/:

{
  "test": {
    "include": [
      "src/fetch_test.ts",
      "src/signal_test.ts"
    ]
  }
}

Or more likely:

{
  "test": {
    "exclude": ["out/"]
  }
}
Test definition selection Jump to heading#

Deno provides two options for selecting tests within the test definitions themselves: ignoring tests and focusing on specific tests.

Ignoring/Skipping Tests Jump to heading#

You can ignore certain tests based on specific conditions using the ignore boolean in the test definition. If ignore is set to true, the test will be skipped. This is useful, for example, if you only want a test to run on a specific operating system.

Deno.test({
  name: "do macOS feature",
  ignore: Deno.build.os !== "darwin", 
  fn() {
    
  },
});

If you want to ignore a test without passing any conditions, you can use the ignore() function from the Deno.test object:

Deno.test.ignore("my test", () => {
  
});
Only Run Specific Tests Jump to heading#

If you want to focus on a particular test and ignore the rest, you can use the only option. This tells the test runner to run only the tests with only set to true. Multiple tests can have this option set. However, if any test is flagged with only, the overall test run will always fail, as this is intended to be a temporary measure for debugging.

Deno.test.only("my test", () => {
  
});

or

Deno.test({
  name: "Focus on this test only",
  only: true, 
  fn() {
    
  },
});
Failing fast Jump to heading#

If you have a long-running test suite and wish for it to stop on the first failure, you can specify the --fail-fast flag when running the suite.

This will cause the test runner to stop execution after the first test failure.

Reporters Jump to heading#

Deno includes three built-in reporters to format test output:

You can specify which reporter to use with the --reporter flag:


deno test


deno test --reporter=dot


deno test --reporter=junit

Additionally, you can write the JUnit report to a file while still getting human-readable output in the terminal by using the --junit-path flag:

deno test --junit-path=./report.xml
Spying, mocking (test doubles), stubbing and faking time Jump to heading#

The Deno Standard Library provides a set of functions to help you write tests that involve spying, mocking, and stubbing. Check out the @std/testing documentation on JSR for more information on each of these utilities or our tutorial on mocking and spying in tests with deno.

Coverage Jump to heading#

Deno will collect test coverage into a directory for your code if you specify the --coverage flag when starting deno test. This coverage information is acquired directly from the V8 JavaScript engine, ensuring high accuracy.

This can then be further processed from the internal format into well known formats like lcov with the deno coverage tool.

Behavior-Driven Development Jump to heading#

With the @std/testing/bdd module you can write your tests in a familiar format for grouping tests and adding setup/teardown hooks used by other JavaScript testing frameworks like Jasmine, Jest, and Mocha.

The describe function creates a block that groups together several related tests. The it function registers an individual test case. For example:

import { describe, it } from "jsr:@std/testing/bdd";
import { expect } from "jsr:@std/expect";
import { add } from "./add.js";

describe("add function", () => {
  it("adds two numbers correctly", () => {
    const result = add(2, 3);
    expect(result).toBe(5);
  });

  it("handles negative numbers", () => {
    const result = add(-2, -3);
    expect(result).toBe(-5);
  });
});

Check out the documentation on JSR for more information on these functions and hooks.

Documentation Tests Jump to heading#

Deno allows you to evaluate code snippets written in JSDoc or markdown files. This ensures the examples in your documentation are up-to-date and functional.

Example code blocks Jump to heading#

example.ts


export function add(a: number, b: number): number {
  return a + b;
}

The triple backticks mark the start and end of code blocks, the language is determined by the language identifier attribute which may be one of the following:

If no language identifier is specified then the language is inferred from media type of the source document that the code block is extracted from.

deno test --doc example.ts

The above command will extract this example, turn it into a pseudo test case that looks like below:

example.ts$4-10.ts

import { assertEquals } from "jsr:@std/assert/equals";
import { add } from "file:///path/to/example.ts";

Deno.test("example.ts$4-10.ts", async () => {
  const sum = add(1, 2);
  assertEquals(sum, 3);
});

and then run it as a standalone module living in the same directory as the module being documented.

Want to type-check only?

If you want to type-check your code snippets in JSDoc and markdown files without actually running them, you can use deno check command with --doc option (for JSDoc) or with --doc-only option (for markdown) instead.

Exported items are automatically imported Jump to heading#

Looking at the generated test code above, you will notice that it includes the import statement to import the add function even though the original code block does not have it. When documenting a module, any items exported from the module are automatically included in the generated test code using the same name.

Let's say we have the following module:

example.ts


export function add(a: number, b: number): number {
  return a + b;
}

export const ONE = 1;
export default function getTwo() {
  return 2;
}

This will get converted to the following test case:

example.ts$4-10.ts

import { assertEquals } from "jsr:@std/assert/equals";
import { add, ONE }, getTwo from "file:///path/to/example.ts";

Deno.test("example.ts$4-10.ts", async () => {
  const sum = add(ONE, getTwo());
  assertEquals(sum, 3);
});
Skipping code blocks Jump to heading#

You can skip the evaluation of code blocks by adding the ignore attribute.


export async function sendEmail(to: string) {
  
}
Sanitizers Jump to heading#

The test runner offers several sanitizers to ensure that the test behaves in a reasonable and expected way.

Resource sanitizer Jump to heading#

The resource sanitizer ensures that all I/O resources created during a test are closed, to prevent leaks.

I/O resources are things like Deno.FsFile handles, network connections, fetch bodies, timers, and other resources that are not automatically garbage collected.

You should always close resources when you are done with them. For example, to close a file:

const file = await Deno.open("hello.txt");

file.close(); 

To close a network connection:

const conn = await Deno.connect({ hostname: "example.com", port: 80 });

conn.close(); 

To close a fetch body:

const response = await fetch("https://example.com");

await response.body?.cancel(); 

This sanitizer is enabled by default, but can be disabled in this test with sanitizeResources: false:

Deno.test({
  name: "leaky resource test",
  async fn() {
    await Deno.open("hello.txt");
  },
  sanitizeResources: false,
});
Async operation sanitizer Jump to heading#

The async operation sanitizer ensures that all async operations started in a test are completed before the test ends. This is important because if an async operation is not awaited, the test will end before the operation is completed, and the test will be marked as successful even if the operation may have actually failed.

You should always await all async operations in your tests. For example:

Deno.test({
  name: "async operation test",
  async fn() {
    await new Promise((resolve) => setTimeout(resolve, 1000));
  },
});

This sanitizer is enabled by default, but can be disabled with sanitizeOps: false:

Deno.test({
  name: "leaky operation test",
  fn() {
    crypto.subtle.digest(
      "SHA-256",
      new TextEncoder().encode("a".repeat(100000000)),
    );
  },
  sanitizeOps: false,
});
Exit sanitizer Jump to heading#

The exit sanitizer ensures that tested code doesn’t call Deno.exit(), which could signal a false test success.

This sanitizer is enabled by default, but can be disabled with sanitizeExit: false.

Deno.test({
  name: "false success",
  fn() {
    Deno.exit(0);
  },
  sanitizeExit: false,
});


Deno.test({
  name: "failing test",
  fn() {
    throw new Error("this test fails");
  },
});
Snapshot testing Jump to heading#

The Deno Standard Library includes a snapshot module that allows developers to write tests by comparing values against reference snapshots. These snapshots are serialized representations of the original values and are stored alongside the test files.

Snapshot testing enables catching a wide array of bugs with very little code. It is particularly helpful in situations where it is difficult to precisely express what should be asserted, without requiring a prohibitive amount of code, or where the assertions a test makes are expected to change often.

Tests and Permissions Jump to heading#

The permissions property in the Deno.test configuration allows you to specifically deny permissions, but does not grant them. Permissions must be provided when running the test command. When building robust applications, you often need to handle cases where permissions are denied, (for example you may want to write tests to check whether fallbacks have been set up correctly).

Consider a situation where you are reading from a file, you may want to offer a fallback value in the case that the function does not have read permission:

import { assertEquals } from "jsr:@std/assert";
import getFileText from "./main.ts";

Deno.test({
  name: "File reader gets text with permission",
  
  fn: async () => {
    const result = await getFileText();
    console.log(result);
    assertEquals(result, "the content of the file");
  },
});

Deno.test({
  name: "File reader falls back to error message without permission",
  permissions: { read: false },
  fn: async () => {
    const result = await getFileText();
    console.log(result);
    assertEquals(result, "oops don't have permission");
  },
});

The permissions object supports detailed configuration:

Deno.test({
  name: "permission configuration example",
  
  
  permissions: {
    read: ["./data", "./config"], 
    write: false, 
    net: ["example.com:443"], 
    env: ["API_KEY"], 
    run: false, 
    ffi: false, 
    hrtime: false, 
  },
  fn() {
    
  },
});

Remember that any permission not explicitly granted at the command line will be denied, regardless of what's specified in the test configuration.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4