SlideShare une entreprise Scribd logo
1  sur  96
Télécharger pour lire hors ligne
Mocha First Steps
Installing and running tests
Agenda
• JS Unit Testing	

• A first Mocha test	

• Running tests with Karma	

• IDE integration
Getting Ready To Test
• JS Unit tests (try) make sure our JS code
works well
Project Tree
index.html
 
- src
  - main.js
  - buttons.js
  - player.js
 
- style
  - master.css
  - home.css
 
Project Tree
index.html
test.html
 
- src
  - main.js
  - buttons.js
  - player.js
 
- style
  - master.css
  - home.css
 
- spec
  - test_button.js
  - test_player.js
What Mocha Isn’t
• No UI / CSS testing 	

• No server testing
Testing How
Testing Libraries
• Let’s try to write test program for Array	

• Verify indexOf(...) actually works
Array#indexof
var arr1 = [10, 20, 30, 40];
 
if ( arr1.indexOf(20) === 1 ) {
  console.log('success!');
} else {
  console.log('error');
}
What Went Wrong
• Hard to debug	

• Hard to run automatically
We Need …
We Need …
Testing Libraries
• A testing library tells you how to structure
your testing code	


• We’ll use mocha


http://visionmedia.github.io/mocha/
Hello Mocha
var assert = chai.assert;
var array = [10,20,30,40];
 
describe('Array', function() {
!
  describe('#indexOf()', function() {
!
    it('should return -1 when the value is not present',
function() {      
     
assert.equal(array.indexOf(7), -1);
   
}
);
  });
});
Hello Mocha
• describe() defines a block	

• it() defines functionality
Assertions

•

Uses a separate assertions
library	


•
•

I went with Chai	

http://chaijs.com/
Running Our Test:
Karma
Meet Karma
• A test runner for JS	

• Integrates with many IDEs	

• Integrates with CI servers	

• http://karma-runner.github.io/0.10/
index.html
Karma Architecture
Karma
Server
Karma Getting Started
# run just once to install
npm install karma -g
 
# create a project directory
mkdir myproject
cd myproject
 
# create karma configuration file
karma init
Karma Config
• Just a JavaScript file	

• keys determine how test should run
Karma Config
• files is a list of JS files to include in the test	

• Can use wildcards
Karma Config
• browsers is a list of supported browsers
Running Tests
# start a karma server
karma start
 
# execute tests
karma run
IDE Integration
What We Learned
• Mocha is a JS library that helps us write
unit tests	


• Karma is a JS library that helps us run them
Q &A
Advanced Mocha
How to write awesome tests
Agenda
• Flow control: before, after, beforeEach,
afterEach	


• Writing async tests	

• Fixtures and DOM testing
Let’s Flow
describe('Test 1', function() {
  it('should do X', function() {
    var p1 = new Player('bob');
    var p2 = new Player('John');
    var game = new GameEngine(p1, p2);
 
    // test stuff with game
  });
 
  it('should do Y', function() {
    var p1 = new Player('bob');
    var p2 = new Player('John');
    var game = new GameEngine(p1, p2);
 
    // test stuff with game
  });
});
Let’s Flow
describe('Test 1', function() {
  it('should do X', function() {
    var p1 = new Player('bob');
    var p2 = new Player('John');
    var game = new GameEngine(p1, p2);
 
    // test stuff with game
  });
 
  it('should do Y', function() {
    var p1 = new Player('bob');
    var p2 = new Player('John');
    var game = new GameEngine(p1, p2);
 
    // test stuff with game
  });
});

Same code...
A Better Scheme
•

beforeEach() runs
before each test	


•

also has:	


•
•

afterEach() for
cleanups	


describe('Test 1', function() {!
  var game;!
 !
  beforeEach(function() {!
    var p1 = new Player('bob');!
    var p2 = new Player('John');!
    game = new GameEngine(p1, p2);!
  });!
 !
  it('should do X', function() {!
    // test stuff with game!
  });!

!

before() and
after() run once
in the suite

 !
  it('should do Y', function() {!
    // test stuff with game!
  });!
});
Async Testing
Async Theory
var x = 10
test x

x has the right value	

