For the past month and some change, actually might’ve been two months already (It takes a day to write a proof of concept, weeks to land it). I’ve been busy re-thinking Deno’s testing tools.

We’ve had a test runner since before I got involved and it worked just fine. But it was as barebones as you could make it so I rewrote all of it.

A new parallel runner

Our test runner was written in JavaScript, it worked but it was slow as it was a serial test runner that just merged all the tests into a single context and ran them one by one.

Meaning that if one test set a timeout for 60 seconds, or more realistically wait for a server response, nothing would until that has completed.

To deal with that, I rewrote the test runner from scratch in Rust so that I could have explicit control over the threading model.

Each test module now runs on its thread with its own scheduler and runtime.

Compilation and type-checking however is done ahead of time for the entire module graph, which makes it still fast.

deno test --jobs=4

Test times on our std test suite were cut in half from about 1 minute to 30 seconds for the entire test suite.

This has already landed and will ship in Deno version 1.10.

Per test case permissions

Internally we haven’t actually been using deno test for our own unit tests. Until now, I extended the test runner with per test case permissions letting us dog food and drop the ad-hoc test runner completely.

So your unit tests may now be defined with the permissions they require and they will be requested/revoked accordingly.

Deno.test({
  name: "write",
  permissions: {
    write: true,
  },
  async fn() {
    // ...
  },
});

Take note however, that if you run deno test with no permissions, any requests to get more permissions than what you started with will be denied.

This has already landed and will ship in Deno version 1.10.

#javascript #deno #typescript

Rewriting Deno’s Testing Tools
1.60 GEEK