Pro Yearly is on sale from $80 to $50! »

Unit Testing JavaScript Applications

A5b424d4146905962a24acd6815aeb84?s=47 Stephen Thomas
February 09, 2014

Unit Testing JavaScript Applications

A5b424d4146905962a24acd6815aeb84?s=128

Stephen Thomas

February 09, 2014
Tweet

Transcript

  1. http://github.com/sathomas/jsunittest stephen@sathomas.me icon-comment-alt icon-comments icon-comments-alt icon-credit-card icon-dashboard icon-download icon-download-alt icon-edit

    icon-envelope icon-envelope-alt icon-leaf icon-legal icon-lemon icon-lock icon-unlock icon-magic icon-magnet icon-map-marker icon-minus icon-minus-sign icon-resize-vertica icon-retweet icon-road icon-rss icon-screenshot icon-search icon-share icon-share-alt icon-shopping-car http://speakerdeck.com/sathomas Directional Icons icon-arrow-down icon-arrow-left icon-arrow-right icon-arrow-up icon-chevron-down icon-circle-arrow-down icon-circle-arrow-left icon-circle-arrow-right icon-circle-arrow-up icon-chevron-left icon-car icon-car icon-car icon-car icon-ch Video Player Icons icon-play-circle icon-play icon-step-backward icon-fast-backward icon-fas icon-ste Unit Testing JavaScript Applications Stephen Thomas
  2. Finding Bugs is a Bitch!

  3. What If We Could “Childproof” Our Code?

  4. Continuous Test Driven Development Block bugs from getting into our

    code at all.
  5. 1. Frictionless testing during development 2. Re-use of tests for

    integration 3. Coverage reports

  6. 1. Frictionless testing during development 2. Re-use of tests for

    integration 3. Coverage reports
 Test’Em: Test Development Environment Mocha+: Command line execution Blanket.js: Coverage analysis
  7. Example Application

  8. 1. Test Development Environment

  9. Test’Em Configuration { "framework": "mocha", "src_files": [ "node_modules/jquery/dist/jquery.js", "node_modules/underscore/underscore.js", "node_modules/backbone/backbone.js",

    "node_modules/chai/chai.js", "node_modules/sinon/pkg/sinon.js", "src/*.js", "test/*.js" ] }
  10. Test Driven Development 1. Write a Test 2. Verify That

    It Fails 3. Make It Pass 4. Repeat As Necessary
  11. First Test describe("Application", function(){ it("creates global variable…", function(){ should.exist(todoApp); })

    })
  12. Passing Code if (typeof todoApp === "undefined") { todoApp =

    {}; }
  13. None
  14. None
  15. None
  16. Testing a Model describe("Todo Model", function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo

    = new todoApp.Todo(); }) it("should default status…", function(){ this.todo.get('complete').should.be.false; }) it("should default title…", function(){ this.todo.get('title').should.equal(""); }) }) …
  17. Make The Tests Pass todoApp.Todo = Backbone.Model.extend({ defaults: { title:

    "", complete: false } })
  18. Testing a View describe("Todo List Item View", function(){ beforeEach(function(){ this.todo

    = new todoApp.Todo({ title: "Todo"}); this.item = new todoApp.TodoListItem({ model: this.todo}); }) it("render() should return view", function(){ this.item.render().should.equal(this.item); }); it("should render as list item", function(){ this.item.render() .el.nodeName.should.equal("LI"); })
  19. Stubs describe("Todo Model", function(){ describe("Attributes", function(){ beforeEach(function(){ this.todo = new

    todoApp.Todo(); this.stb = sinon.stub(this.todo,"save"); }) afterEach(function(){ this.stb.restore(); }) it(“should set title attr…", function(){ this.todo.set('title',"Test"); this.todo.get('title') .should.equal("Test"); })
  20. Mocking a REST API describe("REST API", function(){ it("should load via

    the API", function(){ this.ajax = sinon.stub($,"ajax")
 .yieldsTo("success", [ {id:1, title:"Mock1", complete:false} ]); this.todos = new todoApp.Todos(); this.todos.fetch(); this.todos.should.have.length(1); this.todos.at(0).get('title') .should.equal("Mock1"); this.ajax.restore(); }) })
  21. Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",

    function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it("should default…", function(){ this.todo.get('complete').should.be.false; })
  22. Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",

    function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.skip("should default…", function(){ this.todo.get('complete').should.be.false; })
  23. Mocha Tip #1: Never “Comment Out” a Test describe("Todo Model",

    function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.skip("should default…", function(){ this.todo.get('complete').should.be.false; })
  24. None
  25. Mocha Tip #1b: Skip an Entire Test Block describe.skip("Todo Model",

    function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it("should default…", function(){ this.todo.get('complete').should.be.false; })
  26. Mocha Tip #2:
 Focus on a Single Test describe("Todo Model",

    function(){ describe("Initialization", function(){ beforeEach(function(){ this.todo = new todoApp.Todo(); }) it.only("should default…", function(){ this.todo.get('complete').should.be.false; })
  27. 2. Command-Line Test Execution

  28. Test Code Setup if (typeof exports !== 'undefined' &&
 this.exports

    !== exports) { var jsdom = require("jsdom").jsdom; var doc=jsdom("<html><body></body></html>"); var window = doc.createWindow(); var $ = require("jquery")(window); global._ = require("underscore"); global.Backbone = require("backbone"); Backbone.$ = $; var chai = require("chai"); var sinon = require("sinon"); }
  29. Mocha Options:
 mocha.opts test/app-todos-test.js src/app-todos.js

  30. Run Mocha

  31. 3. Test Coverage

  32. Install Blanket.js

  33. Generate Coverage Report

  34. None
  35. None
  36. Resources • Test Development Environment Test’em: https://github.com/airportyh/testem • Command Line

    JavaScript Execution Environment node.js: http://nodejs.org • JavaScript Unit Testing Framework Mocha: http://visionmedia.github.io/mocha/ • JavaScript Assertion Library Chai: http://chaijs.com • Spies, Stubs, and Mocks Sinon.JS: http://sinonjs.org • Test Coverage Blanket.js: http://blanketjs.org