testing here is OK
Async Theory
$.get(...)
test result

Can’t test now, 	

result not yet ready
Async Theory
• Async calls take callbacks	

• We should tell mocha to wait
Async Code
describe('Test 1', function() {
 
  it('should do wait', function(done) {
    setTimeout(function() {
      // now we can test result
      assert(true);
      done();
    }, 1000);
  });
 
});
Async Code
Taking a function
argument tells
mocha the test will
only end after it’s
called

describe('Test 1', function() {
 
  it('should do wait', function(done) {
    setTimeout(function() {
      // now we can test result
      assert(true);
      done();
    }, 1000);
  });
 
});
Async Code
Calling the callback
ends the test

describe('Test 1', function() {
 
  it('should do wait', function(done) {
    setTimeout(function() {
      // now we can test result
      assert(true);
      done();
    }, 1000);
  });
 
});
Async Notes
• Always call done() or your test will fail on
timeout	


• Default timeout is 2 seconds
Controlling Timeouts
describe('Test 1', function() {
  // set suite specific timeout
  this.timeout(500);
 
  it('should do wait', function(done) {
    // test specific timeout
    this.timeout(2000);    
  });
});
Same goes for Ajax
describe('Test 1', function() {
  // set suite specific timeout
  this.timeout(5000);
 
  it('should get user photo', function(done) {
    $.get('profile.png', function(data) {
      // run tests on data
      done();
    });
  });
});
DOM Testing
Theory
“Real” HTML
body
h1
div

body
img

div

“Test” HTML
Theory
“Real” HTML
body
h1
div

body
img

div

“Test” HTML

img
Theory
images.js
$('img.thumbnail').css({
width: 200,
height: 200
});

fixture.html
<img class="thumbmail" src="home.png" />
Using Fixtures
before(function() {
fixture_el = document.createElement('div');
fixture_el.id = "fixture";
!
document.body.appendChild(fixture_el);
});
!
beforeEach(function() {
fixture_el.innerHTML = window.__html__["fixture.html"];
});
!
Almost Ready
• HTML files are not served by default	

• We need to tell karma to serve it
Serving HTMLs
• Modify files section to include the last
(HTML) pattern

// list of files / patterns to load in the browser
files: [
'lib/**/*.js',
'plugins/**/*.js',
'test/fixtures/*.html',
'spec/*.js'
],
Testing a jQuery Plugin
it('should change the header text lowercase', function() {
$('.truncate').succinct({ size: 100 });
!
var result = $('.truncate').text();
assert.equal( result.length , 100 );
});
Fixtures & DOM
• Define DOM fragments in HTML files	

• Load from test suite	

• Test and clean up
Spying With Sinon
Stubs, Spies and Mock Objects explained
Agenda
• Reasons to mock	

• Vanilla mocking	

• How sinon can help	

• Stubs and Spies	

• Faking timers	

• Faking the server
Reasons To Mock
Reasons To Mock
$.ajax

setTimeout
PersonalData
Reasons To Mock
$.ajax

setTimeout
PersonalData
Reasons To Mock
• PersonalData object can save data to
server	


• If saving failed, it retries 3 times
Reasons To Mock
• Both server and clock are external	

• We prefer to test in isolation
What We Can Do
• Provide our own $.ajax, that won’t go to
the server	


• Provide our own setTimeout that won’t
wait for the time to pass
What We Can Do
• Lab: Given the class here


https://gist.github.com/ynonp/6667146	


• Write a test case to verify sendData
actually retried 3 times
What We Can Do
• Solution:


https://gist.github.com/ynonp/6667284
Mocking Notes
• Solution is far from perfect. 	

• After the test our “fake” methods remain	

• Writing “fake” methods was not trivial
This Calls for Sinon
About Sinon
• A JS mocking library	

• Helps create fake objects	

• Helps tracking them
About Sinon
• Homepage:


http://sinonjs.org/	


• Google Group:


http://groups.google.com/group/sinonjs	


• IRC Channel:


#sinon.js on freenode
Solving with Sinon
• Here’s how sinon might help us with the
previous task	


• Code:


