SlideShare a Scribd company logo
JavaScript Test-Driven Development
with Jasmine and Karma
!
!
!
!
!
!
!
!
Christopher Bartling
1
Justifying test-driven JavaScript development
• JavaScript is a first-class citizen in our products.
• Modern web applications are predominantly written in
JavaScript with some markup.
• JavaScript usage is growing, even on the server-side.
• Production quality code should be tested.
• Unit, integration, and functional/acceptance testing.
• Don’t practice reckless development!
2
Quick review of test-driven development
• Use unit tests to drive development and design.
• Write the test first, then the code.
• See the test fail, then make it pass.
• Importance of spiking before test-first development.
• Test coverage of your code remains high because of test-
first approach.
• A fast test suite is typically run frequently.
3
Benefits of test-driven development
• Design tool.
• Helps build confidence.
• Executable documentation of the code base.
• Tests infer the intent of the code.
• Code base is continually executed when test suites are
run in continuous integration environments.
• Avoid code rot.
4
The test-driven development cadence
Start with a failing
test
Write code to make
the test pass
Refactor code
and tests
5
The importance of “spiking”
• Test-driven development is grounded in the assumption
that you know your tools and what you are building.
• When unsure about how the solution should proceed,
use spike solutions to learn more about what you’re
attempting to do.
• Spike solutions are not production code.
• Spike solutions are typically thrown away. Value is in the
problem domain learning that takes place.
6
karma
• JavaScript test runner that integrates with a number of
browser runners.
• Dependent on node.js, distributed as a node package.
• Command line tool, but also integrated into JetBrains
WebStorm IDE.
➜ calculator git:(master) ✗ karma start

INFO [karma]: Karma v0.10.8 server started at http://localhost:9876/

INFO [launcher]: Starting browser PhantomJS

INFO [PhantomJS 1.9.2 (Mac OS X)]: Connected on socket TbzZHmxXJQ3aKLGcIIel

PhantomJS 1.9.2 (Mac OS X): Executed 12 of 12 SUCCESS (0.022 secs / 0.003 secs)
7
phantom.js
• Headless WebKit browser runner, scriptable with a
JavaScript API
• Native support for various web standards
• DOM, Canvas, and SVG
• CSS selectors
• JSON
8
Introducing Jasmine
• Testing framework
• Suites possess a hierarchical structure
• Tests as specifications
• Matchers, both built-in and custom
• Spies, a test double pattern
9
Jasmine suite
describe("A specification suite", function() {



	 … 



});	
• Group specifications together using nested describe
function blocks.
• Also useful for delineating context-specific specifications.
10
Jasmine specification
describe("A specification suite", function() {



	 it(“contains spec with an expectation", function() {

	 	 expect(view.tagName).toBe(‘tr’);

	 });



});	
• Specifications are expressed with the it function.
• The description should read well in the report.
• Expectations are expressed with the expect function.
11
Jasmine matchers
12
• not	
• toBe	
• toEqual	
• toMatch	
• toBeDefined	
• toBeUndefined	
• toBeNull
• toBeTruthy	
• toBeFalsy	
• toContain	
• toBeLessThan	
• toBeGreaterThan	
• toBeCloseTo	
• toThrow
Jasmine setup using beforeEach
describe("PintailConsulting.ToDoListView", function() {

	 var view;



	 beforeEach(function(){

	 	 view = new PintailConsulting.ToDoListView();

	 });



	 it(“sets the tagName to ‘div’", function() {

	 	 expect(view.tagName).toBe(‘div’);

	 });

});
13
Jasmine tear down using afterEach
describe("PintailConsulting.ToDoListView", function() {

	 var view;



	 beforeEach(function(){

	 	 view = new PintailConsulting.ToDoListView();

	 });



	 afterEach(function(){

	 	 view = null;

	 });



	 it(“sets the tagName to ‘div’", function() {

	 	 expect(view.tagName).toBe(‘div’);

	 });

});
14
Jasmine custom matchers
beforeEach(function() { 

	 this.addMatchers({

	 	 toBeLessThan: function(expected) {

	 	 	 var actual = this.actual;

	 	 	 var notText = this.isNot ? " not" : "";



	 	 	 this.message = function () {

	 	 	 	 return "Expected " + actual + notText + 

	 	 	 	 	 	 " to be less than " + expected;

	 	 	 }

	 	 	 return actual < expected;

	 	 }

	 });

});
15
Demonstration
16
Jasmine spies
• Test double pattern.
• Interception-based test double mechanism provided by
the Jasmine library.
• Spies record invocations and invocation parameters,
allowing you to inspect the spy after exercising the SUT.
• Very similar to mock objects.
• More information at https://github.com/pivotal/jasmine/
wiki/Spies.
17
Jasmine spy usage
Spying and verifying invocation
var spy = spyOn(dependency, “render”);

