Testesterone
Strengthen your clientside applications with in-browser tests
- No need to mock
window
and browser APIs - No global scope pollution
- Output is printed to the console
- Async tests are supported
- Minimal
expect
-style assertions are built-in
Installation
npm install testesterone -D
Example
index.html
Hello!
app.js
var h1 = document;var nameInput = document; nameInput { h1textContent = 'Hello ' + nameInputvalue;};
app.test.js
var test = ;var h1 = document;var nameInput = document;;

Overview
Testesterone was built to make it simple to test clientside code within a browser. This means there is no need for headless browsers, or for simulating a browser environment from within node.js.
In addition, all test results appear in the console, not in any sort of ui on the page itself. This allows you to run assertions against the actual contents of the DOM within your tests.
API
test(label, callback)
The test
function creates a group in the console that contains your assertions.
;

test
is the equivalent to Mocha's describe
function.
test
s can also be nested, which allows for grouping. For example:
;

Note that the outermost
test()
's return value is a function that must be called! Without doing this, your tests will not be run. ie. You should do this:test(label, callback)()
Of course, this is not very useful without assertions to run.
it(label, callback)
Assertions are run within the context of a test case defined by an it
function.
;

it(label)
Produces an informational label that does not run any assertions. This can be a placeholder for some future test that needs to be written, or for some functionality that has yet to be implemented.
it(label, callback)
Calls the callback and runs its assertions. If no assertion error occurred, then the test will pass.
;

This test obviously fails. We can expand the failing test case to see the reason for the failure. And in fact, this can be further expanded to reveal the full stack trace if desired.

Now let's make the test pass:
;

Or for a more complete example:
;

All the tests pass, but one. The last test fails because x
is not strictly equal to the new array [1, 2, 3, 4]
although they are structurally the same. The expect
function comes with a built-in deep equality detector for such situations. Changing expect(x).to.equal([1, 2, 3, 4]);
to expect(x).to.deep.equal([1, 2, 3, 4]);
will solve this problem.

expect()
Expect has a very minimal assertion API. It has the following methods:
expect(x).equal(y)
: asserts thatx === y
expect(x).not.equal(y)
: asserts thatx !== y
expect(x).deep.equal(y)
: asserts thatdeepEquals(x, y)
expect(x).not.deep.equal(y)
: asserts that!(deepEquals(x, y))
expect(x).explode()
: asserts thatx()
throws an errorexpect(x).not.explode()
: asserts thatx()
does not throw
All of the methods can be prefixed with to
so that they read like spoken english. For example:
to;
Unlike assertion libraries like Chai, which include many methods that allow code like the following to be written: expect('foo bar').to.include('bar');
, this library opts instead for a minimal api so that you do not have to check the documentation to know what is and is not supported by the assertion library. Anything that could be tested with those helper methods can be tested using the to.equal()
interface. For instance, the previous example could be written as: expect('foo bar'.includes('bar')).to.equal(true);
or even:
to;
Async support
Async functions can be easily tested with testesterone. As a bonus, their executions will be timed. In order to test any asynchronous code, pass a second parameter to the it()
function. That second parameter will be a callback that should be called when the asynchronous code is finished executing.
;

All tests, including asynchronous tests, will be run sequentially.
This works with promises as well. The equivalent promise to the above function would be:
;
If done
is not called within 2 seconds of the test being run, the test will automatically fail. This timeout can be configured by setting test.timeout
to any number of milliseconds prior to running a test. The timeout can even be modified on a test-by-test basis.
For example:
testtimeout = 9000; // set the max time a single test can run to 9 seconds ;
And it should be noted that tests do not have to be asynchronous in order for the done
callback to be useful. For heavy functions that may take a while to compute, the timer provided by calling done()
may be nice to have. It relies internally on performance.now()
.
;
Shorthand
Assertions can be written in a more terse syntax if desired:
;
Theme support
Testesterone also works with the dark theme in Chrome's developer console:

Caveats
- Browsers besides Google Chrome are not officially supported at this time. Many do not have the same degree of support for the
console
methods, which this library makes use of. - Tests must be run within a browser context. This wasn't intended to be used in node.js.
- The
expect
interface relies internally onconsole.assert
and does not throw an error if an assertion fails. For this reason, external assertion libraries like Chai would be difficult to integrate. - You must have a single call to
test(label, callback)()
at the outermost level. Multiple tests can be side-by-side within the callback, but there can only be one root-level call totest
.