https://gist.github.com/ynonp/6667378
Solution Notes
• Sinon’s fake timer was easier to use than
writing our own	


• Now we have a synchronous test (instead
of async)
Let’s Talk About Sinon
Spies
• A spy is a function that provides the test
code with info about how it was used
Spies Demo
describe('Sinon', function() {
describe('spies', function() {

!
!
!
!
!

it('should keep count', function() {
var s = sinon.spy();
s();
assert.isTrue(s.calledOnce);
s();
assert.isTrue(s.calledTwice);
s();
assert.equal(s.callCount, 3);

});
});
});
Spy On Existing Funcs
describe('Sinon', function() {
describe('spies', function() {
!
it('should keep count', function() {
var p = new PersonalData();
var spy = sinon.spy(p, 'sendData');
!
p.sendData();
!
assert.isTrue( spy.calledOnce );
});
});
});
Spies Notes
• Full API:


http://sinonjs.org/docs/#spies	


• Tip: Use as callbacks
Spy + Action = Stub
Stub Demo
• Let’s fix our starting example	

• We’ll replace $.ajax with a stub	

• That stub always fails
Stub Demo
var stub = sinon.stub(jQuery, 'ajax').yieldsTo('error');
!
describe('Data', function() {
describe('#sendData()', function() {
!
it('should retry 3 times before quitting', function() {
var p = new PersonalData();
p.sendData();
assert.equal(stub.callCount, 1);
});
});
});
What Can Stubs Do
var callback = sinon.stub();
!
callback.withArgs(42).returns(1);
!
callback.withArgs(1).throws("TypeError");
!
Stubs API
• Full Stubs API docs:


http://sinonjs.org/docs/#stubs	


• Main actions:	

• return stuff	

• throw stuff	

• call stuff
Spies Lab
• Given code here:


https://gist.github.com/ynonp/7101081	


• Fill in the blanks to make the tests pass
Fake Timers
• Use sinon.useFakeTimers() to create a
fake timer	


• Use clock.restore() to clear fake timers
Fake Timers
• Use tick(...) to advance	

• Affected methods:	

• setTimeout, setInterval, clearTimeout,
clearInterval	


• Date constructor
Fake Servers
• Testing client/server communication is hard	

• Use fake servers to simplify it
Fake Servers
$.ajax

PersonalData
Fake Servers
Fake

$.ajax

PersonalData
Let’s write a test for the following class
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.

function Person(id) {
  var self = this;
 
  self.load = function() {
    var url = '/users/' + id;
 
    $.get('/users/' + id, function(info) {
      self.name = info.name;
      self.favorite_color = info.favorite_color;
    });
  };
}
Testing Plan
• Set-up a fake server	

• Create a new Person	

• call load()	

• verify fields data
Setting Up The Server
1.
2.
3.
4.
5.
6.
7.
8.
9.

var server = sinon.fakeServer.create();
 
var headers  = {"Content-Type" : "application/json"};
var response = JSON.stringify(
                {"name" : "joe", "favorite_color": "blue" });
 
server.respondWith("GET", "/users/7",
                   [200, headers, response]);
// now requesting /user/info.php returns joe's info as a JSON
Loading a Person
1.
2.
3.
4.
5.
6.

var p = new Person(7);
// sends a request
p.load();
 
// now we have 1 pending request, let's fake the response
server.respond();
Verifying the Data
1.
2.
3.
4.
5.
6.

// finally, verify data
expect(p.name).to.eq('joe');
expect(p.favorite_color).to.eq('blue');
 
// and restore AJAX behavior
server.restore();
Fake Server
• Use respondWith() to set up routes	

• Use respond() to send the response
Fake Server
• Regexps are also supported, so this works:
1.
2.
3.
4.
5.
6.

server.respondWith(//todo-items/(d+)/, function (xhr, id) {
    xhr.respond(
      200,
      { "Content-Type": "application/json" },
      '[{ "id": ' + id + ' }]');
});
Fake Server
• For fine grained control, consider fake
XMLHttpRequest 	


• http://sinonjs.org/docs/#server
Wrapping Up
Wrapping Up
• Unit tests work best in isolation	

• Sinon will help you isolate units, by faking
their dependencies
Wrapping Up
• Write many tests	

