1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-29 02:29:06 -05:00
denoland-deno/testing/README.md

218 lines
5.7 KiB
Markdown
Raw Normal View History

2019-01-06 14:19:15 -05:00
# Testing
2019-01-03 14:16:15 -05:00
2019-01-15 21:57:40 -05:00
This module provides a few basic utilities to make testing easier and
consistent in Deno.
2019-01-03 14:16:15 -05:00
## Usage
2019-01-15 21:57:40 -05:00
The module exports a `test` function which is the test harness in Deno. It
accepts either a function (including async functions) or an object which
contains a `name` property and a `fn` property. When running tests and
outputting the results, the name of the past function is used, or if the
2019-03-18 11:08:01 -04:00
object is passed, the `name` property is used to identify the test. If the assertion is false an `AssertionError` will be thrown.
2019-01-15 21:57:40 -05:00
2019-03-06 16:39:50 -05:00
Asserts are exposed in `testing/asserts.ts` module.
2019-01-15 21:57:40 -05:00
- `equal()` - Deep comparision function, where `actual` and `expected` are
2019-03-06 16:39:50 -05:00
compared deeply, and if they vary, `equal` returns `false`.
2019-01-15 21:57:40 -05:00
- `assert()` - Expects a boolean value, throws if the value is `false`.
- `assertEquals()` - Uses the `equal` comparison and throws if the `actual` and
2019-01-15 21:57:40 -05:00
`expected` are not equal.
2019-03-18 11:08:01 -04:00
- `assertNotEquals()` - Uses the `equal` comparison and throws if the `actual` and
`expected` are equal.
2019-03-06 16:39:50 -05:00
- `assertStrictEq()` - Compares `actual` and `expected` strictly, therefore
2019-01-15 21:57:40 -05:00
for non-primitives the values must reference the same instance.
2019-03-18 11:08:01 -04:00
- `assertStrContains()` - Make an assertion that `actual` contains `expected`.
- `assertMatch()` - Make an assertion that `actual` match RegExp `expected`.
- `assertArrayContains()` - Make an assertion that `actual` array contains the `expected` values.
2019-03-06 16:39:50 -05:00
- `assertThrows()` - Expects the passed `fn` to throw. If `fn` does not throw,
2019-01-15 21:57:40 -05:00
this function does. Also compares any errors thrown to an optional expected
`Error` class and checks that the error `.message` includes an optional
string.
2019-03-06 16:39:50 -05:00
- `assertThrowsAsync()` - Expects the passed `fn` to be async and throw (or
2019-01-22 01:15:25 -05:00
return a `Promise` that rejects). If the `fn` does not throw or reject, this
function will throw asynchronously. Also compares any errors thrown to an
optional expected `Error` class and checks that the error `.message` includes
an optional string.
2019-03-18 11:08:01 -04:00
- `unimplemented()` - Use this to stub out methods that will throw when invoked
- `unreachable()` - Used to assert unreachable code
2019-01-15 21:57:40 -05:00
`runTests()` executes the declared tests. It accepts a `RunOptions` parameter:
- parallel : Execute tests in a parallel way.
- exitOnFail : if one test fails, test will throw an error and stop the tests. If not all tests will be processed.
2019-01-29 15:10:40 -05:00
2019-01-15 21:57:40 -05:00
Basic usage:
2019-01-03 14:16:15 -05:00
```ts
2019-03-06 16:39:50 -05:00
import { runTests, test } from "https://deno.land/std/testing/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
2019-01-03 14:16:15 -05:00
test({
2019-01-06 14:19:15 -05:00
name: "testing example",
2019-01-03 14:16:15 -05:00
fn() {
assertEquals("world", "world"));
assertEquals({ hello: "world" }, { hello: "world" }));
2019-01-06 14:19:15 -05:00
}
2019-01-03 14:16:15 -05:00
});
2019-01-29 15:10:40 -05:00
runTests();
2019-01-03 14:16:15 -05:00
```
Short syntax (named function instead of object):
2019-01-06 14:19:15 -05:00
2019-01-03 14:16:15 -05:00
```ts
test(function example() {
assertEquals("world", "world"));
assertEquals({ hello: "world" }, { hello: "world" }));
2019-01-15 21:57:40 -05:00
});
```
2019-03-06 16:39:50 -05:00
Using `assertStrictEq()`:
2019-01-15 21:57:40 -05:00
```ts
test(function isStrictlyEqual() {
const a = {};
const b = a;
2019-03-06 16:39:50 -05:00
assertStrictEq(a, b);
2019-01-15 21:57:40 -05:00
});
// This test fails
test(function isNotStrictlyEqual() {
const a = {};
const b = {};
2019-03-06 16:39:50 -05:00
assertStrictEq(a, b);
2019-01-15 21:57:40 -05:00
});
```
2019-03-06 16:39:50 -05:00
Using `assertThrows()`:
2019-01-15 21:57:40 -05:00
```ts
test(function doesThrow() {
2019-03-06 16:39:50 -05:00
assertThrows(() => {
2019-01-15 21:57:40 -05:00
throw new TypeError("hello world!");
});
2019-03-06 16:39:50 -05:00
assertThrows(() => {
2019-01-15 21:57:40 -05:00
throw new TypeError("hello world!");
}, TypeError);
2019-03-06 16:39:50 -05:00
assertThrows(
2019-01-15 21:57:40 -05:00
() => {
throw new TypeError("hello world!");
},
TypeError,
"hello"
);
});
// This test will not pass
test(function fails() {
2019-03-06 16:39:50 -05:00
assertThrows(() => {
2019-01-15 21:57:40 -05:00
console.log("Hello world");
});
2019-01-03 14:16:15 -05:00
});
2019-01-04 05:09:42 -05:00
```
2019-01-22 01:15:25 -05:00
2019-03-06 16:39:50 -05:00
Using `assertThrowsAsync()`:
2019-01-22 01:15:25 -05:00
```ts
test(async function doesThrow() {
await assertThrowsAsync(async () => {
2019-01-22 01:15:25 -05:00
throw new TypeError("hello world!");
});
await assertThrowsAsync(async () => {
2019-01-22 01:15:25 -05:00
throw new TypeError("hello world!");
}, TypeError);
await assertThrowsAsync(
2019-01-22 01:15:25 -05:00
async () => {
throw new TypeError("hello world!");
},
TypeError,
"hello"
);
await assertThrowsAsync(async () => {
2019-01-22 01:15:25 -05:00
return Promise.reject(new Error());
});
});
// This test will not pass
test(async function fails() {
await assertThrowsAsync(async () => {
2019-01-22 01:15:25 -05:00
console.log("Hello world");
});
});
```
2019-03-11 14:21:13 -04:00
### Benching Usage
Basic usage:
```ts
import { runBenchmarks, bench } from "https://deno.land/std/testing/bench.ts";
bench(function forIncrementX1e9(b) {
b.start();
for (let i = 0; i < 1e9; i++);
b.stop();
});
runBenchmarks();
```
Averaging execution time over multiple runs:
```ts
bench({
name: "runs100ForIncrementX1e6",
runs: 100,
func(b) {
b.start();
for (let i = 0; i < 1e6; i++);
b.stop();
}
});
```
#### Benching API
##### `bench(benchmark: BenchmarkDefinition | BenchmarkFunction): void`
Registers a benchmark that will be run once `runBenchmarks` is called.
##### `runBenchmarks(opts?: BenchmarkRunOptions): Promise<void>`
Runs all registered benchmarks serially. Filtering can be applied by setting
`BenchmarkRunOptions.only` and/or `BenchmarkRunOptions.skip` to regular expressions matching benchmark names.
##### `runIfMain(meta: ImportMeta, opts?: BenchmarkRunOptions): Promise<void>`
Runs specified benchmarks if the enclosing script is main.
##### Other exports
```ts
/** Provides methods for starting and stopping a benchmark clock. */
export interface BenchmarkTimer {
start: () => void;
stop: () => void;
}
/** Defines a benchmark through a named function. */
export interface BenchmarkFunction {
(b: BenchmarkTimer): void | Promise<void>;
name: string;
}
/** Defines a benchmark definition with configurable runs. */
export interface BenchmarkDefinition {
func: BenchmarkFunction;
name: string;
runs?: number;
}
/** Defines runBenchmark's run constraints by matching benchmark names. */
export interface BenchmarkRunOptions {
only?: RegExp;
skip?: RegExp;
}
```