TDD using Mocha and Karma

TDD using Mocha and Karma

Download from github

The following example shows how to setup a TDD enviroment using Mocha and Karma.

Mocha is a test framework running on browser or node.js, Karma is a test runner powered by the AngularJs team that allows you to run your test on multiple browsers.

Test libraries overview

The project combines mocha and karma with other libraries that improve the
syntax and the automation of your test. The following table describes all libraries used by project:

LIB Description
Grunt.js A task runner, in this demo it’s used to watch files changes and re-run the tests.
Chai & Sinon Syntax test libraries that add some features to your test, for example: mocking and chaining syntax(LINK)
Blanket.js JavaScript code coverage library that works both in-browser and with nodejs.
Phantom.js PhantomJS is a scripted, headless browser used for automating web page interaction

Setting up the project

Here’s the initial structure of the demo project :

initial-project-structure

initial-project-structure

  • “js” folder contains all .js files that we will test;
  • “test” folder contains all test files used by Mocha framework;
  • “package.json” gives some information about our project and also set the dependencies;

Installing project packages

Firstly, you need to specify all dev dependencies in your package.json :

Run the following command inside your project folder using administrator’s privilege:

npm install

the node_modules folder will be created, you can find all dependencies libraries inside it.

{
"name": "blog-tdd-using-mocha",
"version": "0.1.0",
"contributors": [
{
"name": "Samuele Resca"
}
],
"devDependencies": {
"chai": "^1.10.0",
"grunt": "^0.4.5",
"grunt-blanket-mocha": "^0.4.1",
"grunt-karma": "^0.12.1",
"karma": "^0.13.10",
"karma-chrome-launcher": "^0.2.0",
"karma-firefox-launcher": "^0.1.6",
"karma-html2js-preprocessor": "^0.1.0",
"karma-mocha": "^0.2.0",
"karma-phantomjs-launcher": "^0.2.1",
"load-grunt-tasks": "^3.1.0",
"mocha": "^2.3.3",
"phantomjs": "^1.9.18",
"sinon": "^1.12.2",
"sinon-chai": "^2.6.0"
}
}

Creating a new test case

Now you can add a simple test case to your project. Firstly, you need to create some files:

test-case-project

test-case-project

  • js\Telefilm.js: it’ll contain a simple class to test;
  • test\test-telefilm.js: it’ll contain all tests runned on Telefilm class;
  • test\index.html: it’s the entry point of our test;

js\Telefilm.js

The following code shows the structure of Telefilm class:

/*
*SIMPLE CLASS: describes telefilms
*/
var Telefilm = function (name, characters) {
this.name = name;
this.characters = characters;
};
Telefilm.prototype.getName = function () {
return this.name;
};
Telefilm.prototype.getCharacters = function () {
return this.characters;
};
Telefilm.prototype.addCharacter = function (character) {
return this.characters.push(character);
};

test\telefilm-test.js

The following code describes all test that will be run on the Telefilm class(all references are available here http://chaijs.com/api/bdd/

//FIX to the error : "expect is not defined"
var expect = chai.expect;
//describe Telefilm tests
describe('Telefilm', function() {
//Before the execution, initialize the object
before(function() {
this.telefilm = new Telefilm("Scrubs", ["John Dorian"]);
});
//LIst of tests
it('should be able to init new telefilm object', function() {
expect(this.telefilm).to.exist;
});
it('should be able to get characters', function() {
expect(this.telefilm.getCharacters()).to.ok;
});
it('should be able to get name', function() {
expect(this.telefilm.getName()).to.ok;
});
it('should be able to add character', function(){
var localTelefilm= new Telefilm("Scrubs",[]);
localTelefilm.addCharacter("Elliot Reid");
expect(localTelefilm.getCharacters().length).to.be.equals(1);
})
});

test/index.html

The following code describes the index page of the project, it’s used as application entry point and also to view test results on browser:

<meta charset="utf-8">
<link rel="stylesheet" href="../node_modules/grunt-blanket-mocha/node_modules/mocha/mocha.css">
<div id="mocha"><!--CONTENT OF TEST RESULTS --></div>
<div id="test" style="position: fixed; top: 0; left: -99999px;">
</div>
<!-- Testing dependencies -->
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/sinon-chai/lib/sinon-chai.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script src="../node_modules/grunt-blanket-mocha/node_modules/mocha/mocha.js"></script>
<script src="../node_modules/grunt-blanket-mocha/node_modules/blanket/dist/mocha/blanket_mocha.js"></script>
<script src="../node_modules/grunt-blanket-mocha/support/mocha-blanket.js"></script>
<!-- We will using BDD-style assertions. See Mocha documentation for more info -->
<script>mocha.setup('tdd');</script>
<!--Class to TEST-->
<script src="../js/Telefilm.js" data-cover></script>
<!--Test suite-->
<script src="telefilm-test.js"></script>
<script>
//Running on PHANTOMJS
if (window.PHANTOMJS) {
blanket.options("reporter", "../node_modules/grunt-blanket-mocha/support/grunt-reporter.js");
}
// Running on browser
else {
mocha.run();
}
</script>

Running tests on browser

Now you can test your code by opening index.html in your browser and see the results of tests:

test-results-project

test-results-project

Running tests on CLI

You can also configure Grunt to execute all tests using command-line:

    1. Add a “Gruntfile.js” in the root folder of your project;
    2. Configure the Gruntfile.js for the execution of mocha libraries:
//Grunt configuration
module.exports = function(grunt) {
'use strict';
require('load-grunt-tasks')(grunt);
grunt.initConfig({
//blanket_mocha CONFIGURATION
blanket_mocha: {
options: {
run: true,
reporter: 'Min',
// We want a minimum of 70% coverage
threshold: 70
},
files: {
src: '*.html'
}
}
});
//Register the task as DEFUALT
grunt.registerTask('default', ['blanket_mocha']);
};
    1. Execute the command:
      grunt

      in the root directory of your project;

The result is the execution of your test by using command-line behavior:

cli-tests-execution-project

cli-tests-execution-project

Running tests on multi behavior using Karma

This paragraph shows how to configure Karma and Grunt to run tests on multiple browsers and also on PhatomJS:

karma-config-project

karma-config-project

    1. You need to add karma enviroment to your Gruntfile.js config file, copy and paste the following snippet inside your grunt.initConfig object:
      https://gist.github.com/8434499843ba8e5016d9
    2. Add on the root folder karma.config.js file that is referenced by Gruntfile configuration:
      https://gist.github.com/041325a7b15d700fcceb
    3. Run the following command
      grunt karma:dev

      on your command line to execute your tests on Chrome, Firefox and PhantomJS;

requirejs-custom-define

requirejs-custom-define

final-result-tdd

Conclusion

This demo shows how to configure a simple tdd enviroment, you can find the full example on github. It also generates coverages report in this folder: test\coverage(for more informations about coverage follow this link.

Cheers 🙂