systemUnderTest.display();

expect(spy).toHaveBeenCalled();	


Spying, verifying invocation and argument(s)
var spy = spyOn(dependency, “render”);

systemUnderTest.display(“Hello”);

expect(spy).toHaveBeenCalledWith(“Hello”);
18
Jasmine spy usage
Spying, verifying number of invocations and arguments for
each call
var spy = spyOn(Leaflet, “circle”).andCallThrough();

mapView.processResults(earthquakeJsonResults);

expect(spy).toHaveBeenCalled()

expect(circleConstructorSpy.callCount).toBe(2);

expect(circleConstructorSpy.argsForCall[0][0])

.toEqual([56.6812, -155.0237])
19
Loose matching with jasmine.any
• Accepts a constructor or “class” name as an expected
value.
• Returns true if the constructor matches the constructor
of the actual value.


var spy = jasmine.createSpy(My.Namespace, ’foo’);

foo(12, function(x) { return x * x; });
expect(spy).toHaveBeenCalledWith

	 (jasmine.any(Number), jasmine.any(Function));
20
Jasmine spy usage
• andCallThrough(): Allows the invocation to passthrough
to the real subject.
• andReturn(result): Return a hard-coded result.
• andCallFake(fakeImplFunction): Return a
dynamically generated result from a function.
• createSpy(identity): Manually create a spy.
• createSpyObj(identity, propertiesArray):
Creates a mock with multiple property spies.
21
Jasmine asynchronous support
• Use runs and waitsFor blocks and a latch function.
• The latch function polls until it returns true or the timeout
expires, whichever comes first.
• If the timeout expires, the specification fails with a
message.
• Kind of clunky to use.
22
Jasmine asynchronous example
describe("an async spec", function() { 

	 var done;



	 beforeEach(function() {

	 	 done = false;

	 	 var doStuff = function() {

	 	 	 // simulate async stuff and wait 10ms

	 	 	 setTimeout(function() { done = true; }, 10); 

	 	 };

	 	 runs(doStuff);

	 	 waitsFor(function() { return done; }, 

	 	 	 ‘The doStuff function should be done by now.’, 

	 	 	 100); 

	 });



	 it("did stuff", function() {

	 	 expect(done).toBe(true);

	 });

});
23
karma-coverage
• Test coverage plugin for karma
• https://github.com/karma-runner/karma-coverage
npm install karma-coverage --save-dev	
• Run karma with coverage configured (karma.conf.js)
• Generate reports using istanbul report
• Reports saved to the coverage subdirectory
24
Code coverage report
25
Unit testing tips
• Strive for one assertion per example.
• Allows all assertions to execute.
• Each assertion runs in a clean SUT setup.
• Avoid making live AJAX calls in your unit tests/specs.
• Spy/intercept the low-level AJAX invocations
(jQuery.ajax)
• Use fixture data for testing AJAX callbacks.
26
How do we sustain test-driven development?
• Practice, practice, practice!
• Code katas,
• Pair programming, even in remote situations.
• Screenhero, Hangouts, Skype
• Continuous integration server.
• Run your test suites often, preferably on every commit.
27
Functional/acceptance testing
• Very important part of the testing portfolio.
• Many tools support testing web-based user interfaces
today.
• Geb, Capybara, Cucumber{Ruby|jvm|js}, Protractor.js,
Concordian, spock
• You should strongly consider adding functional/
acceptance testing in your testing portfolio.
• Covers areas of code that unit testing cannot cover.
28
Tool references
• http://phantomjs.org
• http://karma-runner.github.io/
• http://gruntjs.com/
• http://bower.io/
• http://pivotal.github.io/jasmine/
• http://yeoman.io/
29
Recommended reading
• Secrets of the JavaScript Ninja - John Resig and Bear
Bibeault
• JavaScript: The Good Parts - Douglas Crockford
• Test-Driven JavaScript Development - Christian
Johansen
30
Learning resources
• Let’s Code: Test-Driven JavaScript
• http://www.letscodejavascript.com/
• Egghead.io
• http://egghead.io/
31
Code kata resources
• http://katas.softwarecraftsmanship.org/
• http://codekata.pragprog.com/
• http://projecteuler.net/
• http://codekatas.org/
32
Presentation GitHub repository
• https://github.com/cebartling/ncaa-basketball-
tournament
• The web-client directory contains this entire sample
Backbone.js-based application.
33
Thank you!
• Christopher Bartling
• @cbartling
• chris@pintailconsultingllc.com
34