• Each test verifies a small chunk of code	

• Don’t test everything
Online Resources

• Chai:


http://chaijs.com/	


• Mocha:


http://visionmedia.github.io/mocha/	


• Sinon:


http://sinonjs.org/	


• Karma (test runner):


http://karma-runner.github.io/0.10/index.html
Thanks For Listening
• Ynon Perek	

• http://ynonperek.com	

• ynon@ynonperek.com

Contenu connexe

Tendances

Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyIgor Napierala
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaExoLeaders.com
 
Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)Deutsche Post
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsFITC
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingLars Thorup
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Roy Yu
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineGil Fink
 
JavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaJavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaChristopher Bartling
 
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma Christopher Bartling
 
Unit tests in node.js
Unit tests in node.jsUnit tests in node.js
Unit tests in node.jsRotem Tamir
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSJim Lynch
 
Unit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and KarmaUnit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and KarmaAndrey Kolodnitsky
 
Testing JavaScript Applications
Testing JavaScript ApplicationsTesting JavaScript Applications
Testing JavaScript ApplicationsThe Rolling Scopes
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express MiddlewareMorris Singer
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSKnoldus Inc.
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Сергей Больщиков "Protractor Tips & Tricks"
Сергей Больщиков "Protractor Tips & Tricks"Сергей Больщиков "Protractor Tips & Tricks"
Сергей Больщиков "Protractor Tips & Tricks"Fwdays
 

Tendances (20)

Jasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishyJasmine - why JS tests don't smell fishy
Jasmine - why JS tests don't smell fishy
 
Good karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with KarmaGood karma: UX Patterns and Unit Testing in Angular with Karma
Good karma: UX Patterns and Unit Testing in Angular with Karma
 
Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)Javascript Test Automation Workshop (21.08.2014)
Javascript Test Automation Workshop (21.08.2014)
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit Testing
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Angular testing
Angular testingAngular testing
Angular testing
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
 
JavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and KarmaJavaScript TDD with Jasmine and Karma
JavaScript TDD with Jasmine and Karma
 
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma JavaScript Test-Driven Development with Jasmine 2.0 and Karma
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
 
Unit tests in node.js
Unit tests in node.jsUnit tests in node.js
Unit tests in node.js
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJS
 
Unit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and KarmaUnit testing in JavaScript with Jasmine and Karma
Unit testing in JavaScript with Jasmine and Karma
 
Testing JavaScript Applications
Testing JavaScript ApplicationsTesting JavaScript Applications
Testing JavaScript Applications
 
Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express Middleware
 
Unit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJSUnit Testing and Coverage for AngularJS
Unit Testing and Coverage for AngularJS
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Сергей Больщиков "Protractor Tips & Tricks"
Сергей Больщиков "Protractor Tips & Tricks"Сергей Больщиков "Protractor Tips & Tricks"
Сергей Больщиков "Protractor Tips & Tricks"
 

Similaire à Unit Testing JavaScript Applications

Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testingMats Bryntse
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchMats Bryntse
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineGil Fink
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWHolger Grosse-Plankermann
 
Unit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and HowsUnit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and Howsatesgoral
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
UI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected JourneyUI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected JourneyOren Farhi
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupErnest Jumbe
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
Awesomeness of JavaScript…almost
Awesomeness of JavaScript…almostAwesomeness of JavaScript…almost
Awesomeness of JavaScript…almostQuinton Sheppard
 
In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingAnna Khabibullina
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It'sJim Lynch
 
Node.js Development Workflow Automation with Grunt.js
Node.js Development Workflow Automation with Grunt.jsNode.js Development Workflow Automation with Grunt.js
Node.js Development Workflow Automation with Grunt.jskiyanwang
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockRobot Media
 
CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!Ortus Solutions, Corp
 

Similaire à Unit Testing JavaScript Applications (20)

Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Java script unit testing
Java script unit testingJava script unit testing
Java script unit testing
 
Testing Ext JS and Sencha Touch
Testing Ext JS and Sencha TouchTesting Ext JS and Sencha Touch
Testing Ext JS and Sencha Touch
 
