Skip to main content

Writing tests

yeet comes with a simple test framework: the yeet.test JS property to write tests and the yeet test CLI command to run them. Here's an example:

// symbol.test.js
import { assertEquals } from "yeet:assert";
import { demangle } from "yeet:sym";

const shortName = (symbol) => demangle(symbol).split("::").at(-1);

yeet.test("shortName", () => {
assertEquals(shortName("_ZN4core3fmt5write17h05af8562b5e29e21E"), "write");
assertEquals(shortName("SSL_read"), "SSL_read");
});

If we run yeet test in the same directory, it finds symbol.test.js by the .test.js suffix:

running 1 test from ./symbol.test.js
shortName ... FAILED (1ms)

ERRORS

shortName => ./symbol.test.js
error: TypeError: Cannot read properties of null (reading 'split')
at shortName (/tmp/demo/symbol.test.js:4:47)
at Object.fn (/tmp/demo/symbol.test.js:8:16)

FAILURES

shortName => ./symbol.test.js

FAILED | 0 passed | 1 failed (9ms)

error: Test failed

Oops! We need to fix a null pointer bug:

-const shortName = (symbol) => demangle(symbol).split("::").at(-1);
+const shortName = (symbol) => (demangle(symbol) ?? symbol).split("::").at(-1);

And run yeet test again:

running 1 test from ./symbol.test.js
shortName ... ok (0ms)

ok | 1 passed | 0 failed (7ms)

(If you have used Deno's testing tools, much of this will look familiar: our API overlaps a lot with Deno.test and deno test.)

Inline tests​

The yeet testing API makes it possible to write tests inline, alongside the code being tested, without creating dedicated test modules. This can be convenient.

To facilitate this, yeet.test is present as a stub even in production environments.

// main.js
import { assertEquals } from "yeet:assert";

const formatUptime = (seconds) => {
const d = Math.floor(seconds / 86400);
const h = Math.floor(seconds / 3600) % 24;
const m = Math.floor(seconds / 60) % 60;
return `${d}d ${h}h ${m}m`;
};

yeet.test("formatUptime", () => assertEquals(formatUptime(90061), "1d 1h 1m"));

const main = async () => {
const { data } = await yeet.graph.query(`{ host { uptime { uptime } } }`);
console.log(formatUptime(data.host.uptime.uptime));
}
if (import.meta.main) main();

Under yeet test, import.meta.main is false, so main does not run. In this example, main.js needs to be passed to yeet test explicitly.

yeet test main.js \
&& echo "Test passed! Running the script..." \
&& yeet run main.js

Reference​