Deno comes with it's own minimal testing framework built-in which is super handy for getting off the ground with testing.
import add from "./add.ts";
import { expect } from "https://deno.land/x/expect@v0.2.1/mod.ts";
Deno.test("should add two numbers", () => {
expect(add(1, 2)).toEqual(3);
});
However, if you are used to using popular testing frameworks such as Jest, Mocha etc. then you are out of luck. The Deno testing API doesn't current support mainly of the rich testing features you are used to such as beforeEach
hooks, describe
blocks etc.
So while Deno.test
is great for small PoCs and getting started, it might not be what you're looking for as your functionality becomes more complicated and evolved. It also isn't the easiest setup to convert tests to if you are looking to migrate an existing Node project.
This is where Deno's ability to run ESM browser code natively comes into it's own. The likes of Mocha have browser support meaning that you can immediately pull Mocha into your Deno projects right now and it'll work as you're used to! π
Here's a simple example to get you started:
/**
* First we import Mocha and it's type definitions.
*/
// @deno-types="https://unpkg.com/@types/mocha@7.0.2/index.d.ts"
import "https://unpkg.com/mocha@7.2.0/mocha.js";
/**
* Here I'm using the Deno `expect` library, but you can use
* any assertion library - including Deno's std testing library.
* See: https://deno.land/std/testing
*/
import { expect } from "https://deno.land/x/expect@v0.2.1/mod.ts";
/**
* Callback on completion of tests to ensure Deno exits with
* the appropriate status code.
*/
function onCompleted(failures: number): void {
if (failures > 0) {
Deno.exit(1);
} else {
Deno.exit(0);
}
}
/**
* Browser based Mocha requires `window.location` to exist.
*/
(window as any).location = new URL("http://localhost:0");
/**
* In order to use `describe` etc. we need to set Mocha to `bdd`
* mode.
*
* We also need to set the reporter to `spec` (though other options
* are available) to prevent Mocha using the default browser reporter
* which requires access to a DOM.
*/
mocha.setup({ ui: "bdd", reporter: "spec" });
/**
* Ensure there are no leaks in our tests.
*/
mocha.checkLeaks();
/**
* Our example function under test
*/
function add(a: number, b: number): number {
return a + b;
}
/**
* We write our tests as usual!
*/
describe("add", () => {
it("should add two positive numbers correctly", () => {
expect(add(2, 3)).toEqual(5);
});
});
/**
* And finally we run our tests, passing the onCompleted function
* hook and setting some globals.
*/
mocha.run(onCompleted).globals(["onerror"])
And that's it! You can now run the file and you should see something like:
$ deno run ./mocha.ts
This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.
add
β should add two positive numbers correctly
1 passing (3ms)
There's a small warning due to the most recent version of Mocha making use of buffer v5 which requires full typed array (Uint8Array) support which Deno does not yet have, but otherwise our test has run and passed as expected!
We can check that it fails as well by making the following change:
describe("add", () => {
it("should add two positive numbers correctly", () => {
expect(add(2, 3)).toEqual(10); // Should fail!
});
});
And the result is:
$ deno run ./mocha.ts
This browser lacks typed array (Uint8Array) support which is required by `buffer` v5.x. Use `buffer` v4.x if you require old browser support.
add
1) should add two positive numbers correctly
0 passing (47ms)
1 failing
1) add
should add two positive numbers correctly:
AssertionError: expect(actual).toEqual(expected)
- 5
+ 10
at applyMatcher (https://deno.land/x/expect@v0.2.1/expect.ts:102:23)
at Proxy.<anonymous> (https://deno.land/x/expect@v0.2.1/expect.ts:109:15)
And it's failed as expected π
You're not just limited to Mocha, you can use exactly the same techniques to pull in Chai, Sinon and any other library that has browser support. If you want to see an example of how this is used in a large Deno project, check out denolib/typeorm.
How are you testing your Deno code? Have any suggestions to improve test setup that are worth sharing? Share your comments, questions and ideas in the section below - great to hear what everyone is doing!
Happy testing! π¦ π
Top comments (8)
Hey Craig,
Thought you might be interested, you inspired me to write a library for this. Built out a super-simple CLI for it, too, and using for running deno tests on cbor-redux.
github.com/ahuggins-nhs/deno_mocha
Istanbul's nyc is probably next, if I can crack that or you know anyone who has.
This is awesome! Nice one π
Nice to see the successful transplant of a big name browser utility!
Thanks so much, this is very useful. With powerful tests there's almost no need for a debugger!
any info on the use of code coverage in deno?
Hey @ynwd π
I'm not 100% sure r.e. code coverage using Mocha - most people tend to use Istanbul for coverage with Mocha, but I'm not familiar with a browser-only compatible setup (i.e. no Node) - there appears to be an issue with some useful details on the Instanbul GitHub Issues with may be of use? There may be other 3rd party libs that can perform in browser code coverage that are compatible with Mocha which would then likely also work with Deno.
With respect to Deno itself, from what I've heard code coverage is currently being worked on - check out Deno GitHub Issue. Some PoCs have been done already (e.g. see here). There is also this PR which is still in draft and slated for the Deno 1.4.0 release which will add a
--coverage
flag to thedeno test
command so fingers crossed built-in coverage support may be released over the next few months.deno test --coverage --unstable
:)))deno.land/manual@v1.4.4/testing#te...