More Related Content

What's hot (20)

PPT
Spring Core
Pushan Bhattacharya
 
PDF
Performance Tuning - Memory leaks, Thread deadlocks, JDK tools
Haribabu Nandyal Padmanaban
 
PPTX
Dependency Inversion Principle
Marco Mangia Musardo
 
PPT
Introduction to the Web API
Brad Genereaux
 
PPTX
CockroachDB
andrei moga
 
PPTX
Episode 19 - Asynchronous Apex - Batch apex & schedulers
Jitendra Zaa
 
PDF
Using MongoDB as a high performance graph database
Chris Clarke
 
PPTX
OLTP+OLAP=HTAP
EDB
 
PDF
Enterprise JavaBeans(EJB)
Armen Arzumanyan
 
PPTX
Salesforce asynchronous apex
Badan Singh Pundeer
 
PPTX
Spring Security 5
Jesus Perez Franco
 
PPTX
Maven Basics - Explained
Smita Prasad
 
PPTX
REST API Design
Devi Kiran G
 
PPTX
How to Lock Down Apache Kafka and Keep Your Streams Safe
confluent
 
PPT
Spring Boot in Action
Alex Movila
 
PDF
Scalability, Availability & Stability Patterns
Jonas Bonér
 
PDF
JCR, Sling or AEM? Which API should I use and when?
connectwebex
 
ODP
BDD with Cucumber
Knoldus Inc.
 
PDF
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
Brian Hong
 
PPTX
Spring Boot
Jiayun Zhou
 
Spring Core
Pushan Bhattacharya
 
Performance Tuning - Memory leaks, Thread deadlocks, JDK tools
Haribabu Nandyal Padmanaban
 
Dependency Inversion Principle
Marco Mangia Musardo
 
Introduction to the Web API
Brad Genereaux
 
CockroachDB
andrei moga
 
Episode 19 - Asynchronous Apex - Batch apex & schedulers
Jitendra Zaa
 
Using MongoDB as a high performance graph database
Chris Clarke
 
OLTP+OLAP=HTAP
EDB
 
Enterprise JavaBeans(EJB)
Armen Arzumanyan
 
Salesforce asynchronous apex
Badan Singh Pundeer
 
Spring Security 5
Jesus Perez Franco
 
Maven Basics - Explained
Smita Prasad
 
REST API Design
Devi Kiran G
 
How to Lock Down Apache Kafka and Keep Your Streams Safe
confluent
 
Spring Boot in Action
Alex Movila
 
Scalability, Availability & Stability Patterns
Jonas Bonér
 
JCR, Sling or AEM? Which API should I use and when?
connectwebex
 
BDD with Cucumber
Knoldus Inc.
 
아마존 클라우드와 함께한 1개월, 쿠키런 사례중심 (KGC 2013)
Brian Hong
 
Spring Boot
Jiayun Zhou
 

Viewers also liked (20)

PPTX
Unit testing in JavaScript with Jasmine and Karma
Andrey Kolodnitsky
 
PDF
Karma - JS Test Runner
Sebastiano Armeli
 
PDF
Intro to testing Javascript with jasmine
Timothy Oxley
 
PDF
Angularjs - Unit testing introduction
Nir Kaufman
 
PPTX
TDD Basics with Angular.js and Jasmine
Luis Sánchez Castellanos
 
PDF
Linux Performance Tools
Brendan Gregg
 
KEY
Jasmine
Chris Powers
 
PPTX
Bdd 개요 및 Karma 도입 예
Seulgi Choi
 
PPT
Jquery 3
Manish Kumar Singh
 
PPTX
jQuery 3 main changes
Osama Quboh
 
PPT
TDD, unit testing and java script testing frameworks workshop
Sikandar Ahmed
 
PDF
Angular testing
Raissa Ferreira
 
PDF
Angular 2 - What's new and what's different
Priscila Negreiros
 
PDF
AngularJS Unit Test
Chiew Carol
 
PPT
Jasmine - A BDD test framework for JavaScript
Sumanth krishna
 
PDF
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Christopher Bartling
 
PPT
Automated Testing With Jasmine, PhantomJS and Jenkins
Work at Play
 
PDF
Inclure du Javascript de manière performante
Jean-Pierre Vincent
 
DOCX
Borang data murid
Jasmine Eng
 
PDF
Professionelle Anforderungsanalyse am Beispiel einer Java-Anwendung zur Betri...
GFU Cyrus AG
 
Unit testing in JavaScript with Jasmine and Karma
Andrey Kolodnitsky
 
Karma - JS Test Runner
Sebastiano Armeli
 
Intro to testing Javascript with jasmine
Timothy Oxley
 
Angularjs - Unit testing introduction
Nir Kaufman
 
TDD Basics with Angular.js and Jasmine
Luis Sánchez Castellanos
 
Linux Performance Tools
Brendan Gregg
 
Jasmine
Chris Powers
 
Bdd 개요 및 Karma 도입 예
Seulgi Choi
 
jQuery 3 main changes
Osama Quboh
 
TDD, unit testing and java script testing frameworks workshop
Sikandar Ahmed
 
Angular testing
Raissa Ferreira
 
Angular 2 - What's new and what's different
Priscila Negreiros
 
AngularJS Unit Test
Chiew Carol
 
Jasmine - A BDD test framework for JavaScript
Sumanth krishna
 
JavaScript Test-Driven Development with Jasmine 2.0 and Karma
Christopher Bartling
 
Automated Testing With Jasmine, PhantomJS and Jenkins
Work at Play
 
Inclure du Javascript de manière performante
Jean-Pierre Vincent
 
Borang data murid
Jasmine Eng
 
Professionelle Anforderungsanalyse am Beispiel einer Java-Anwendung zur Betri...
GFU Cyrus AG
 
Ad

Similar to JavaScript TDD with Jasmine and Karma (20)

PDF
Quick tour to front end unit testing using jasmine
Gil Fink
 
PPTX
introduction to node.js
orkaplan
 
PPTX
Testing Ext JS and Sencha Touch
Mats Bryntse
 
PDF
Quick tour to front end unit testing using jasmine
Gil Fink
 
PDF
CBDW2014 - MockBox, get ready to mock your socks off!
Ortus Solutions, Corp
 
PPTX
Qt test framework
ICS
 
PPTX
Java script unit testing
Mats Bryntse
 
ODP
Unit Testing and Coverage for AngularJS
Knoldus Inc.
 
PPTX
Understanding JavaScript Testing
Kissy Team
 
PPTX
OWASP ZAP Workshop for QA Testers
Javan Rasokat
 
PDF
Performance Test Driven Development with Oracle Coherence
aragozin
 
PDF
JAVASCRIPT TDD(Test driven Development) & Qunit Tutorial
Anup Singh
 
PDF
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
PDF
[AWS Dev Day] 실습워크샵 | Amazon EKS 핸즈온 워크샵
Amazon Web Services Korea
 
PPTX
Nashorn
Rory Preddy
 
PDF
The Many Ways to Test Your React App
All Things Open
 
PPTX
Safe Wrappers and Sane Policies for Self Protecting JavaScript
Phú Phùng
 
PPTX
Jakarta EE Test Strategies (2022)
Ryan Cuprak
 
PDF
Advanced Java Testing
Vincent Massol
 
PDF
Building stable testing by isolating network layer
Jz Chang
 
Quick tour to front end unit testing using jasmine
Gil Fink
 
introduction to node.js
orkaplan
 
Testing Ext JS and Sencha Touch
Mats Bryntse
 
Quick tour to front end unit testing using jasmine
Gil Fink
 
CBDW2014 - MockBox, get ready to mock your socks off!
Ortus Solutions, Corp
 
Qt test framework
ICS
 
Java script unit testing
Mats Bryntse
 
Unit Testing and Coverage for AngularJS
Knoldus Inc.
 
Understanding JavaScript Testing
Kissy Team
 
OWASP ZAP Workshop for QA Testers
Javan Rasokat
 
Performance Test Driven Development with Oracle Coherence
aragozin
 
JAVASCRIPT TDD(Test driven Development) & Qunit Tutorial
Anup Singh
 
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
 
[AWS Dev Day] 실습워크샵 | Amazon EKS 핸즈온 워크샵
Amazon Web Services Korea
 
Nashorn
Rory Preddy
 
The Many Ways to Test Your React App
All Things Open
 
Safe Wrappers and Sane Policies for Self Protecting JavaScript
Phú Phùng
 
Jakarta EE Test Strategies (2022)
Ryan Cuprak
 
Advanced Java Testing
Vincent Massol
 
Building stable testing by isolating network layer
Jz Chang
 
Ad

More from Christopher Bartling (11)

PDF
Acceptance Test-driven Development with Cucumber-jvm
Christopher Bartling
 
KEY
Building Tropo Apps with Grails
Christopher Bartling
 
KEY
CoffeeScript By Example
Christopher Bartling
 
PPT
Acceptance Test Driven Development With Spec Flow And Friends
Christopher Bartling
 
PPT
Introduction To Grails
Christopher Bartling
 
KEY
Cucumber, Cuke4Duke, and Groovy
Christopher Bartling
 
PPTX
Test Driven In Groovy
Christopher Bartling
 
KEY
iPhone OS: The Next Killer Platform
Christopher Bartling
 
PDF
RESTful Web Services
Christopher Bartling
 
PDF
Grails Overview
Christopher Bartling
 
PDF
Rich Web Clients 20081118
Christopher Bartling
 
Acceptance Test-driven Development with Cucumber-jvm
Christopher Bartling
 
Building Tropo Apps with Grails
Christopher Bartling
 
CoffeeScript By Example
Christopher Bartling
 
Acceptance Test Driven Development With Spec Flow And Friends
Christopher Bartling
 
Introduction To Grails
Christopher Bartling
 
Cucumber, Cuke4Duke, and Groovy
Christopher Bartling
 
Test Driven In Groovy
Christopher Bartling
 
iPhone OS: The Next Killer Platform
Christopher Bartling
 
RESTful Web Services
Christopher Bartling
 
Grails Overview
Christopher Bartling
 
Rich Web Clients 20081118
Christopher Bartling
 

Recently uploaded (20)

PDF
Python basic programing language for automation
DanialHabibi2
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Python basic programing language for automation
DanialHabibi2
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 

JavaScript TDD with Jasmine and Karma

  • 1. JavaScript Test-Driven Development with Jasmine and Karma ! ! ! ! ! ! ! ! Christopher Bartling 1
  • 2. Justifying test-driven JavaScript development • JavaScript is a first-class citizen in our products. • Modern web applications are predominantly written in JavaScript with some markup. • JavaScript usage is growing, even on the server-side. • Production quality code should be tested. • Unit, integration, and functional/acceptance testing. • Don’t practice reckless development! 2
  • 3. Quick review of test-driven development • Use unit tests to drive development and design. • Write the test first, then the code. • See the test fail, then make it pass. • Importance of spiking before test-first development. • Test coverage of your code remains high because of test- first approach. • A fast test suite is typically run frequently. 3
  • 4. Benefits of test-driven development • Design tool. • Helps build confidence. • Executable documentation of the code base. • Tests infer the intent of the code. • Code base is continually executed when test suites are run in continuous integration environments. • Avoid code rot. 4
  • 5. The test-driven development cadence Start with a failing test Write code to make the test pass Refactor code and tests 5
  • 6. The importance of “spiking” • Test-driven development is grounded in the assumption that you know your tools and what you are building. • When unsure about how the solution should proceed, use spike solutions to learn more about what you’re attempting to do. • Spike solutions are not production code. • Spike solutions are typically thrown away. Value is in the problem domain learning that takes place. 6
  • 7. karma • JavaScript test runner that integrates with a number of browser runners. • Dependent on node.js, distributed as a node package. • Command line tool, but also integrated into JetBrains WebStorm IDE. ➜ calculator git:(master) ✗ karma start
 INFO [karma]: Karma v0.10.8 server started at http://localhost:9876/
 INFO [launcher]: Starting browser PhantomJS
 INFO [PhantomJS 1.9.2 (Mac OS X)]: Connected on socket TbzZHmxXJQ3aKLGcIIel
 PhantomJS 1.9.2 (Mac OS X): Executed 12 of 12 SUCCESS (0.022 secs / 0.003 secs) 7
  • 8. phantom.js • Headless WebKit browser runner, scriptable with a JavaScript API • Native support for various web standards • DOM, Canvas, and SVG • CSS selectors • JSON 8
  • 9. Introducing Jasmine • Testing framework • Suites possess a hierarchical structure • Tests as specifications • Matchers, both built-in and custom • Spies, a test double pattern 9
  • 10. Jasmine suite describe("A specification suite", function() {
 
 … 
 
 }); • Group specifications together using nested describe function blocks. • Also useful for delineating context-specific specifications. 10
  • 11. Jasmine specification describe("A specification suite", function() {
 
 it(“contains spec with an expectation", function() {
 expect(view.tagName).toBe(‘tr’);
 });
 
 }); • Specifications are expressed with the it function. • The description should read well in the report. • Expectations are expressed with the expect function. 11
  • 12. Jasmine matchers 12 • not • toBe • toEqual • toMatch • toBeDefined • toBeUndefined • toBeNull • toBeTruthy • toBeFalsy • toContain • toBeLessThan • toBeGreaterThan • toBeCloseTo • toThrow
  • 13. Jasmine setup using beforeEach describe("PintailConsulting.ToDoListView", function() {
 var view;
 
 beforeEach(function(){
 view = new PintailConsulting.ToDoListView();
 });
 
 it(“sets the tagName to ‘div’", function() {
 expect(view.tagName).toBe(‘div’);
 });
 }); 13
  • 14. Jasmine tear down using afterEach describe("PintailConsulting.ToDoListView", function() {
 var view;
 
 beforeEach(function(){
 view = new PintailConsulting.ToDoListView();
 });
 
 afterEach(function(){
 view = null;
 });
 
 it(“sets the tagName to ‘div’", function() {
 expect(view.tagName).toBe(‘div’);
 });
 }); 14
  • 15. Jasmine custom matchers beforeEach(function() { 
 this.addMatchers({
 toBeLessThan: function(expected) {
 var actual = this.actual;
 var notText = this.isNot ? " not" : "";
 
 this.message = function () {
 return "Expected " + actual + notText + 
 " to be less than " + expected;
 }
 return actual < expected;
 }
 });
 }); 15
  • 17. Jasmine spies • Test double pattern. • Interception-based test double mechanism provided by the Jasmine library. • Spies record invocations and invocation parameters, allowing you to inspect the spy after exercising the SUT. • Very similar to mock objects. • More information at https://github.com/pivotal/jasmine/ wiki/Spies. 17
  • 18. Jasmine spy usage Spying and verifying invocation var spy = spyOn(dependency, “render”);
 systemUnderTest.display();
 expect(spy).toHaveBeenCalled(); 
 Spying, verifying invocation and argument(s) var spy = spyOn(dependency, “render”);
 systemUnderTest.display(“Hello”);
 expect(spy).toHaveBeenCalledWith(“Hello”); 18
  • 19. Jasmine spy usage Spying, verifying number of invocations and arguments for each call var spy = spyOn(Leaflet, “circle”).andCallThrough();
 mapView.processResults(earthquakeJsonResults);
 expect(spy).toHaveBeenCalled()
 expect(circleConstructorSpy.callCount).toBe(2);
 expect(circleConstructorSpy.argsForCall[0][0])
 .toEqual([56.6812, -155.0237]) 19
  • 20. Loose matching with jasmine.any • Accepts a constructor or “class” name as an expected value. • Returns true if the constructor matches the constructor of the actual value. 
 var spy = jasmine.createSpy(My.Namespace, ’foo’);
 foo(12, function(x) { return x * x; }); expect(spy).toHaveBeenCalledWith
 (jasmine.any(Number), jasmine.any(Function)); 20
  • 21. Jasmine spy usage • andCallThrough(): Allows the invocation to passthrough to the real subject. • andReturn(result): Return a hard-coded result. • andCallFake(fakeImplFunction): Return a dynamically generated result from a function. • createSpy(identity): Manually create a spy. • createSpyObj(identity, propertiesArray): Creates a mock with multiple property spies. 21
  • 22. Jasmine asynchronous support • Use runs and waitsFor blocks and a latch function. • The latch function polls until it returns true or the timeout expires, whichever comes first. • If the timeout expires, the specification fails with a message. • Kind of clunky to use. 22
  • 23. Jasmine asynchronous example describe("an async spec", function() { 
 var done;
 
 beforeEach(function() {
 done = false;
 var doStuff = function() {
 // simulate async stuff and wait 10ms
 setTimeout(function() { done = true; }, 10); 
 };
 runs(doStuff);
 waitsFor(function() { return done; }, 
 ‘The doStuff function should be done by now.’, 
 100); 
 });
 
 it("did stuff", function() {
 expect(done).toBe(true);
 });
 }); 23
  • 24. karma-coverage • Test coverage plugin for karma • https://github.com/karma-runner/karma-coverage npm install karma-coverage --save-dev • Run karma with coverage configured (karma.conf.js) • Generate reports using istanbul report • Reports saved to the coverage subdirectory 24
  • 26. Unit testing tips • Strive for one assertion per example. • Allows all assertions to execute. • Each assertion runs in a clean SUT setup. • Avoid making live AJAX calls in your unit tests/specs. • Spy/intercept the low-level AJAX invocations (jQuery.ajax) • Use fixture data for testing AJAX callbacks. 26
  • 27. How do we sustain test-driven development? • Practice, practice, practice! • Code katas, • Pair programming, even in remote situations. • Screenhero, Hangouts, Skype • Continuous integration server. • Run your test suites often, preferably on every commit. 27
  • 28. Functional/acceptance testing • Very important part of the testing portfolio. • Many tools support testing web-based user interfaces today. • Geb, Capybara, Cucumber{Ruby|jvm|js}, Protractor.js, Concordian, spock • You should strongly consider adding functional/ acceptance testing in your testing portfolio. • Covers areas of code that unit testing cannot cover. 28
  • 29. Tool references • http://phantomjs.org • http://karma-runner.github.io/ • http://gruntjs.com/ • http://bower.io/ • http://pivotal.github.io/jasmine/ • http://yeoman.io/ 29
  • 30. Recommended reading • Secrets of the JavaScript Ninja - John Resig and Bear Bibeault • JavaScript: The Good Parts - Douglas Crockford • Test-Driven JavaScript Development - Christian Johansen 30
  • 31. Learning resources • Let’s Code: Test-Driven JavaScript • http://www.letscodejavascript.com/ • Egghead.io • http://egghead.io/ 31
  • 32. Code kata resources • http://katas.softwarecraftsmanship.org/ • http://codekata.pragprog.com/ • http://projecteuler.net/ • http://codekatas.org/ 32
  • 33. Presentation GitHub repository • https://github.com/cebartling/ncaa-basketball- tournament • The web-client directory contains this entire sample Backbone.js-based application. 33
  • 34. Thank you! • Christopher Bartling • @cbartling • [email protected] 34