Introduction to
JavaScript Testing
Ran Mizrahi (@ranm8)
Open Source Dpt. Leader @ CodeOasis
Saturday, April 27, 13
About CodeOasis
• CodeOasis specializes in cutting-edge web solutions.
• Large variety of customers (from startups to enterprises).
• Technologies we love:
• PHP - Symfony2 and Drupal
• node.js
• HTML5
• CSS3
• AngularJS
• Our Microsoft department works with C#, WPF, etc.
Saturday, April 27, 13
Why Do Software Projects Fail?!
• Deliver late or over budget.
• Deliver the wrong thing.
• Unstable in production.
Production Maintenance
• Expensive maintenance.
• Long adjustment to market
needs.
• Long development cycles.
Saturday, April 27, 13
Why Do Software Projects Fail?!
Saturday, April 27, 13
Untestable code...
function createUser(properties) {
var user = {
firstName: properties.firstName,
lastName: properties.lastName,
username: properties.username,
mail: properties.mail
};
var fullName = User.firstName + ' ' + User.lastName;
// Make sure user is valid
if (!user.firstName || !user.lastName) {
throw new Error('First or last name are not valid!');
} else if(typeof user.mail === 'string' && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-
Z]{2,3}$/)) === null) {
throw new Error('Mail is not valid');
} else if (!user.username) {
throw new Error('Username is not valid');
}
$.post('/user', {
fullName: fullName,
userName: user.username,
mail: user.mail
}, function(data) {
var message;
if (data.code === 200) {
message = 'User saved successfully!';
} else {
message = 'Operation was failed!';
}
$('#some-div').animate({
'margin-left': $(window).width()
}, 1000, function() {
$(this).html(message);
});
});
}
Saturday, April 27, 13
Why Test Your Code???
The problems with untestable code:
• Tightly coupled.
• No separation of concerns.
• Not readable.
• Not predictable.
• Global states.
• Long methods.
• Large classes/objects.
Saturday, April 27, 13
Why Test Your Code???
The problems with untestable code:
• Tightly coupled.
• No separation of concerns.
• Not readable.
• Not predictable.
• Global states.
• Long methods.
• Large classes/objects.
>
• Hard to maintain.
• High learning curve.
• Stability issues.
• You can never expect
problems before they
occur
Saturday, April 27, 13
Test-Driven Development To The Recuse!
Methodology for using automated unit
tests to drive software design, quality
and stability.
Saturday, April 27, 13
Test-Driven Development To The Recuse!
How it’s done :
• First the developer writes
a failing test case that
defines a desired
functionality to the
software.
• Makes the code pass
those tests.
• Refactor the code to meet
standards.
Saturday, April 27, 13
Seems Great But How Much Longer Does TDD Takes???
My experience:
• Initial progress will be slower.
• Greater consistency.
• Long tern cost is drastically
lower
• After getting used to it, you
can write TDD faster (-:
Studies:
• Takes 15-30% longer.
• 45-80% less bugs.
• Fixing bugs later on is
dramatically faster.
Saturday, April 27, 13
The Three Rules of TDD
Rule #1
Your code should always fail before you implement the code
Rule #2
Implement the simplest code possible to pass your tests.
Rule #3
Refactor, refactor and refractor - There is no shame in refactoring.
Saturday, April 27, 13
BDD (Behavior-Driven Development)
Test-Driven Development
Saturday, April 27, 13
BDD (Behavior-Driven Development)
Test-Driven Development
What exactly are we testing?!
Saturday, April 27, 13
BDD (Behavior-Driven Development)
• Originally started in 2003 by Dan North, author of JBehave, the
first BDD tool.
• Based on the TDD methodology.
• Aims to provide tools for both developers and business (e.g.
product manager, etc.) to share development process together.
• The steps of BDD :
• Developers and business personas write specification together.
• Developer writes tests based on specs and make them fail.
• Write code to pass those tests.
• Refactor, refactor, refactor...
Saturday, April 27, 13
BDD (Behavior-Driven Development)
Feature: ls
In order to see the directory structure
As a UNIX user
I need to be able to list the current directory's contents
Scenario: List 2 files in a directory
Given I am in a directory "test"
And I have a file named "foo"
And I have a file named "bar"
When I run "ls"
Then I should get:
"""
bar
foo
"""
Saturday, April 27, 13
Main Test Types
• Unit Testing
• Integration Testing
• Functional Testing
Saturday, April 27, 13
Challenges Testing JavaScript
• Async tests:
• Testing async methods can be tricky.
• Define tests timeout.
• Indicate when test is completed in callback.
• Assert on callback.
• DOM:
• Testing DOM is a difficult task.
• The key is to separate your controller and model logic from
DOM and test those only.
• Testing DOM is done using functional testing (e.g. WebDriver,
etc.)
Saturday, April 27, 13
TDD/BDD using Mocha and Expect.js
Mocha is a feature-rich JavaScript test frameworks running on
node and the browser, making asynchronies tests easy.
Mocha
Main features:
• Supports both TDD and BDD styles.
• Both browser and node support.
• Proper exit status for CI support.
• node.js debugger support.
• Highly flexible, choose and join the pieces yourself (spy library,
assertion library, etc.).
Saturday, April 27, 13
TDD/BDD using Mocha and Expect.js
Expect.js is a minimalistic assertion library based on should.js
Expect.js
Main features:
• BDD style.
• Compatible with all test frameworks.
• Both node.js and browser compatible.
• Standalone assertion library.
Saturday, April 27, 13
TDD/BDD using Mocha and Expect.js
Installing Mocha and Expect.js
$ npm install mocha -g
$ npm install expect.js -g
Install mocha globally using npm:
Install Expect.js:
Saturday, April 27, 13
TDD/BDD using Mocha and Expect.js
var expect = require('expect.js');
describe('Array', function() {
describe('#indexOf()', function() {
it('Expect -1 when the value is not present', function() {
var array = [1, 2, 3];
expect(array.indexOf(4)).to.be(-1);
});
});
});
“Normal” test:
Run it..
$ mocha --reporter spec
Array
#indexOf()
✓ Expect -1 when the value is not present
1 test complete (5 ms)
Saturday, April 27, 13
TDD/BDD using Mocha and Expect.js
“Async” test:
var expect = require('expect.js');
function asyncCall(val ,callback) {
var prefix = ' - ';
setTimeout(function() {
var newString = val + prefix + 'OK';
callback(newString);
}, 500);
}
describe('asyncCall', function() {
it('Add suffix that prefixed with - to the given string', function(done) {
var testVal = 'Foo';
asyncCall(testVal, function(response) {
expect(response).to.contain(testVal + ' - OK');
done();
});
});
});
Let’s run it...
Saturday, April 27, 13
Back to our code
Saturday, April 27, 13
First, Let’s Write The Tests!
function createUser(properties) {
var user = {
firstName: properties.firstName,
lastName: properties.lastName,
username: properties.username,
mail: properties.mail
};
var fullName = User.firstName + ' ' + User.lastName;
// Make sure user is valid
if (!user.firstName || !user.lastName) {
throw new Error('First or last name are not valid!');
} else if(typeof user.mail === 'string' && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-
Z]{2,3}$/)) === null) {
throw new Error('Mail is not valid');
} else if (!user.username) {
throw new Error('Username is not valid');
}
$.post('/user', {
fullName: fullName,
userName: user.username,
mail: user.mail
}, function(data) {
var message;
if (data.code === 200) {
message = 'User saved successfully!';
} else {
message = 'Operation was failed!';
}
$('#some-div').animate({
'margin-left': $(window).width()
}, 1000, function() {
$(this).html(message);
});
});
}
Saturday, April 27, 13
First, Let’s Write The Tests!
What to test in our case:
• Validations.
• Full name getter.
• User save callback
What not to test :
• DOM manipulations - for that, we should use functional testing for
that cause (e.g. WebDriver)
• AJAX requests - Leaving integration testing aside.
Saturday, April 27, 13
First, Let’s Write The Tests!
describe('User', function() {
var user;
beforeEach(function() {
// Create the user obj
user = new User({
firstName: 'Ran',
lastName: 'Mizrahi',
mail: 'ranm@codeoasis.com',
username: 'ranm'
});
});
afterEach(function() {
// clean-up
user = {};
});
describe('#fullName()', function() {
it('Should return firstName and lastName separated by space', function() {
expect(user.fullName).to.be('Ran Mizrahi');
});
});
describe('#save()', function() {
it('Should save user without any errors', function(done) {
user.save(function(error) {
if (error) {
throw error;
} else {
done();
}
});
});
});
describe('#mail()', function() {
it('Should set mail correctly after mail validation', function() {
expect(user.mail).to.be('ranm@codeoasis.com');
});
});
});
Saturday, April 27, 13
Run those tests
Saturday, April 27, 13
Now, Let’s Write The Code
var User = (function() {
'use strict';
var User = function(properties) {
// Set some data
this.firstName = properties.firstName || '';
this.lastName = properties.lastName || '';
this.username = properties.username || '';
this.mail = properties.mail || '';
};
User.__defineGetter__('fullName', function() {
return this.firstName + ' ' + this.lastName;
});
User.__defineSetter__('mail', function(mail) {
var matcher = new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/);
if (mail.match(matcher) === null) {
throw 'Mail is not valid';
}
this._mail = mail;
});
User.prototype.save = function(callback) {
setTimeout(function() {
callback();
}, 1000);
return this;
};
return User;
}());
Saturday, April 27, 13
Run those tests,
again!
Saturday, April 27, 13
Running The Tests
mocha tests can run in different environments and formats:
• Browser - using mocha.js (see example)
• For CI automation use JSTestDriver.
• CLI - as demonstrated before using the “mocha” command.
• CI (e.g. xunit) - $ mocha test/asyncTest.js --reporter xunit.
• Many other formats (JSON, HTML, list, Spec, etc.)
Saturday, April 27, 13
Benefits of Testing Your Code
• Short feedback/testing cycle.
• High code coverage of tests that can be at run any time to
provide feedback that the software is functioning.
• Provides detailed spec/docs of the application.
• Less time spent on debugging and refactoring.
• Know what breaks early on.
• Enforces code quality (decoupled) and simplicity.
• Help you focus on writing one job code units.
Saturday, April 27, 13
Questions?
Thank you!
Saturday, April 27, 13

More Related Content

PDF
Introduction to node.js by Ran Mizrahi @ Reversim Summit
PDF
Intro To JavaScript Unit Testing - Ran Mizrahi
PPTX
Ran Mizrahi - Symfony2 meets Drupal8
PDF
How AngularJS Embraced Traditional Design Patterns
PDF
Dependency Injection @ AngularJS
PDF
Intro to node.js - Ran Mizrahi (28/8/14)
PDF
JavaScript Library Overview
PDF
Javascript Best Practices
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi - Symfony2 meets Drupal8
How AngularJS Embraced Traditional Design Patterns
Dependency Injection @ AngularJS
Intro to node.js - Ran Mizrahi (28/8/14)
JavaScript Library Overview
Javascript Best Practices

What's hot (20)

PDF
Node.js vs Play Framework (with Japanese subtitles)
PPT
Javascript and Jquery Best practices
PPTX
Good karma: UX Patterns and Unit Testing in Angular with Karma
KEY
Agile JavaScript Testing
PDF
JavaScript TDD with Jasmine and Karma
PDF
Design patterns revisited with PHP 5.3
PDF
Advanced Jasmine - Front-End JavaScript Unit Testing
ODP
Unit Testing and Coverage for AngularJS
PDF
Angularjs - Unit testing introduction
PDF
How to build to do app using vue composition api and vuex 4 with typescript
ODP
Jquery- One slide completing all JQuery
KEY
Building a real life application in node js
PDF
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
PDF
Survive JavaScript - Strategies and Tricks
PDF
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
PPTX
Unit testing in JavaScript with Jasmine and Karma
PDF
Secrets of JavaScript Libraries
PDF
Angular testing
PDF
Workshop 3: JavaScript build tools
PDF
Tech friday 22.01.2016
Node.js vs Play Framework (with Japanese subtitles)
Javascript and Jquery Best practices
Good karma: UX Patterns and Unit Testing in Angular with Karma
Agile JavaScript Testing
JavaScript TDD with Jasmine and Karma
Design patterns revisited with PHP 5.3
Advanced Jasmine - Front-End JavaScript Unit Testing
Unit Testing and Coverage for AngularJS
Angularjs - Unit testing introduction
How to build to do app using vue composition api and vuex 4 with typescript
Jquery- One slide completing all JQuery
Building a real life application in node js
JavaCro'14 - Scala and Java EE 7 Development Experiences – Peter Pilgrim
Survive JavaScript - Strategies and Tricks
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Unit testing in JavaScript with Jasmine and Karma
Secrets of JavaScript Libraries
Angular testing
Workshop 3: JavaScript build tools
Tech friday 22.01.2016
Ad

Viewers also liked (20)

PDF
Getting merged
PDF
Understanding Your Content
PPT
Introduction
PPT
Me, write an exam?
PDF
My Carnegie Mellon University Master\'s Thesis
PPT
PPS
Cloud gate_tramping in china
PDF
Founders Fund Manifesto
PDF
Don't make my eyes bleed - Neil Davidson
ODP
Snowflakes
PPTX
Gita ch 3
PDF
A framework for measuring social media
PPTX
What's a Wiki?
PPS
Euskara Motibazioak
PPT
ярмарка инноваций в образовании для веб
PPT
Idiazabal gazta on linen satzeko marketin-plana
PDF
Wix Application Framework
PPT
Mappeoppgave 2 2003
PDF
Intro to node.js - Ran Mizrahi (27/8/2014)
PPT
P2 Tour
Getting merged
Understanding Your Content
Introduction
Me, write an exam?
My Carnegie Mellon University Master\'s Thesis
Cloud gate_tramping in china
Founders Fund Manifesto
Don't make my eyes bleed - Neil Davidson
Snowflakes
Gita ch 3
A framework for measuring social media
What's a Wiki?
Euskara Motibazioak
ярмарка инноваций в образовании для веб
Idiazabal gazta on linen satzeko marketin-plana
Wix Application Framework
Mappeoppgave 2 2003
Intro to node.js - Ran Mizrahi (27/8/2014)
P2 Tour
Ad

Similar to Intro to JavaScript Testing (20)

PDF
Intro to PHP Testing
PDF
JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript"
PDF
Node.js Development Workflow Automation with Grunt.js
PPTX
Hadoop cluster performance profiler
PPTX
Java script unit testing
ODP
Grails unit testing
PDF
Testing iOS Apps
PPTX
Scalamen and OT
PPTX
Node.js Patterns for Discerning Developers
PDF
540slidesofnodejsbackendhopeitworkforu.pdf
PDF
Quick tour to front end unit testing using jasmine
PDF
How we're building Wercker
PDF
May: Automated Developer Testing: Achievements and Challenges
PDF
TDD super mondays-june-2014
PPT
Pragmatic Parallels: Java and JavaScript
PDF
Unit tests in node.js
PPTX
Java scriptforjavadev part2a
PPT
Unit testing with Spock Framework
PDF
Into The Box 2018 | Assert control over your legacy applications
PDF
Spring IO 2015 Spock Workshop
Intro to PHP Testing
JS Lab`16. Сергей Селецкий: "Ретроспектива тестирования JavaScript"
Node.js Development Workflow Automation with Grunt.js
Hadoop cluster performance profiler
Java script unit testing
Grails unit testing
Testing iOS Apps
Scalamen and OT
Node.js Patterns for Discerning Developers
540slidesofnodejsbackendhopeitworkforu.pdf
Quick tour to front end unit testing using jasmine
How we're building Wercker
May: Automated Developer Testing: Achievements and Challenges
TDD super mondays-june-2014
Pragmatic Parallels: Java and JavaScript
Unit tests in node.js
Java scriptforjavadev part2a
Unit testing with Spock Framework
Into The Box 2018 | Assert control over your legacy applications
Spring IO 2015 Spock Workshop

Recently uploaded (20)

PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
PPT
Module 1.ppt Iot fundamentals and Architecture
PPTX
Modernising the Digital Integration Hub
PDF
Enhancing plagiarism detection using data pre-processing and machine learning...
PPTX
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
PDF
Improvisation in detection of pomegranate leaf disease using transfer learni...
PDF
A review of recent deep learning applications in wood surface defect identifi...
PDF
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
PPTX
Custom Battery Pack Design Considerations for Performance and Safety
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PDF
Credit Without Borders: AI and Financial Inclusion in Bangladesh
PPTX
AI IN MARKETING- PRESENTED BY ANWAR KABIR 1st June 2025.pptx
PDF
1 - Historical Antecedents, Social Consideration.pdf
PDF
OpenACC and Open Hackathons Monthly Highlights July 2025
PDF
CloudStack 4.21: First Look Webinar slides
PDF
How IoT Sensor Integration in 2025 is Transforming Industries Worldwide
PDF
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
PDF
A proposed approach for plagiarism detection in Myanmar Unicode text
PDF
Developing a website for English-speaking practice to English as a foreign la...
PPTX
Chapter 5: Probability Theory and Statistics
Taming the Chaos: How to Turn Unstructured Data into Decisions
Module 1.ppt Iot fundamentals and Architecture
Modernising the Digital Integration Hub
Enhancing plagiarism detection using data pre-processing and machine learning...
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
Improvisation in detection of pomegranate leaf disease using transfer learni...
A review of recent deep learning applications in wood surface defect identifi...
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
Custom Battery Pack Design Considerations for Performance and Safety
NewMind AI Weekly Chronicles – August ’25 Week III
Credit Without Borders: AI and Financial Inclusion in Bangladesh
AI IN MARKETING- PRESENTED BY ANWAR KABIR 1st June 2025.pptx
1 - Historical Antecedents, Social Consideration.pdf
OpenACC and Open Hackathons Monthly Highlights July 2025
CloudStack 4.21: First Look Webinar slides
How IoT Sensor Integration in 2025 is Transforming Industries Worldwide
Hybrid horned lizard optimization algorithm-aquila optimizer for DC motor
A proposed approach for plagiarism detection in Myanmar Unicode text
Developing a website for English-speaking practice to English as a foreign la...
Chapter 5: Probability Theory and Statistics

Intro to JavaScript Testing

  • 1. Introduction to JavaScript Testing Ran Mizrahi (@ranm8) Open Source Dpt. Leader @ CodeOasis Saturday, April 27, 13
  • 2. About CodeOasis • CodeOasis specializes in cutting-edge web solutions. • Large variety of customers (from startups to enterprises). • Technologies we love: • PHP - Symfony2 and Drupal • node.js • HTML5 • CSS3 • AngularJS • Our Microsoft department works with C#, WPF, etc. Saturday, April 27, 13
  • 3. Why Do Software Projects Fail?! • Deliver late or over budget. • Deliver the wrong thing. • Unstable in production. Production Maintenance • Expensive maintenance. • Long adjustment to market needs. • Long development cycles. Saturday, April 27, 13
  • 4. Why Do Software Projects Fail?! Saturday, April 27, 13
  • 5. Untestable code... function createUser(properties) { var user = { firstName: properties.firstName, lastName: properties.lastName, username: properties.username, mail: properties.mail }; var fullName = User.firstName + ' ' + User.lastName; // Make sure user is valid if (!user.firstName || !user.lastName) { throw new Error('First or last name are not valid!'); } else if(typeof user.mail === 'string' && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA- Z]{2,3}$/)) === null) { throw new Error('Mail is not valid'); } else if (!user.username) { throw new Error('Username is not valid'); } $.post('/user', { fullName: fullName, userName: user.username, mail: user.mail }, function(data) { var message; if (data.code === 200) { message = 'User saved successfully!'; } else { message = 'Operation was failed!'; } $('#some-div').animate({ 'margin-left': $(window).width() }, 1000, function() { $(this).html(message); }); }); } Saturday, April 27, 13
  • 6. Why Test Your Code??? The problems with untestable code: • Tightly coupled. • No separation of concerns. • Not readable. • Not predictable. • Global states. • Long methods. • Large classes/objects. Saturday, April 27, 13
  • 7. Why Test Your Code??? The problems with untestable code: • Tightly coupled. • No separation of concerns. • Not readable. • Not predictable. • Global states. • Long methods. • Large classes/objects. > • Hard to maintain. • High learning curve. • Stability issues. • You can never expect problems before they occur Saturday, April 27, 13
  • 8. Test-Driven Development To The Recuse! Methodology for using automated unit tests to drive software design, quality and stability. Saturday, April 27, 13
  • 9. Test-Driven Development To The Recuse! How it’s done : • First the developer writes a failing test case that defines a desired functionality to the software. • Makes the code pass those tests. • Refactor the code to meet standards. Saturday, April 27, 13
  • 10. Seems Great But How Much Longer Does TDD Takes??? My experience: • Initial progress will be slower. • Greater consistency. • Long tern cost is drastically lower • After getting used to it, you can write TDD faster (-: Studies: • Takes 15-30% longer. • 45-80% less bugs. • Fixing bugs later on is dramatically faster. Saturday, April 27, 13
  • 11. The Three Rules of TDD Rule #1 Your code should always fail before you implement the code Rule #2 Implement the simplest code possible to pass your tests. Rule #3 Refactor, refactor and refractor - There is no shame in refactoring. Saturday, April 27, 13
  • 12. BDD (Behavior-Driven Development) Test-Driven Development Saturday, April 27, 13
  • 13. BDD (Behavior-Driven Development) Test-Driven Development What exactly are we testing?! Saturday, April 27, 13
  • 14. BDD (Behavior-Driven Development) • Originally started in 2003 by Dan North, author of JBehave, the first BDD tool. • Based on the TDD methodology. • Aims to provide tools for both developers and business (e.g. product manager, etc.) to share development process together. • The steps of BDD : • Developers and business personas write specification together. • Developer writes tests based on specs and make them fail. • Write code to pass those tests. • Refactor, refactor, refactor... Saturday, April 27, 13
  • 15. BDD (Behavior-Driven Development) Feature: ls In order to see the directory structure As a UNIX user I need to be able to list the current directory's contents Scenario: List 2 files in a directory Given I am in a directory "test" And I have a file named "foo" And I have a file named "bar" When I run "ls" Then I should get: """ bar foo """ Saturday, April 27, 13
  • 16. Main Test Types • Unit Testing • Integration Testing • Functional Testing Saturday, April 27, 13
  • 17. Challenges Testing JavaScript • Async tests: • Testing async methods can be tricky. • Define tests timeout. • Indicate when test is completed in callback. • Assert on callback. • DOM: • Testing DOM is a difficult task. • The key is to separate your controller and model logic from DOM and test those only. • Testing DOM is done using functional testing (e.g. WebDriver, etc.) Saturday, April 27, 13
  • 18. TDD/BDD using Mocha and Expect.js Mocha is a feature-rich JavaScript test frameworks running on node and the browser, making asynchronies tests easy. Mocha Main features: • Supports both TDD and BDD styles. • Both browser and node support. • Proper exit status for CI support. • node.js debugger support. • Highly flexible, choose and join the pieces yourself (spy library, assertion library, etc.). Saturday, April 27, 13
  • 19. TDD/BDD using Mocha and Expect.js Expect.js is a minimalistic assertion library based on should.js Expect.js Main features: • BDD style. • Compatible with all test frameworks. • Both node.js and browser compatible. • Standalone assertion library. Saturday, April 27, 13
  • 20. TDD/BDD using Mocha and Expect.js Installing Mocha and Expect.js $ npm install mocha -g $ npm install expect.js -g Install mocha globally using npm: Install Expect.js: Saturday, April 27, 13
  • 21. TDD/BDD using Mocha and Expect.js var expect = require('expect.js'); describe('Array', function() { describe('#indexOf()', function() { it('Expect -1 when the value is not present', function() { var array = [1, 2, 3]; expect(array.indexOf(4)).to.be(-1); }); }); }); “Normal” test: Run it.. $ mocha --reporter spec Array #indexOf() ✓ Expect -1 when the value is not present 1 test complete (5 ms) Saturday, April 27, 13
  • 22. TDD/BDD using Mocha and Expect.js “Async” test: var expect = require('expect.js'); function asyncCall(val ,callback) { var prefix = ' - '; setTimeout(function() { var newString = val + prefix + 'OK'; callback(newString); }, 500); } describe('asyncCall', function() { it('Add suffix that prefixed with - to the given string', function(done) { var testVal = 'Foo'; asyncCall(testVal, function(response) { expect(response).to.contain(testVal + ' - OK'); done(); }); }); }); Let’s run it... Saturday, April 27, 13
  • 23. Back to our code Saturday, April 27, 13
  • 24. First, Let’s Write The Tests! function createUser(properties) { var user = { firstName: properties.firstName, lastName: properties.lastName, username: properties.username, mail: properties.mail }; var fullName = User.firstName + ' ' + User.lastName; // Make sure user is valid if (!user.firstName || !user.lastName) { throw new Error('First or last name are not valid!'); } else if(typeof user.mail === 'string' && user.mail.match(new RegExp(/^w+@[a-zA-Z_]+?.[a-zA- Z]{2,3}$/)) === null) { throw new Error('Mail is not valid'); } else if (!user.username) { throw new Error('Username is not valid'); } $.post('/user', { fullName: fullName, userName: user.username, mail: user.mail }, function(data) { var message; if (data.code === 200) { message = 'User saved successfully!'; } else { message = 'Operation was failed!'; } $('#some-div').animate({ 'margin-left': $(window).width() }, 1000, function() { $(this).html(message); }); }); } Saturday, April 27, 13
  • 25. First, Let’s Write The Tests! What to test in our case: • Validations. • Full name getter. • User save callback What not to test : • DOM manipulations - for that, we should use functional testing for that cause (e.g. WebDriver) • AJAX requests - Leaving integration testing aside. Saturday, April 27, 13
  • 26. First, Let’s Write The Tests! describe('User', function() { var user; beforeEach(function() { // Create the user obj user = new User({ firstName: 'Ran', lastName: 'Mizrahi', mail: '[email protected]', username: 'ranm' }); }); afterEach(function() { // clean-up user = {}; }); describe('#fullName()', function() { it('Should return firstName and lastName separated by space', function() { expect(user.fullName).to.be('Ran Mizrahi'); }); }); describe('#save()', function() { it('Should save user without any errors', function(done) { user.save(function(error) { if (error) { throw error; } else { done(); } }); }); }); describe('#mail()', function() { it('Should set mail correctly after mail validation', function() { expect(user.mail).to.be('[email protected]'); }); }); }); Saturday, April 27, 13
  • 28. Now, Let’s Write The Code var User = (function() { 'use strict'; var User = function(properties) { // Set some data this.firstName = properties.firstName || ''; this.lastName = properties.lastName || ''; this.username = properties.username || ''; this.mail = properties.mail || ''; }; User.__defineGetter__('fullName', function() { return this.firstName + ' ' + this.lastName; }); User.__defineSetter__('mail', function(mail) { var matcher = new RegExp(/^w+@[a-zA-Z_]+?.[a-zA-Z]{2,3}$/); if (mail.match(matcher) === null) { throw 'Mail is not valid'; } this._mail = mail; }); User.prototype.save = function(callback) { setTimeout(function() { callback(); }, 1000); return this; }; return User; }()); Saturday, April 27, 13
  • 30. Running The Tests mocha tests can run in different environments and formats: • Browser - using mocha.js (see example) • For CI automation use JSTestDriver. • CLI - as demonstrated before using the “mocha” command. • CI (e.g. xunit) - $ mocha test/asyncTest.js --reporter xunit. • Many other formats (JSON, HTML, list, Spec, etc.) Saturday, April 27, 13
  • 31. Benefits of Testing Your Code • Short feedback/testing cycle. • High code coverage of tests that can be at run any time to provide feedback that the software is functioning. • Provides detailed spec/docs of the application. • Less time spent on debugging and refactoring. • Know what breaks early on. • Enforces code quality (decoupled) and simplicity. • Help you focus on writing one job code units. Saturday, April 27, 13