SlideShare a Scribd company logo
Testing NodeJS
(with Mocha, Should, Sinon, & JSCoverage)
Michael Lilley
michael.lilley@gmail.com
Melbourne NodeJS Meetup Group
Wednesday, 28 August 2013
Accompanying Sample Repository - https://github.com/mlilley/testing_nodejs_with_mocha.git
Which Framework?
• Popular
• Decent high level features
• Highly configurable to suit many tastes
• Been around for almost 2 years
• Can run in the browser also
Why Mocha?
Setting Up
1. Install mocha module
$ npm install mocha
2. Choose and install your assertion library (we’ll use should)
$ npm install should
3. Create a directory for your tests
$ mkdir test
Setting Up
REPORTER = dot
test:
@NODE_ENV=test ./node_modules/.bin/mocha
--reporter $(REPORTER) 
test-w:
@NODE_ENV=test ./node_modules/.bin/mocha 
--reporter $(REPORTER) 
--watch
.PHONY: test test-w
4. Create your Makefile
Remember the tabs!
Setting Up
{
...
"scripts": {
"test": "make test"
}
...
}
5. Configure package.json
Code To Be Tested
var Adder = exports.Adder = function() {};
Adder.prototype.add = function(a, b) {
return a + b;
};
sync_adder.js
var Adder = exports.Adder = function() {};
Adder.prototype.add = function(a, b, callback) {
setTimeout(function() {
callback(a + b);
}, 100);
};
async_adder.js
Tests - Synchronous
var should = require('should');
var Adder = require('../sync_adder').Adder;
describe('Synchronous Adder', function() {
describe('add()', function() {
it('should return 3 when adding 1 and 2', function() {
var adder = new Adder();
adder.add(1, 2).should.equal(3);
});
});
});
test/sync_adder.js
• NB: or use mocha option ‘--require’ to automatically require common deps (ie: Should)
Tests - Asynchronous
test/async_adder.js
• If done() not called, test fails • Default timeout is 2,000 ms
• Adjust with this.timeout(x)
var should = require('should');
var Adder = require('../async_adder').Adder;
describe('Asynchronous Adder', function() {
describe('add()', function() {
it('should callback with 3 when adding 1 and 2', function(done) {
var adder = new Adder();
adder.add(1, 2, function(result) {
result.should.equal(3);
done();
});
});
});
});
Hooks
• before(fn), after(fn), beforeEach(fn), afterEach(fn)
• Use within describe() at any nesting level
• Use outside describe() for global scope
• after/afterEach run on test fail too (unless --bail)
Should DSL
x.should.be.ok
x.should.be.true
x.should.be.false
x.should.be.empty
x.should.be.within(y,z)
x.should.be.a(y)
x.should.be[.an].instanceOf(y)
x.should.be.above(n)
x.should.be.below(n)
x.should.eql(y)
x.should.equal(y)
x.should.match(/y/)
x.should.have.length(y)
x.should.have.property(prop[, val])
x.should.have.ownProperty(prop[, val])
x.should.have.status(code)
x.should.have.header(field[, val])
x.should.include(y)
x.should.throw([string|/regexp/])
// truthiness
// === true
// === false
// length == 0
// range
// typeof
// instanceOf
// > val
// < val
// ==
// ===
// regexp match
// .length == y
// prop exists
// prop exists (immediate)
// .statusCode == y
// .header with field & val
// x.indexOf(y) != -1
// thrown exception
Negation:
• x.should.not.be.ok
Chaining:
• x.should.be.a(‘string’).and.have.length(5)
Implementation:
• should added to Object as property
• Therefore x must not be null or undefined
• Use should.exist(x) to test first where
needed.
Running Tests
• Run your tests
$ make test
or $ npm test
or $ ./node_modules/.bin/mocha <options> <path|files>
• Run your tests automatically when files change
$ make test-w
• Run multiple test suites / partial suite / specific tests
– Specify desired file or directory on cmd line
– Use “tagging” and --grep feature
• Tag test names with some unique string (ie “@slow” or “#API” or “APP”)
• Pass cmd line option --grep <pattern>
• Run Mocha programatically for more control
Mocha Configurability
• Change assertion library (require(…))
– Should, expect.js, Chai, Expectations, better-assert, Node’s assert lib, etc
• Change interface (--ui flag)
– for BDD style: describe, it, before, after, beforeEach, afterEach.
– for TDD style: suite, test, setup, teardown.
– others
• Change output Reporter (--reporter flag)
– For different styles of terminal output
– For output of docs (html, xml, documentation, …)
– For feeding into other programs (test coverage, …)
• … and more …
Sinon
• Sinon
– APIs for spies, stubs, mocks, and utils
– Framework agnostic
– To use:
• $ npm install sinon
• var sinon = require(‘sinon’);
– Don’t include via --require because need access to exports
Test Coverage
1. Install node-jscoverage binary
$ git clone https://github.com/visionmedia/node-jscoverage.git
$ ./configure && make && make install
2. Adjust Makefile to:
– invoke jscoverage on source to produce instrumented version
– run mocha on instrumented source with html-cov reporter to ourput coverage report.
...
test-cov: lib-cov
@MYPROJ_COVERAGE=1 $(MAKE) test REPORTER=html-cov > coverage.html
lib-cov:
@jscoverage lib lib-cov
...
Test Coverage
3. Adjust project structure (see example repo)
– index.js conditionally requires normal or instrumented source based on env var set in
makefile
module.exports = process.env.MYPROJ_COVERAGE
? require('./lib-cov/myproj')
: require('./lib/myproj')
4. Run it
$ make test-cov
For more…
• Mocha - http://visionmedia.github.io/mocha/
• Mocha Wiki - https://github.com/visionmedia/mocha/wiki
• Should - https://github.com/visionmedia/should.js/
• Sinon - http://sinonjs.org/
• Node-JSCoverage - https://github.com/visionmedia/node-jscoverage
Ad

Recommended

JavaScript Testing: Mocha + Chai
JavaScript Testing: Mocha + Chai
James Cryer
 
Unit tests in node.js
Unit tests in node.js
Rotem Tamir
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
Michał Pierzchała
 
Testing JavaScript Applications
Testing JavaScript Applications
The Rolling Scopes
 
[React Native Tutorial] Lecture 3: More on ES6/ES2015
[React Native Tutorial] Lecture 3: More on ES6/ES2015
Kobkrit Viriyayudhakorn
 
Running BabelJS on Windows (Try ES6 on Windows)
Running BabelJS on Windows (Try ES6 on Windows)
Kobkrit Viriyayudhakorn
 
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
Beautiful code instead of callback hell using ES6 Generators, Koa, Bluebird (...
andreaslubbe
 
ECMAScript 6 and the Node Driver
ECMAScript 6 and the Node Driver
MongoDB
 
Introduction to node.js
Introduction to node.js
jacekbecela
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
Run Node Run
Run Node Run
Kevin Swiber
 
Node js presentation
Node js presentation
martincabrera
 
Introduction to Node.js: What, why and how?
Introduction to Node.js: What, why and how?
Christian Joudrey
 
Node ppt
Node ppt
Tamil Selvan R S
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
.toster
 
Celery introduction
Celery introduction
Ionel Mărieș Cristian
 
Performance and stability testing \w Gatling
Performance and stability testing \w Gatling
Dmitry Vrublevsky
 
ECMAScript 6
ECMAScript 6
偉格 高
 
GPerf Using Jesque
GPerf Using Jesque
ctoestreich
 
Spock: Test Well and Prosper
Spock: Test Well and Prosper
Ken Kousen
 
Background processing with Resque
Background processing with Resque
Nicolas Blanco
 
Javascript asynchronous
Javascript asynchronous
kang taehun
 
Node.js System: The Approach
Node.js System: The Approach
Haci Murat Yaman
 
Node child process
Node child process
LearningTech
 
Debugging & profiling node.js
Debugging & profiling node.js
tomasperezv
 
Node.js - Best practices
Node.js - Best practices
Felix Geisendörfer
 
Intro to Node.js (v1)
Intro to Node.js (v1)
Chris Cowan
 
Celery: The Distributed Task Queue
Celery: The Distributed Task Queue
Richard Leland
 
Testing Javascript Apps with Mocha and Chai
Testing Javascript Apps with Mocha and Chai
Andrew Winder
 
Testing Javascript with Jasmine
Testing Javascript with Jasmine
Tim Tyrrell
 

More Related Content

What's hot (20)

Introduction to node.js
Introduction to node.js
jacekbecela
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
Run Node Run
Run Node Run
Kevin Swiber
 
Node js presentation
Node js presentation
martincabrera
 
Introduction to Node.js: What, why and how?
Introduction to Node.js: What, why and how?
Christian Joudrey
 
Node ppt
Node ppt
Tamil Selvan R S
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
.toster
 
Celery introduction
Celery introduction
Ionel Mărieș Cristian
 
Performance and stability testing \w Gatling
Performance and stability testing \w Gatling
Dmitry Vrublevsky
 
ECMAScript 6
ECMAScript 6
偉格 高
 
GPerf Using Jesque
GPerf Using Jesque
ctoestreich
 
Spock: Test Well and Prosper
Spock: Test Well and Prosper
Ken Kousen
 
Background processing with Resque
Background processing with Resque
Nicolas Blanco
 
Javascript asynchronous
Javascript asynchronous
kang taehun
 
Node.js System: The Approach
Node.js System: The Approach
Haci Murat Yaman
 
Node child process
Node child process
LearningTech
 
Debugging & profiling node.js
Debugging & profiling node.js
tomasperezv
 
Node.js - Best practices
Node.js - Best practices
Felix Geisendörfer
 
Intro to Node.js (v1)
Intro to Node.js (v1)
Chris Cowan
 
Celery: The Distributed Task Queue
Celery: The Distributed Task Queue
Richard Leland
 
Introduction to node.js
Introduction to node.js
jacekbecela
 
Introduction to asynchronous DB access using Node.js and MongoDB
Introduction to asynchronous DB access using Node.js and MongoDB
Adrien Joly
 
Node js presentation
Node js presentation
martincabrera
 
Introduction to Node.js: What, why and how?
Introduction to Node.js: What, why and how?
Christian Joudrey
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
.toster
 
Performance and stability testing \w Gatling
Performance and stability testing \w Gatling
Dmitry Vrublevsky
 
GPerf Using Jesque
GPerf Using Jesque
ctoestreich
 
Spock: Test Well and Prosper
Spock: Test Well and Prosper
Ken Kousen
 
Background processing with Resque
Background processing with Resque
Nicolas Blanco
 
Javascript asynchronous
Javascript asynchronous
kang taehun
 
Node.js System: The Approach
Node.js System: The Approach
Haci Murat Yaman
 
Node child process
Node child process
LearningTech
 
Debugging & profiling node.js
Debugging & profiling node.js
tomasperezv
 
Intro to Node.js (v1)
Intro to Node.js (v1)
Chris Cowan
 
Celery: The Distributed Task Queue
Celery: The Distributed Task Queue
Richard Leland
 

Viewers also liked (13)

Testing Javascript Apps with Mocha and Chai
Testing Javascript Apps with Mocha and Chai
Andrew Winder
 
Testing Javascript with Jasmine
Testing Javascript with Jasmine
Tim Tyrrell
 
Testing with Express, Mocha & Chai
Testing with Express, Mocha & Chai
Joerg Henning
 
Test automation introduction training at Polteq
Test automation introduction training at Polteq
Martijn de Vrieze
 
Unit testing with mocha
Unit testing with mocha
Revath S Kumar
 
Unit Testing TypeScript
Unit Testing TypeScript
Daniel Jimenez Garcia
 
Agile scrum roles
Agile scrum roles
David Tzemach
 
The What, Why and How of (Web) Analytics Testing (Web, IoT, Big Data)
The What, Why and How of (Web) Analytics Testing (Web, IoT, Big Data)
Anand Bagmar
 
Appium: Prime Cuts
Appium: Prime Cuts
Sauce Labs
 
DevOps Pipelines and Metrics Driven Feedback Loops
DevOps Pipelines and Metrics Driven Feedback Loops
Andreas Grabner
 
Alphorm.com Formation TypeScript
Alphorm.com Formation TypeScript
Alphorm
 
Mudularity and Unit Testing in TypeScript (for ng-bkk #3)
Mudularity and Unit Testing in TypeScript (for ng-bkk #3)
Suthep Sangvirotjanaphat
 
Les Aventures d'Alice - la Révolte des Tests
Les Aventures d'Alice - la Révolte des Tests
Ly-Jia Goldstein
 
Testing Javascript Apps with Mocha and Chai
Testing Javascript Apps with Mocha and Chai
Andrew Winder
 
Testing Javascript with Jasmine
Testing Javascript with Jasmine
Tim Tyrrell
 
Testing with Express, Mocha & Chai
Testing with Express, Mocha & Chai
Joerg Henning
 
Test automation introduction training at Polteq
Test automation introduction training at Polteq
Martijn de Vrieze
 
Unit testing with mocha
Unit testing with mocha
Revath S Kumar
 
The What, Why and How of (Web) Analytics Testing (Web, IoT, Big Data)
The What, Why and How of (Web) Analytics Testing (Web, IoT, Big Data)
Anand Bagmar
 
Appium: Prime Cuts
Appium: Prime Cuts
Sauce Labs
 
DevOps Pipelines and Metrics Driven Feedback Loops
DevOps Pipelines and Metrics Driven Feedback Loops
Andreas Grabner
 
Alphorm.com Formation TypeScript
Alphorm.com Formation TypeScript
Alphorm
 
Mudularity and Unit Testing in TypeScript (for ng-bkk #3)
Mudularity and Unit Testing in TypeScript (for ng-bkk #3)
Suthep Sangvirotjanaphat
 
Les Aventures d'Alice - la Révolte des Tests
Les Aventures d'Alice - la Révolte des Tests
Ly-Jia Goldstein
 
Ad

Similar to Testing NodeJS with Mocha, Should, Sinon, and JSCoverage (20)

Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
Gil Fink
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
Matt Stine
 
Belvedere
Belvedere
Colin Panisset
 
TypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Declarative Infrastructure Tools
Declarative Infrastructure Tools
Yulia Shcherbachova
 
DevOpsDays InSpec Workshop
DevOpsDays InSpec Workshop
Mandi Walls
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012
Deepak Garg
 
Make BDD great again
Make BDD great again
Yana Gusti
 
How to Reverse Engineer Web Applications
How to Reverse Engineer Web Applications
Jarrod Overson
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
Yevgeniy Brikman
 
BuildStuff.LT 2018 InSpec Workshop
BuildStuff.LT 2018 InSpec Workshop
Mandi Walls
 
Unit testing presentation
Unit testing presentation
Arthur Freyman
 
Strategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoring
Alessandro Franceschi
 
introduction to node.js
introduction to node.js
orkaplan
 
InSpec Workshop at Velocity London 2018
InSpec Workshop at Velocity London 2018
Mandi Walls
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоны
Timur Safin
 
InSpec For DevOpsDays Amsterdam 2017
InSpec For DevOpsDays Amsterdam 2017
Mandi Walls
 
Java - A broad introduction
Java - A broad introduction
Birol Efe
 
Introduction to InSpec and 1.0 release update
Introduction to InSpec and 1.0 release update
Alex Pop
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
Sencha
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
Gil Fink
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
Matt Stine
 
TypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Declarative Infrastructure Tools
Declarative Infrastructure Tools
Yulia Shcherbachova
 
DevOpsDays InSpec Workshop
DevOpsDays InSpec Workshop
Mandi Walls
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012
Deepak Garg
 
Make BDD great again
Make BDD great again
Yana Gusti
 
How to Reverse Engineer Web Applications
How to Reverse Engineer Web Applications
Jarrod Overson
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
Yevgeniy Brikman
 
BuildStuff.LT 2018 InSpec Workshop
BuildStuff.LT 2018 InSpec Workshop
Mandi Walls
 
Unit testing presentation
Unit testing presentation
Arthur Freyman
 
Strategies for Puppet code upgrade and refactoring
Strategies for Puppet code upgrade and refactoring
Alessandro Franceschi
 
introduction to node.js
introduction to node.js
orkaplan
 
InSpec Workshop at Velocity London 2018
InSpec Workshop at Velocity London 2018
Mandi Walls
 
Новый InterSystems: open-source, митапы, хакатоны
Новый InterSystems: open-source, митапы, хакатоны
Timur Safin
 
InSpec For DevOpsDays Amsterdam 2017
InSpec For DevOpsDays Amsterdam 2017
Mandi Walls
 
Java - A broad introduction
Java - A broad introduction
Birol Efe
 
Introduction to InSpec and 1.0 release update
Introduction to InSpec and 1.0 release update
Alex Pop
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
Sencha
 
Ad

Recently uploaded (20)

Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Quantum AI: Where Impossible Becomes Probable
Quantum AI: Where Impossible Becomes Probable
Saikat Basu
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Cracking the Code - Unveiling Synergies Between Open Source Security and AI.pdf
Priyanka Aash
 
9-1-1 Addressing: End-to-End Automation Using FME
9-1-1 Addressing: End-to-End Automation Using FME
Safe Software
 
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
"How to survive Black Friday: preparing e-commerce for a peak season", Yurii ...
Fwdays
 
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
EIS-Webinar-Engineering-Retail-Infrastructure-06-16-2025.pdf
Earley Information Science
 
UserCon Belgium: Honey, VMware increased my bill
UserCon Belgium: Honey, VMware increased my bill
stijn40
 
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Hyderabad MuleSoft In-Person Meetup (June 21, 2025) Slides
Ravi Tamada
 
You are not excused! How to avoid security blind spots on the way to production
You are not excused! How to avoid security blind spots on the way to production
Michele Leroux Bustamante
 
Curietech AI in action - Accelerate MuleSoft development
Curietech AI in action - Accelerate MuleSoft development
shyamraj55
 
Securing AI - There Is No Try, Only Do!.pdf
Securing AI - There Is No Try, Only Do!.pdf
Priyanka Aash
 
Python Conference Singapore - 19 Jun 2025
Python Conference Singapore - 19 Jun 2025
ninefyi
 
"Scaling in space and time with Temporal", Andriy Lupa.pdf
"Scaling in space and time with Temporal", Andriy Lupa.pdf
Fwdays
 
2025_06_18 - OpenMetadata Community Meeting.pdf
2025_06_18 - OpenMetadata Community Meeting.pdf
OpenMetadata
 
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
A Constitutional Quagmire - Ethical Minefields of AI, Cyber, and Privacy.pdf
Priyanka Aash
 
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
" How to survive with 1 billion vectors and not sell a kidney: our low-cost c...
Fwdays
 
Connecting Data and Intelligence: The Role of FME in Machine Learning
Connecting Data and Intelligence: The Role of FME in Machine Learning
Safe Software
 
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
CapCut Pro Crack For PC Latest Version {Fully Unlocked} 2025
pcprocore
 
From Manual to Auto Searching- FME in the Driver's Seat
From Manual to Auto Searching- FME in the Driver's Seat
Safe Software
 
Security Tips for Enterprise Azure Solutions
Security Tips for Enterprise Azure Solutions
Michele Leroux Bustamante
 
Quantum AI: Where Impossible Becomes Probable
Quantum AI: Where Impossible Becomes Probable
Saikat Basu
 
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik - Passionate Tech Enthusiast
Raman Bhaumik
 

Testing NodeJS with Mocha, Should, Sinon, and JSCoverage

  • 1. Testing NodeJS (with Mocha, Should, Sinon, & JSCoverage) Michael Lilley [email protected] Melbourne NodeJS Meetup Group Wednesday, 28 August 2013 Accompanying Sample Repository - https://github.com/mlilley/testing_nodejs_with_mocha.git
  • 3. • Popular • Decent high level features • Highly configurable to suit many tastes • Been around for almost 2 years • Can run in the browser also Why Mocha?
  • 4. Setting Up 1. Install mocha module $ npm install mocha 2. Choose and install your assertion library (we’ll use should) $ npm install should 3. Create a directory for your tests $ mkdir test
  • 5. Setting Up REPORTER = dot test: @NODE_ENV=test ./node_modules/.bin/mocha --reporter $(REPORTER) test-w: @NODE_ENV=test ./node_modules/.bin/mocha --reporter $(REPORTER) --watch .PHONY: test test-w 4. Create your Makefile Remember the tabs!
  • 6. Setting Up { ... "scripts": { "test": "make test" } ... } 5. Configure package.json
  • 7. Code To Be Tested var Adder = exports.Adder = function() {}; Adder.prototype.add = function(a, b) { return a + b; }; sync_adder.js var Adder = exports.Adder = function() {}; Adder.prototype.add = function(a, b, callback) { setTimeout(function() { callback(a + b); }, 100); }; async_adder.js
  • 8. Tests - Synchronous var should = require('should'); var Adder = require('../sync_adder').Adder; describe('Synchronous Adder', function() { describe('add()', function() { it('should return 3 when adding 1 and 2', function() { var adder = new Adder(); adder.add(1, 2).should.equal(3); }); }); }); test/sync_adder.js • NB: or use mocha option ‘--require’ to automatically require common deps (ie: Should)
  • 9. Tests - Asynchronous test/async_adder.js • If done() not called, test fails • Default timeout is 2,000 ms • Adjust with this.timeout(x) var should = require('should'); var Adder = require('../async_adder').Adder; describe('Asynchronous Adder', function() { describe('add()', function() { it('should callback with 3 when adding 1 and 2', function(done) { var adder = new Adder(); adder.add(1, 2, function(result) { result.should.equal(3); done(); }); }); }); });
  • 10. Hooks • before(fn), after(fn), beforeEach(fn), afterEach(fn) • Use within describe() at any nesting level • Use outside describe() for global scope • after/afterEach run on test fail too (unless --bail)
  • 11. Should DSL x.should.be.ok x.should.be.true x.should.be.false x.should.be.empty x.should.be.within(y,z) x.should.be.a(y) x.should.be[.an].instanceOf(y) x.should.be.above(n) x.should.be.below(n) x.should.eql(y) x.should.equal(y) x.should.match(/y/) x.should.have.length(y) x.should.have.property(prop[, val]) x.should.have.ownProperty(prop[, val]) x.should.have.status(code) x.should.have.header(field[, val]) x.should.include(y) x.should.throw([string|/regexp/]) // truthiness // === true // === false // length == 0 // range // typeof // instanceOf // > val // < val // == // === // regexp match // .length == y // prop exists // prop exists (immediate) // .statusCode == y // .header with field & val // x.indexOf(y) != -1 // thrown exception Negation: • x.should.not.be.ok Chaining: • x.should.be.a(‘string’).and.have.length(5) Implementation: • should added to Object as property • Therefore x must not be null or undefined • Use should.exist(x) to test first where needed.
  • 12. Running Tests • Run your tests $ make test or $ npm test or $ ./node_modules/.bin/mocha <options> <path|files> • Run your tests automatically when files change $ make test-w • Run multiple test suites / partial suite / specific tests – Specify desired file or directory on cmd line – Use “tagging” and --grep feature • Tag test names with some unique string (ie “@slow” or “#API” or “APP”) • Pass cmd line option --grep <pattern> • Run Mocha programatically for more control
  • 13. Mocha Configurability • Change assertion library (require(…)) – Should, expect.js, Chai, Expectations, better-assert, Node’s assert lib, etc • Change interface (--ui flag) – for BDD style: describe, it, before, after, beforeEach, afterEach. – for TDD style: suite, test, setup, teardown. – others • Change output Reporter (--reporter flag) – For different styles of terminal output – For output of docs (html, xml, documentation, …) – For feeding into other programs (test coverage, …) • … and more …
  • 14. Sinon • Sinon – APIs for spies, stubs, mocks, and utils – Framework agnostic – To use: • $ npm install sinon • var sinon = require(‘sinon’); – Don’t include via --require because need access to exports
  • 15. Test Coverage 1. Install node-jscoverage binary $ git clone https://github.com/visionmedia/node-jscoverage.git $ ./configure && make && make install 2. Adjust Makefile to: – invoke jscoverage on source to produce instrumented version – run mocha on instrumented source with html-cov reporter to ourput coverage report. ... test-cov: lib-cov @MYPROJ_COVERAGE=1 $(MAKE) test REPORTER=html-cov > coverage.html lib-cov: @jscoverage lib lib-cov ...
  • 16. Test Coverage 3. Adjust project structure (see example repo) – index.js conditionally requires normal or instrumented source based on env var set in makefile module.exports = process.env.MYPROJ_COVERAGE ? require('./lib-cov/myproj') : require('./lib/myproj') 4. Run it $ make test-cov
  • 17. For more… • Mocha - http://visionmedia.github.io/mocha/ • Mocha Wiki - https://github.com/visionmedia/mocha/wiki • Should - https://github.com/visionmedia/should.js/ • Sinon - http://sinonjs.org/ • Node-JSCoverage - https://github.com/visionmedia/node-jscoverage