under-the-sun
v2.1.1
Published
A nothing-new-under-the-sun testing framework.
Downloads
77
Maintainers
Readme
Under the Sun
A nothing-new-under-the-sun testing framework.
This testing framework was inspired by the likes of uvu. It is intended to be as fast as possible yet as simple as possible.
Installation
npm install --save-dev under-the-sun
Usage
// examples/my.test.js
import assert from "node:assert"
import { test } from "under-the-sun"
test("something synchronous", () => {
assert(2 === 2, "2 should be 2")
})
test("something asynchronous", async () => {
await new Promise((resolve) => setTimeout(resolve, 1000))
assert(2 === 3, "2 should still be...2")
})
Execute tests in a directory via CLI:
npx under-the-sun examples
# or with alias
npx uts examples
Execute a filtered set of tests via CLI:
npx under-the-sun examples my asynchronous
In this case, only files in the examples
directory matching the regex my
will be considered.
Within those files, only tests whose descriptions match the regex asynchronous
will be executed.
Output
If you're unsatisfied with the default test reporter, you can override it.
// examples/test-reporter.js
import { setTestReporter } from "under-the-sun"
let failure = false
setTestReporter({
reportResult(testDescription, result) {
if (!result.error) {
// Do something about test success.
return
}
// Do something about test failure.
failure = true
console.error("FAIL: " + testDescription)
},
reportFinish() {
// Finalize the test run.
process.exit(failure ? 1 : 0)
},
})
Then just load this file alongside your tests:
uts -r examples/test-reporter.js examples
You can check out the default implementation for ideas.
CLI
The CLI is available via under-the-sun
or uts
.
uts [-p <file pattern>] [-i <ignore pattern>] [options] [<dir> [<file filter> [<description filter>]]]
Tests will be discovered automatically within the dir
directory.
Test files must match both file pattern
and file filter
to be executed.
Only tests within those files matching description filter
will be executed.
dir
is the current directory by default.file pattern
is/\.test\.(j|t)s$/
by default.ignore pattern
is/(^|\/)(node_modules($|\/)|\.)/
by default.- i.e. ignores
node_modules/
and dot files
- i.e. ignores
file filter
matches all files by default.description filter
matches all tests by default.
The file pattern
, file filter
, and description filter
CLI arguments
are passed directly to new RegExp(<pattern>)
.
If this seems confusing, start by just running uts
without any arguments.
Options
-r
/--require
- Load a module/script prior to test execution.-m
/--magic
- Maketest
anddefineTestGroup
globally available (no need to import/require).-s
/--serial
- Run tests sequentially rather than in parallel (default). Note: This is only intended as a debugging mechanism for when your tests are failing intermittently in parallel. Tests will not run in deterministic order even with this flag.
API
The library exposes a couple items for programmatic usage, but it's a small enough surface area it will just be easier for you to check them out on your own.
Examples
See the examples/ directory for specific working examples.
Why should I use this?
You probably don't want to. That being said, here are some aims of this library:
- Fast - This library pretty much just runs your JavaScript with as much
async
as possible. There's nothing fancy that could possibly slow things down. The only way make it meaningfully faster would be to use some alternative runtime (e.g. native code, process-level multithreading, caching). - Simple - This library doesn't provide a large API, so you're not tightly coupling your code to it in a way you can't easily change later.
I think this testing library is best for pure JavaScript/TypeScript Node.js libraries.
It's entirely possible someone has already written a library that does exactly what this does, better and with more features. I didn't find it though.
Why Not uvu?
You said this is like uvu. Why not just use that?
uvu doesn't do any kind of parallelization.
This library is still single-threaded, but it leverages the asynchronous concurrency built into JavaScript. This strategy is particularly helpful when you have a lot of tests with a significant I/O-bound component.
Why Not Jest?
You reference Jest's assertion library. Why not use it wholesale?
Jest is slow. It's pretty great to work with, but my experience has shown that it takes multiple seconds to run basic tests.
Why Not Vitest?
Vitest is focused on the web application ecosystem, not so much the Node library ecosystem.
Why Not AVA?
AVA has fallen out of favor, and I didn't want to waste time figuring out why. I'm guessing it has something to do with the opinionated-ness of it. Also, uvu's author claims that uvu is faster.
Why Not Mocha?
Mocha has also fallen out of favor. I've never used it, so maybe it's completely superior. ¯\(ツ)/¯
Why Not Tape?
Also never used it.
TypeScript
If you're using TypeScript, you may want to run your tests with some kind of TypeScript module loader like esbuild-register, @swc-node/register, or ts-node.
under-the-sun -r esbuild-register examples
under-the-sun -r @swc-node/register examples
under-the-sun -r ts-node/register examples
Assertions
This library does not ship with any assertions. You'll have to find your own.
Here are some options for you:
Node's assert
Module
Node's assert module comes with Node out of the box, so you don't have to install anything. It has a little bit of flexibility, but the reporting may not be as nice as you're used to.
import assert from "node:assert"
test("...", async () => {
assert(2 === 2, "2 should be 2")
assert.strictEqual(2, 3, "2 should still be 2")
assert.deepStrictEqual({}, {}, "More complex equality")
})
Jest's expect
Library
If you're coming from Jest, you may feel most comfortable picking up it's expect library.
import { expect } from "expect"
test("...", async () => {
expect(2).toBe(2)
expect({}).toStrictEqual({})
})
Chai
For a more traditional JS approach, you may want to use Chai.
import { assert } from "chai"
test("...", async () => {
assert.equal(2, 3, "2 should still be 2")
})
Watching
To run tests in watch mode, follow a strategy like uvu's.
{
"scripts": {
"test:watch": "watchlist src -- uts examples"
},
"devDependencies": {
"under-the-sun": "^1.0.0",
"watchlist": "^0.2.1"
}
}