instatest v0.3.3
instatest
Super lightweight framework for instantaneous unit testing of JavaScript packages.
Installation
npm install instatestUsage
Insert a test into your code via
import * as insta from "instatest";
insta.beginUnit("my-package", "my-file");
insta.test("My test", () => {
insta.assert(2 + 2 == 4, "Test addition");
});
insta.endUnit("my-package", "my-file");Running
npx instatest srcwill search the src directory for all .js and .mjs files and run them. Afterwards, it will execute all found tests in the same order as they were found and display a summary of the result.
Note that only tests are executed which are in units with the same package name as the current package.
Configuration
You can pass a list of files and directories to instatest. Directories are searched recursively for .js and .mjs files. For example, via
npx instatest index.js testyou run index.js and all .js and .mjs files located in the test directory or one of its subdirectories.
Of course, you can install instatest also as a script in your package.json file via
...
"scripts": {
"test": "instatest index.js test",
...
},
...and then run it via
npm run testNote that instatest assumes that your package is configured to use ES modules, so your package.json should also include
...
"type": "module",
...Tests
The following assumes that you have imported the instatest module via
import * as insta from "instatest";The statement insta.test(descr, fn) executes the tests in function fn and groups the results together under the label descr. The function fn can be an async function.
Tests can be nested, for example:
insta.test("My Test", () => {
insta.test("Addition", () => {
insta.assertEq(2 + 2, 4);
insta.assertEq(7 + 3, 10);
insta.assertThrow(() => { throw 42; });
});
insta.test("Multiplication", () => {
insta.assertEq(2 * 2, 4);
insta.assertEq(7 * 3, 21);
});
insta.assertEq(1/0, Number.POSITIVE_INFINITY, "Division");
});Assert
Asserts must be done from within a surrounding test. The following variants are available:
assert(cond, descr)orassertTrue(cond, descr): Asserts thatcondis strictly equal totrue.assertFalse(cond, descr): Asserts thatcondis strictly equal tofalse.assertEq(x, y, descr): Asserts that valuesxandyare equal. Equality is implemented viaeq, which is basically strict equality for primitive types, and deep equality for objects.assertNEq(x, y, descr): Asserts that valuesxandyare unequal, i.e. that!eq(x, y).assertThrow(fn, descr): Asserts that executing the functionfnasynchronously results in an exception.assertLazy(fn, descr): Asserts that asynchronous execution of the functionfnresults in a value strictly equal totrue.
Units
Just as asserts live inside of tests, tests live inside of units. A unit has a package name, and can furthermore carry a list of arbitrary string qualifiers. Units are necessary so that testing can skip those tests which do not belong to the current package, but just to a package it depends on. A unit is started via
insta.beginUnit("package", ...);and ends with
insta.endUnit("package", ...);where the package name and qualifiers in beginUnit and endUnit must be the same, and unique compared to other units.
Instantaneous Testing
You can store your tests separately from the modules you are testing, or you can alternatively embed them directly in your modules.
Directly embedding tests is encouraged, and we call it instantaneous testing. It does not come with significant performance penalties, because simply loading a module which contains an insta.test statement will not execute the test; rather it will just schedule it for execution. The scheduled tests can be executed manually via
insta.runTests(unitFilter);Here unitFilter is a function that decides whether a particular test unit [packageName, q0, q1, ...] should be run. You can also pass a string packageName, or a prefix
[packageName, q0, q1, ...] instead of a function.
By default the instatest CLI will use the current package name as a filter.
To configure a list of packages, for example package1, package2 and package3,
add the following to your package.json configuration file:
...
"config": {
"instatest": {
"packages": "package1; package2; package3"
},
...
},
...Running Your Tests In The Browser
By passing the --browser option to instatest, instead of running the tests directly, it will generate a directory instatest-browser, for example:
npx instatest src --browserTo make use of it, you should have webpack and http-server installed:
npm install --save-dev webpack webpack-cli http-serverThen first run webpack via
npx webpack --config=instatest-browser/webpack.config.jsIf that step was successful, you can now run the tests in the browser:
npx http-server -c-1 instatest-browser -oAssuming you have already registered instatest in your package.json as a test script, you can streamline this by adding a test-browser script to your package.json:
...
"scripts": {
"test": "instatest src",
"pretest-browser": "npm run test -- --browser && npx webpack --config=instatest-browser/webpack.config.js",
"test-browser": "npx http-server -c-1 instatest-browser -o",
...
},
...Now calling npm run test-browser will first freshly generate the instatest-browser directory, run webpack, and then start up a local http-server and a browser running your tests.
Lockdown
Instatest encourages locking down your modules and APIs as much as possible. In particular, you can lock down instatest itself and the basic Object API via
insta.lockdown();After executing above statement, the following will throw an error:
insta.assert.hey = "doesn't really make sense";It also switches off the possibility to manipulate Object:
Object.really = "now why would you want to do that?";will also throw an error.
To run your tests via npm in lockdown mode, configure instatest via the package.json of your package as follows:
...
"config": {
"instatest": {
"lockdown": true
},
...
},
...You can also pass --lockdown or --lockdown=true to instatest as an option.
There are two utility functions to help you lock down your own APIs:
insta.lockClass(cls)locks down the classclsinsta.lockFunc(fn)locks down the functionfn
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago