SlideShare a Scribd company logo
Introduction to 
{ JavaScript Testing } 
Ran Mizrahi (@ranm8) 
Founder and CEO @ CoCycles
About { Me } 
• Founder and CEO of CoCycles. 
• Former Open Source Dpt. Leader of CodeOasis. 
• Architected and lead the development of the Wix App Market. 
• Full-stack and hands-on software engineer.
Why Do Software Projects { Fail } ? 
Production Maintenance 
• Deliver late or over budget. 
• Deliver the wrong thing. 
• Unstable in production. 
• Expensive maintenance. 
• Long adjustment to market 
needs. 
• Long development cycles.
Why Do Software Projects { Fail } ?
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); 
}); 
}); 
}
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 
Why Test Your { Code } ?
{ Test-Driven Development } To The Rescue 
Methodology for using automated unit 
tests to drive software design, quality 
and stability.
{ Test-Driven Development } To The Rescue 
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.
Seems Great But How Much Longer Does { TDD Take } ? 
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.
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.
{ BDD } Behaviour-Driven Development 
What exactly are we testing?! 
Test-Driven Development
{ BDD } Behaviour-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...
{ BDD } Behaviour-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 
"""
Main { Test Types } 
• Unit Testing 
• Integration Testing 
• Functional Testing
{ 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.)
TDD/BDD Using { Mocha and ChaiJS } 
Mocha 
Mocha is a feature-rich JavaScript test frameworks running on 
node and the browser, making asynchronies tests easy. 
Main features: 
• Supports both TDD and BDD styles. 
• Simple async testing. 
• 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.).
TDD/BDD Using { Mocha and ChaiJS } 
ChaiJS 
Chai is a BDD / TDD assertion library for node and the browser 
that can be paired with any JavaScript testing framework. 
Main features: 
• BDD/TDD style. 
• Compatible with all test frameworks. 
• Both node.js and browser compatible. 
• Standalone assertion library. 
• Extendable
TDD/BDD Using { Mocha and ChaiJS } 
Installing Mocha and Chai 
Install mocha globally using npm: 
$ npm install mocha -g 
Install Chai (Locally): 
$ npm install chai
TDD/BDD Using { Mocha and ChaiJS } 
“Normal” test: 
var expect = require(‘chai').expect; 
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); 
}); 
}); 
}); 
Run it.. 
$ mocha --reporter spec 
Array 
#indexOf() 
✓ Expect -1 when the value is not present 
1 test complete (5 ms)
TDD/BDD Using { Mocha and ChaiJS } 
Async test: 
var expect = require(‘chai').expect; 
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...
Back To { Our Code }
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); 
}); 
}); 
}
First, Let’s { Write The Tests } 
What to test in our case: 
• Full name concatenation. 
• API call data. 
• Request callback. 
What not to test : 
• DOM manipulations - Functional testing (e.g. WebDriver). 
• API requests - Integration testing.
First, Let’s { Write The Unit Tests } 
describe('#saveUser()', function() { 
it('should call http service with method POST, path /user, and the user object', function() { 
}); 
it('should compose the full name in to the user object', function() { 
}); 
it('should only return the payload from the response object', function() { 
}); 
}); 
});
The { Implementation } 
function userService($http, baseUrl) { 
baseUrl = baseUrl || 'http://google.com/api'; 
function composeFullName(firstName, lastName) { 
return firstName + ' ' + lastName; 
} 
function returnPayload(response) { 
return response.payload; 
} 
function execute(path, body, method) { 
return $http({ 
url: baseUrl + path, 
method: method || 'GET', 
data: body 
}); 
} 
return { 
saveUser: function(user) { 
user.fullName = composeFullName(user.firstName, user.lastName); 
return execute('/user', user, 'POST').then(returnPayload); 
} 
}; 
}
Implement { Our Unit Tests } 
describe('user service', function() { 
var userService, 
httpMock, 
thenFunc; 
function createHttpMock() { 
thenFunc = sinon.stub(); 
httpMock = sinon.stub().returns({ then: thenFunc }); 
} 
beforeEach(function() { 
createHttpMock(); 
userService = UserService(httpMock); 
}); 
function getUser() { 
return { firstName: 'Ran', lastName: 'Mizrahi' }; 
}
Implement { Our Unit Tests } 
describe('#saveUser()', function() { 
var user; 
beforeEach(function() { 
user = getUser(); 
userService.saveUser(user); 
}); 
it('should call http service with method POST, path /user, and the user object', function() { 
expect(httpMock).to.have.been.calledWith({ 
url: 'http://google.com/api/user', 
method: 'POST', 
data: user 
}); 
}); 
it('should compose the full name in to the user object', function() { 
expect(user.fullName).to.equal('Ran Mizrahi'); 
}); 
it('should only return the payload from the response object', function() { 
var returnPayload = thenFunc.args[0][0]; 
expect(returnPayload({ payload: 'Hello!!!' })).to.equal('Hello!!!'); 
}); 
}); 
});
Run Those { Tests Again }
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.)
Benefits of { Testing The 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 and simplicity. 
• Helps separating units to responsibilities.
Thank you! 
Questions?

More Related Content

PDF
Intro to JavaScript Testing
PDF
Intro to node.js - Ran Mizrahi (28/8/14)
PDF
How AngularJS Embraced Traditional Design Patterns
PDF
Introduction to node.js by Ran Mizrahi @ Reversim Summit
PPTX
Ran Mizrahi - Symfony2 meets Drupal8
PDF
Test automation & Seleniun by oren rubin
PPTX
Testing Ext JS and Sencha Touch
KEY
Agile JavaScript Testing
Intro to JavaScript Testing
Intro to node.js - Ran Mizrahi (28/8/14)
How AngularJS Embraced Traditional Design Patterns
Introduction to node.js by Ran Mizrahi @ Reversim Summit
Ran Mizrahi - Symfony2 meets Drupal8
Test automation & Seleniun by oren rubin
Testing Ext JS and Sencha Touch
Agile JavaScript Testing

What's hot (20)

PDF
JavaScript Library Overview
PDF
Intro to JavaScript
PDF
Javascript Best Practices
PDF
Unit Testing JavaScript Applications
PDF
Unit and functional testing with Siesta
PPTX
Good karma: UX Patterns and Unit Testing in Angular with Karma
PDF
jQuery Proven Performance Tips & Tricks
PPT
Testing in AngularJS
PDF
UI Testing Best Practices - An Expected Journey
PDF
Introduction to Protractor
PDF
Javascript Test Automation Workshop (21.08.2014)
PDF
Testing javascript in the frontend
PDF
Survive JavaScript - Strategies and Tricks
ZIP
Automated Frontend Testing
PDF
Design patterns revisited with PHP 5.3
PDF
Dart for Java Developers
PDF
Night Watch with QA
PPTX
Node.JS error handling best practices
PPTX
Java script unit testing
PDF
How Testability Inspires AngularJS Design / Ran Mizrahi
JavaScript Library Overview
Intro to JavaScript
Javascript Best Practices
Unit Testing JavaScript Applications
Unit and functional testing with Siesta
Good karma: UX Patterns and Unit Testing in Angular with Karma
jQuery Proven Performance Tips & Tricks
Testing in AngularJS
UI Testing Best Practices - An Expected Journey
Introduction to Protractor
Javascript Test Automation Workshop (21.08.2014)
Testing javascript in the frontend
Survive JavaScript - Strategies and Tricks
Automated Frontend Testing
Design patterns revisited with PHP 5.3
Dart for Java Developers
Night Watch with QA
Node.JS error handling best practices
Java script unit testing
How Testability Inspires AngularJS Design / Ran Mizrahi
Ad

Viewers also liked (20)

PDF
Wix Application Framework
PDF
Dependency Injection @ AngularJS
PDF
Bitcoin for humans
PDF
Product development for startups
PPT
PPT
Final Presentation
PPT
Jugaaad: Innovation book
PPTX
Studying at UNH: Education and Research Opportunities
PDF
Founders Fund Manifesto
PPS
Cheeky Carbon Presentation
PDF
4. prosegizontas tin ekpadeutiki omada
PDF
Wemagazine
PPT
Publish2 Tour
PPT
PPT
Sticky Information - Von Hippel
PDF
Don't make my eyes bleed - Neil Davidson
PPT
Jornada de motivacion y busqueda de opciones
PDF
Diadrastikoi a theoritiko plaisio
Wix Application Framework
Dependency Injection @ AngularJS
Bitcoin for humans
Product development for startups
Final Presentation
Jugaaad: Innovation book
Studying at UNH: Education and Research Opportunities
Founders Fund Manifesto
Cheeky Carbon Presentation
4. prosegizontas tin ekpadeutiki omada
Wemagazine
Publish2 Tour
Sticky Information - Von Hippel
Don't make my eyes bleed - Neil Davidson
Jornada de motivacion y busqueda de opciones
Diadrastikoi a theoritiko plaisio
Ad

Similar to Intro To JavaScript Unit Testing - Ran Mizrahi (20)

PDF
3 WAYS TO TEST YOUR COLDFUSION API
PDF
3 WAYS TO TEST YOUR COLDFUSION API -
PPTX
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
PDF
How do I Write Testable Javascript so I can Test my CF API on Server and Client
PPTX
How do I write Testable Javascript so I can Test my CF API on Server and Client
PDF
BDD Testing and Automating from the trenches - Presented at Into The Box June...
PDF
ITB2016 -BDD testing and automation from the trenches
PDF
Testing with Express, Mocha & Chai
PDF
How to write Testable Javascript
PDF
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
PPTX
Understanding TDD - theory, practice, techniques and tips.
PDF
An Introduction to the World of Testing for Front-End Developers
PDF
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
PPTX
Introduction to bdd
PDF
ES3-2020-06 Test Driven Development (TDD)
PPTX
Test Driven Development - a Practitioner’s Perspective
PDF
How do I write Testable Javascript?
PDF
How do I write Testable Javascript
PDF
How do I write testable javascript?
PDF
JavaScript development methodology
3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API -
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
How do I Write Testable Javascript so I can Test my CF API on Server and Client
How do I write Testable Javascript so I can Test my CF API on Server and Client
BDD Testing and Automating from the trenches - Presented at Into The Box June...
ITB2016 -BDD testing and automation from the trenches
Testing with Express, Mocha & Chai
How to write Testable Javascript
How do I write Testable Javascript - Presented at dev.Objective() June 16, 2016
Understanding TDD - theory, practice, techniques and tips.
An Introduction to the World of Testing for Front-End Developers
FITC Web Unleashed 2017 - Introduction to the World of Testing for Front-End ...
Introduction to bdd
ES3-2020-06 Test Driven Development (TDD)
Test Driven Development - a Practitioner’s Perspective
How do I write Testable Javascript?
How do I write Testable Javascript
How do I write testable javascript?
JavaScript development methodology

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Electronic commerce courselecture one. Pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
KodekX | Application Modernization Development
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Machine learning based COVID-19 study performance prediction
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
MYSQL Presentation for SQL database connectivity
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Chapter 3 Spatial Domain Image Processing.pdf
Encapsulation_ Review paper, used for researhc scholars
Mobile App Security Testing_ A Comprehensive Guide.pdf
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Review of recent advances in non-invasive hemoglobin estimation
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
The Rise and Fall of 3GPP – Time for a Sabbatical?
NewMind AI Weekly Chronicles - August'25 Week I
Dropbox Q2 2025 Financial Results & Investor Presentation
Reach Out and Touch Someone: Haptics and Empathic Computing
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Electronic commerce courselecture one. Pdf
Building Integrated photovoltaic BIPV_UPV.pdf
KodekX | Application Modernization Development
Per capita expenditure prediction using model stacking based on satellite ima...
Machine learning based COVID-19 study performance prediction
NewMind AI Monthly Chronicles - July 2025
Network Security Unit 5.pdf for BCA BBA.
MYSQL Presentation for SQL database connectivity

Intro To JavaScript Unit Testing - Ran Mizrahi

  • 1. Introduction to { JavaScript Testing } Ran Mizrahi (@ranm8) Founder and CEO @ CoCycles
  • 2. About { Me } • Founder and CEO of CoCycles. • Former Open Source Dpt. Leader of CodeOasis. • Architected and lead the development of the Wix App Market. • Full-stack and hands-on software engineer.
  • 3. Why Do Software Projects { Fail } ? Production Maintenance • Deliver late or over budget. • Deliver the wrong thing. • Unstable in production. • Expensive maintenance. • Long adjustment to market needs. • Long development cycles.
  • 4. Why Do Software Projects { Fail } ?
  • 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); }); }); }
  • 6. 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 Why Test Your { Code } ?
  • 7. { Test-Driven Development } To The Rescue Methodology for using automated unit tests to drive software design, quality and stability.
  • 8. { Test-Driven Development } To The Rescue 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.
  • 9. Seems Great But How Much Longer Does { TDD Take } ? 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.
  • 10. 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.
  • 11. { BDD } Behaviour-Driven Development What exactly are we testing?! Test-Driven Development
  • 12. { BDD } Behaviour-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...
  • 13. { BDD } Behaviour-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 """
  • 14. Main { Test Types } • Unit Testing • Integration Testing • Functional Testing
  • 15. { 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.)
  • 16. TDD/BDD Using { Mocha and ChaiJS } Mocha Mocha is a feature-rich JavaScript test frameworks running on node and the browser, making asynchronies tests easy. Main features: • Supports both TDD and BDD styles. • Simple async testing. • 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.).
  • 17. TDD/BDD Using { Mocha and ChaiJS } ChaiJS Chai is a BDD / TDD assertion library for node and the browser that can be paired with any JavaScript testing framework. Main features: • BDD/TDD style. • Compatible with all test frameworks. • Both node.js and browser compatible. • Standalone assertion library. • Extendable
  • 18. TDD/BDD Using { Mocha and ChaiJS } Installing Mocha and Chai Install mocha globally using npm: $ npm install mocha -g Install Chai (Locally): $ npm install chai
  • 19. TDD/BDD Using { Mocha and ChaiJS } “Normal” test: var expect = require(‘chai').expect; 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); }); }); }); Run it.. $ mocha --reporter spec Array #indexOf() ✓ Expect -1 when the value is not present 1 test complete (5 ms)
  • 20. TDD/BDD Using { Mocha and ChaiJS } Async test: var expect = require(‘chai').expect; 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...
  • 21. Back To { Our Code }
  • 22. 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); }); }); }
  • 23. First, Let’s { Write The Tests } What to test in our case: • Full name concatenation. • API call data. • Request callback. What not to test : • DOM manipulations - Functional testing (e.g. WebDriver). • API requests - Integration testing.
  • 24. First, Let’s { Write The Unit Tests } describe('#saveUser()', function() { it('should call http service with method POST, path /user, and the user object', function() { }); it('should compose the full name in to the user object', function() { }); it('should only return the payload from the response object', function() { }); }); });
  • 25. The { Implementation } function userService($http, baseUrl) { baseUrl = baseUrl || 'http://google.com/api'; function composeFullName(firstName, lastName) { return firstName + ' ' + lastName; } function returnPayload(response) { return response.payload; } function execute(path, body, method) { return $http({ url: baseUrl + path, method: method || 'GET', data: body }); } return { saveUser: function(user) { user.fullName = composeFullName(user.firstName, user.lastName); return execute('/user', user, 'POST').then(returnPayload); } }; }
  • 26. Implement { Our Unit Tests } describe('user service', function() { var userService, httpMock, thenFunc; function createHttpMock() { thenFunc = sinon.stub(); httpMock = sinon.stub().returns({ then: thenFunc }); } beforeEach(function() { createHttpMock(); userService = UserService(httpMock); }); function getUser() { return { firstName: 'Ran', lastName: 'Mizrahi' }; }
  • 27. Implement { Our Unit Tests } describe('#saveUser()', function() { var user; beforeEach(function() { user = getUser(); userService.saveUser(user); }); it('should call http service with method POST, path /user, and the user object', function() { expect(httpMock).to.have.been.calledWith({ url: 'http://google.com/api/user', method: 'POST', data: user }); }); it('should compose the full name in to the user object', function() { expect(user.fullName).to.equal('Ran Mizrahi'); }); it('should only return the payload from the response object', function() { var returnPayload = thenFunc.args[0][0]; expect(returnPayload({ payload: 'Hello!!!' })).to.equal('Hello!!!'); }); }); });
  • 28. Run Those { Tests Again }
  • 29. 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.)
  • 30. Benefits of { Testing The 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 and simplicity. • Helps separating units to responsibilities.