http://tiny.cc/DLL
(and some other stuff)
If you have any front-end logic including jquery, ajax, promises, conditionals... etc.
These are untested and vulnerable areas of your application that you are not picked up in code coverage.
Mocha is a feature-rich JavaScript test framework for browser and Node.
const should = require('chai').should() let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; describe('Jam', function() { before(function() { //... }); context('Root', function() { it('Should be an object', function() { jam.should.be.an('object'); }); }); });
const assert = chai.assert; let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; suite('Jam', function() { setup(function() { //... }); suite('Root', function() { test('Is an object', function() { assert.isObject(jam, 'Jam is an object'); }); }); });
const expect = chai.expect; let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; suite('Jam'); test('Root', function() { expect(jam).to.be.an('object'); });
Chai is an assertion library.
Should allows you to chain result expectations whilst keeping the test assert clean and verbose.
const should = require('chai').should() let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; jam.should.be.an('object'); jam.should.have.property('types').with.lengthOf(4); jam.types.should.be.an('array'); jam.types.should.be.an('array').that.does.not.include('Peanut Butter');
Expect covers the same functionality but it does a lot of the chaining for you.
You pass your test object into the expect then chain your result expectations
const expect = chai.expect; let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; expect(jam).to.be.an('object'); expect(jam).to.have.property('types').with.lengthOf(4); expect(jam.types).to.be.an('array'); expect(jam.types).to.be.an('array').that.does.not.include('Peanut Butter');
Assert is not as chainable as Should or Expect but can handle more complex assertions and is more like the syntax found in other libraries
const assert = chai.assert; let jam = { types: [ 'Blueberry', 'Strawberry', 'Raspberry', 'Plum' ] }; assert.isObject(jam, 'Jam is an object'); assert.property(jam, 'types'); assert.isArray(jam.types, 'Jam types is an array'); assert.lengthOf(jam.types, 4, '4 items in array'); assert.doesNotHaveAnyKeys(jam.types, 'Peanut Butter');
Testing functions that return jquery elements, http request, data, asynchronous promises, ect... would be pretty difficult without stubs and spies, they allow us to force a response or watch interactions between objects
A test spy is a function that records arguments, return value, the value of this and exception thrown (if any) for all its calls. There are two types of spies: Some are anonymous functions, while others wrap methods that already exist in the system under test.
Test stubs are functions with pre-programmed behaviour.
They support the all of the Chai assertion library in addition to methods which can be used to alter the stub’s behaviour.
As spies, stubs can be either anonymous, or wrap existing functions. When wrapping an existing function with a stub, the original function is not called.
Plugins are lightweight bolt-on's for chai that help extend functionality without changing the assert chains.
Plugins give you continuity across your entire test suite.
Chai has a massive collection of 3rd party and vendor specific plugins.
chai.use(chaiHttp); chai.use(sinonChai);
Chai HTTP provides an interface for live integration testing web apps using Chai's chain-able asserts this you test server routes.
"A Promise is a proxy for a value not necessarily known when the promise is created.
It allows you to associate handlers with an asynchronous action's eventual success value or failure reason.
This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future."
function longRunningAddition (x, y) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(x + y); }, 200); }); };
let result = calculator.longRunningAddition(10, 5); result.should.equal(15);
Mocha comes with multiple built in reporters to change the console output of the test run
There are lots of tools for measuring code coverage in JavaScript they plug into your test framework of choice and output metrics on how many lines and blocks are covered with tests.
Let's look at Istanbul, Coverall, Wallaby