<script type="module">
import hugs from 'https://cdn.skypack.dev/hugs';
</script>
README
Hugs
Are you fatigued by any of the following?
Having to recreate your test environment each time you start up a new project
Indecision as to what assertion library to use?
Wanting to try out a different test framework but bored of learning yet another API that's almost the same but not quite
If you are, then you need Hugs!
Hugs is a module that allows you to write your nodejs tests in exactly the same way regardless of which test framework you choose to use.
It does this by wrapping those frameworks with a consistent API.
Currently, Hugs supports the following test frameworks:
Less typing means more time to hold the hand of your favourite person/pet/piñata instead!
However, if you really want to type more things, then you still can as Hugs does not mandate you have to use asserts.
Why?
Working on multiple projects and multiple teams, each with a different preference for a test runner (Jasmine or Mocha or TAP) and assertion framework (assert, expect or should) as well as test double frameworks (Jasmine or sinon), I got fatigued off with trying to remember which methods I should be calling.
All I want to do is set up a test and check that a value is equal to something. I was also bored with every new project I start to have to set up my test setup again. With hugs, I only need to install hugs and my testrunner e.g mocha.
Install
npm install hugs
Usage
Below is an example snippet but see /examples folder. It needs to be run with the corresponding test runner for the chosen framework.
gt; cd examples
gt; npm install
gt; npm run examples # runs examples under both mocha and tap
gt; npm run example:mocha # just run mocha example
gt; npm run example:tap # just run tap example
gt; npm run example:browser:mocha # just run browser mocha example
gt; npm run example:browser:jasmine # just run browser jasmine example
gt; npm run help # see all available npm run commands
let hugs = require('hugs');
// This example uses Mocha but the require call can be changed to 'tap'
// and without any other changes, the tests will work
let test = hugs(require('mocha'));
let spy = test.spy;
let assert = require('assert');
let oUT = { method: () => { } };
test(
'a test with a spy',
function (done) {
spy(oUT, 'method');
oUT.method(1, 2);
assert.callCount(oUT.method, 1); // sinon assertions exposed onto native asserts object
assert.calledWith(oUT.method, 1, 2);
done();
}
);
More examples can be seen in the /examples directory
Browser tests using Karma
There isn't a karma framework for hugs as it is only a wrapper around testing frameworks.
In order to configure karma to use hugs, configure karma as if you were using your framework of choice e.g mocha
and add the following lines to your files section before your tests files like so:
files: [
'index.js', // thing you are testing
'node_modules/hugs/src/exporters/sinon.js', // add this
'node_modules/hugs/src/targets/mocha.js', // add this and replace with tape or ava etc
'node_modules/hugs/src/index.js', // add this
'./test/index.js' // your test files.
],
See the /examples directory for a working example of a karma setup.
Ending tests
Different frameworks have slightly different mechanisms for ending tests with asynchronous code.
In order to have a test be written in the same way regardless of the test runner used, the done() method ends the test correctly depending on the given runner, calling either t.end(), done() or returning a promise.
For mocha users, this means that all tests need to be written as if it's an async test i.e done function is a parameter to the test. The --async-only flag for mocha cli is useful here.
AVA uses a different function altogether for async tests called test.cb. This meant adding a cb() function to the hugs interface which when using mocha or tap is actually the same method as their respective test() method.
Type
Lifecycle
async (callback)
async (promise)
AVA
signature
test.cb(’title’, (t) => {});
test(‘title’, () => {});
AVA
end
t.end();
return promise;
Mocha
signature
test(’title’, (done) => {});
test(‘title’, () => {});
Mocha
end
done();
return promise;
Tap
signature
test(’title’, (t) => {});
test(‘title’, (t) => {});
Tap
end
t.end();
return promise;
Hugs
signature
test.cb('title', (done) => {});
test('title', () => {});
Hugs
end
done();
return promise;
API
The test object returned from a hugs() call has the following API:
afterEach - Lifecycle method to register functions to execute after each test function