Performance patterns
Performance patternsPerformance patterns
Performance patterns
 
Quick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmineQuick tour to front end unit testing using jasmine
Quick tour to front end unit testing using jasmine
 
Jest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRWJest: Frontend Testing richtig gemacht @WebworkerNRW
Jest: Frontend Testing richtig gemacht @WebworkerNRW
 
Unit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and HowsUnit Testing - The Whys, Whens and Hows
Unit Testing - The Whys, Whens and Hows
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
UI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected JourneyUI Testing Best Practices - An Expected Journey
UI Testing Best Practices - An Expected Journey
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup Group
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Awesomeness of JavaScript…almost
Awesomeness of JavaScript…almostAwesomeness of JavaScript…almost
Awesomeness of JavaScript…almost
 
In search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testingIn search of JavaScript code quality: unit testing
In search of JavaScript code quality: unit testing
 
NodeJS
NodeJSNodeJS
NodeJS
 
Describe's Full of It's
Describe's Full of It'sDescribe's Full of It's
Describe's Full of It's
 
Node.js Development Workflow Automation with Grunt.js
Node.js Development Workflow Automation with Grunt.jsNode.js Development Workflow Automation with Grunt.js
Node.js Development Workflow Automation with Grunt.js
 
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMockUnit testing in iOS featuring OCUnit, GHUnit & OCMock
Unit testing in iOS featuring OCUnit, GHUnit & OCMock
 
Java Performance Tuning
Java Performance TuningJava Performance Tuning
Java Performance Tuning
 
CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!CBDW2014 - MockBox, get ready to mock your socks off!
CBDW2014 - MockBox, get ready to mock your socks off!
 

Plus de Ynon Perek

09 performance
09 performance09 performance
09 performanceYnon Perek
 
Mobile Web Intro
Mobile Web IntroMobile Web Intro
Mobile Web IntroYnon Perek
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threadsYnon Perek
 
Mobile Devices
Mobile DevicesMobile Devices
Mobile DevicesYnon Perek
 
Architecture app
Architecture appArchitecture app
Architecture appYnon Perek
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScriptYnon Perek
 
Introduction to Selenium and Ruby
Introduction to Selenium and RubyIntroduction to Selenium and Ruby
Introduction to Selenium and RubyYnon Perek
 
Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application TestingYnon Perek
 
Qt Design Patterns
Qt Design PatternsQt Design Patterns
Qt Design PatternsYnon Perek
 
Web Application Security
Web Application SecurityWeb Application Security
Web Application SecurityYnon Perek
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM ManipulationsYnon Perek
 

Plus de Ynon Perek (20)

Regexp
RegexpRegexp
Regexp
 
Html5 intro
Html5 introHtml5 intro
Html5 intro
 
09 performance
09 performance09 performance
09 performance
 
Mobile Web Intro
Mobile Web IntroMobile Web Intro
Mobile Web Intro
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Vimperl
VimperlVimperl
Vimperl
 
Syllabus
SyllabusSyllabus
Syllabus
 
Mobile Devices
Mobile DevicesMobile Devices
Mobile Devices
 
Network
NetworkNetwork
Network
 
Architecture app
Architecture appArchitecture app
Architecture app
 
Cryptography
CryptographyCryptography
Cryptography
 
How to write easy-to-test JavaScript
How to write easy-to-test JavaScriptHow to write easy-to-test JavaScript
How to write easy-to-test JavaScript
 
Introduction to Selenium and Ruby
Introduction to Selenium and RubyIntroduction to Selenium and Ruby
Introduction to Selenium and Ruby
 
Introduction To Web Application Testing
Introduction To Web Application TestingIntroduction To Web Application Testing
Introduction To Web Application Testing
 
Accessibility
AccessibilityAccessibility
Accessibility
 
Angularjs
AngularjsAngularjs
Angularjs
 
Js memory
Js memoryJs memory
Js memory
 
Qt Design Patterns
Qt Design PatternsQt Design Patterns
Qt Design Patterns
 
Web Application Security
Web Application SecurityWeb Application Security
Web Application Security
 
JavaScript DOM Manipulations
JavaScript DOM ManipulationsJavaScript DOM Manipulations
JavaScript DOM Manipulations
 

Dernier

Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxnull - The Open Security Community
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDGMarianaLemus7
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 

Dernier (20)

Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptxMaking_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
Making_way_through_DLL_hollowing_inspite_of_CFG_by_Debjeet Banerjee.pptx
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
APIForce Zurich 5 April Automation LPDG
APIForce Zurich 5 April  Automation LPDGAPIForce Zurich 5 April  Automation LPDG
APIForce Zurich 5 April Automation LPDG
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 

Unit Testing JavaScript Applications

  • 1. Mocha First Steps Installing and running tests
  • 2. Agenda • JS Unit Testing • A first Mocha test • Running tests with Karma • IDE integration
  • 3. Getting Ready To Test • JS Unit tests (try) make sure our JS code works well
  • 4. Project Tree index.html   - src   - main.js   - buttons.js   - player.js   - style   - master.css   - home.css  
  • 5. Project Tree index.html test.html   - src   - main.js   - buttons.js   - player.js   - style   - master.css   - home.css   - spec   - test_button.js   - test_player.js
  • 6. What Mocha Isn’t • No UI / CSS testing • No server testing
  • 8. Testing Libraries • Let’s try to write test program for Array • Verify indexOf(...) actually works
  • 9. Array#indexof var arr1 = [10, 20, 30, 40];   if ( arr1.indexOf(20) === 1 ) {   console.log('success!'); } else {   console.log('error'); }
  • 10. What Went Wrong • Hard to debug • Hard to run automatically
  • 13. Testing Libraries • A testing library tells you how to structure your testing code • We’ll use mocha
 http://visionmedia.github.io/mocha/
  • 14. Hello Mocha var assert = chai.assert; var array = [10,20,30,40];   describe('Array', function() { !   describe('#indexOf()', function() { !     it('should return -1 when the value is not present', function() {             assert.equal(array.indexOf(7), -1);     } );   }); });
  • 15. Hello Mocha • describe() defines a block • it() defines functionality
  • 16. Assertions • Uses a separate assertions library • • I went with Chai http://chaijs.com/
  • 18. Meet Karma • A test runner for JS • Integrates with many IDEs • Integrates with CI servers • http://karma-runner.github.io/0.10/ index.html
  • 20. Karma Getting Started # run just once to install npm install karma -g   # create a project directory mkdir myproject cd myproject   # create karma configuration file karma init
  • 21. Karma Config • Just a JavaScript file • keys determine how test should run
  • 22. Karma Config • files is a list of JS files to include in the test • Can use wildcards
  • 23. Karma Config • browsers is a list of supported browsers
  • 24. Running Tests # start a karma server karma start   # execute tests karma run
  • 26. What We Learned • Mocha is a JS library that helps us write unit tests • Karma is a JS library that helps us run them
  • 27. Q &A
  • 28. Advanced Mocha How to write awesome tests
  • 29. Agenda • Flow control: before, after, beforeEach, afterEach • Writing async tests • Fixtures and DOM testing
  • 30. Let’s Flow describe('Test 1', function() {   it('should do X', function() {     var p1 = new Player('bob');     var p2 = new Player('John');     var game = new GameEngine(p1, p2);       // test stuff with game   });     it('should do Y', function() {     var p1 = new Player('bob');     var p2 = new Player('John');     var game = new GameEngine(p1, p2);       // test stuff with game   }); });
  • 31. Let’s Flow describe('Test 1', function() {   it('should do X', function() {     var p1 = new Player('bob');     var p2 = new Player('John');     var game = new GameEngine(p1, p2);       // test stuff with game   });     it('should do Y', function() {     var p1 = new Player('bob');     var p2 = new Player('John');     var game = new GameEngine(p1, p2);       // test stuff with game   }); }); Same code...
  • 32. A Better Scheme • beforeEach() runs before each test • also has: • • afterEach() for cleanups describe('Test 1', function() {!   var game;!  !   beforeEach(function() {!     var p1 = new Player('bob');!     var p2 = new Player('John');!     game = new GameEngine(p1, p2);!   });!  !   it('should do X', function() {!     // test stuff with game!   });! ! before() and after() run once in the suite  !   it('should do Y', function() {!     // test stuff with game!   });! });
  • 34. Async Theory var x = 10 test x x has the right value testing here is OK
  • 35. Async Theory $.get(...) test result Can’t test now, result not yet ready
  • 36. Async Theory • Async calls take callbacks • We should tell mocha to wait
  • 37. Async Code describe('Test 1', function() {     it('should do wait', function(done) {     setTimeout(function() {       // now we can test result       assert(true);       done();     }, 1000);   });   });
  • 38. Async Code Taking a function argument tells mocha the test will only end after it’s called describe('Test 1', function() {     it('should do wait', function(done) {     setTimeout(function() {       // now we can test result       assert(true);       done();     }, 1000);   });   });
  • 39. Async Code Calling the callback ends the test describe('Test 1', function() {     it('should do wait', function(done) {     setTimeout(function() {       // now we can test result       assert(true);       done();     }, 1000);   });   });
  • 40. Async Notes • Always call done() or your test will fail on timeout • Default timeout is 2 seconds
  • 41. Controlling Timeouts describe('Test 1', function() {   // set suite specific timeout   this.timeout(500);     it('should do wait', function(done) {     // test specific timeout     this.timeout(2000);       }); });
  • 42. Same goes for Ajax describe('Test 1', function() {   // set suite specific timeout   this.timeout(5000);     it('should get user photo', function(done) {     $.get('profile.png', function(data) {       // run tests on data       done();     });   }); });
  • 47. Using Fixtures before(function() { fixture_el = document.createElement('div'); fixture_el.id = "fixture"; ! document.body.appendChild(fixture_el); }); ! beforeEach(function() { fixture_el.innerHTML = window.__html__["fixture.html"]; }); !
  • 48. Almost Ready • HTML files are not served by default • We need to tell karma to serve it
  • 49. Serving HTMLs • Modify files section to include the last (HTML) pattern // list of files / patterns to load in the browser files: [ 'lib/**/*.js', 'plugins/**/*.js', 'test/fixtures/*.html', 'spec/*.js' ],
  • 50. Testing a jQuery Plugin it('should change the header text lowercase', function() { $('.truncate').succinct({ size: 100 }); ! var result = $('.truncate').text(); assert.equal( result.length , 100 ); });
  • 51. Fixtures & DOM • Define DOM fragments in HTML files • Load from test suite • Test and clean up
  • 52. Spying With Sinon Stubs, Spies and Mock Objects explained
  • 53. Agenda • Reasons to mock • Vanilla mocking • How sinon can help • Stubs and Spies • Faking timers • Faking the server
  • 57. Reasons To Mock • PersonalData object can save data to server • If saving failed, it retries 3 times
  • 58. Reasons To Mock • Both server and clock are external • We prefer to test in isolation
  • 59. What We Can Do • Provide our own $.ajax, that won’t go to the server • Provide our own setTimeout that won’t wait for the time to pass
  • 60. What We Can Do • Lab: Given the class here
 https://gist.github.com/ynonp/6667146 • Write a test case to verify sendData actually retried 3 times
  • 61. What We Can Do • Solution:
 https://gist.github.com/ynonp/6667284
  • 62. Mocking Notes • Solution is far from perfect. • After the test our “fake” methods remain • Writing “fake” methods was not trivial
  • 63. This Calls for Sinon
  • 64. About Sinon • A JS mocking library • Helps create fake objects • Helps tracking them
  • 65. About Sinon • Homepage:
 http://sinonjs.org/ • Google Group:
 http://groups.google.com/group/sinonjs • IRC Channel:
 #sinon.js on freenode
  • 66. Solving with Sinon • Here’s how sinon might help us with the previous task • Code:
 https://gist.github.com/ynonp/6667378
  • 67. Solution Notes • Sinon’s fake timer was easier to use than writing our own • Now we have a synchronous test (instead of async)
  • 69. Spies • A spy is a function that provides the test code with info about how it was used
  • 70. Spies Demo describe('Sinon', function() { describe('spies', function() { ! ! ! ! ! it('should keep count', function() { var s = sinon.spy(); s(); assert.isTrue(s.calledOnce); s(); assert.isTrue(s.calledTwice); s(); assert.equal(s.callCount, 3); }); }); });
  • 71. Spy On Existing Funcs describe('Sinon', function() { describe('spies', function() { ! it('should keep count', function() { var p = new PersonalData(); var spy = sinon.spy(p, 'sendData'); ! p.sendData(); ! assert.isTrue( spy.calledOnce ); }); }); });
  • 72. Spies Notes • Full API:
 http://sinonjs.org/docs/#spies • Tip: Use as callbacks
  • 73. Spy + Action = Stub
  • 74. Stub Demo • Let’s fix our starting example • We’ll replace $.ajax with a stub • That stub always fails
  • 75. Stub Demo var stub = sinon.stub(jQuery, 'ajax').yieldsTo('error'); ! describe('Data', function() { describe('#sendData()', function() { ! it('should retry 3 times before quitting', function() { var p = new PersonalData(); p.sendData(); assert.equal(stub.callCount, 1); }); }); });
  • 76. What Can Stubs Do var callback = sinon.stub(); ! callback.withArgs(42).returns(1); ! callback.withArgs(1).throws("TypeError"); !
  • 77. Stubs API • Full Stubs API docs:
 http://sinonjs.org/docs/#stubs • Main actions: • return stuff • throw stuff • call stuff
  • 78. Spies Lab • Given code here:
 https://gist.github.com/ynonp/7101081 • Fill in the blanks to make the tests pass
  • 79. Fake Timers • Use sinon.useFakeTimers() to create a fake timer • Use clock.restore() to clear fake timers
  • 80. Fake Timers • Use tick(...) to advance • Affected methods: • setTimeout, setInterval, clearTimeout, clearInterval • Date constructor
  • 81. Fake Servers • Testing client/server communication is hard • Use fake servers to simplify it
  • 84. Let’s write a test for the following class 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. function Person(id) {   var self = this;     self.load = function() {     var url = '/users/' + id;       $.get('/users/' + id, function(info) {       self.name = info.name;       self.favorite_color = info.favorite_color;     });   }; }
  • 85. Testing Plan • Set-up a fake server • Create a new Person • call load() • verify fields data
  • 86. Setting Up The Server 1. 2. 3. 4. 5. 6. 7. 8. 9. var server = sinon.fakeServer.create();   var headers  = {"Content-Type" : "application/json"}; var response = JSON.stringify(                 {"name" : "joe", "favorite_color": "blue" });   server.respondWith("GET", "/users/7",                    [200, headers, response]); // now requesting /user/info.php returns joe's info as a JSON
  • 87. Loading a Person 1. 2. 3. 4. 5. 6. var p = new Person(7); // sends a request p.load();   // now we have 1 pending request, let's fake the response server.respond();
  • 88. Verifying the Data 1. 2. 3. 4. 5. 6. // finally, verify data expect(p.name).to.eq('joe'); expect(p.favorite_color).to.eq('blue');   // and restore AJAX behavior server.restore();
  • 89. Fake Server • Use respondWith() to set up routes • Use respond() to send the response
  • 90. Fake Server • Regexps are also supported, so this works: 1. 2. 3. 4. 5. 6. server.respondWith(//todo-items/(d+)/, function (xhr, id) {     xhr.respond(       200,       { "Content-Type": "application/json" },       '[{ "id": ' + id + ' }]'); });
  • 91. Fake Server • For fine grained control, consider fake XMLHttpRequest • http://sinonjs.org/docs/#server
  • 93. Wrapping Up • Unit tests work best in isolation • Sinon will help you isolate units, by faking their dependencies
  • 94. Wrapping Up • Write many tests • Each test verifies a small chunk of code • Don’t test everything
  • 95. Online Resources • Chai:
 http://chaijs.com/ • Mocha:
 http://visionmedia.github.io/mocha/ • Sinon:
 http://sinonjs.org/ • Karma (test runner):
 http://karma-runner.github.io/0.10/index.html
  • 96. Thanks For Listening • Ynon Perek • http://ynonperek.com • ynon@ynonperek.com