Ten Things You Should Know About Jasmine

Ten Things You Should Know About Jasmine

The movement toward building JavaScript rich web applications like Twitter and GMail brings with it some unique challenges. In this talk you'll learn how Jasmine, a BDD JavaScript testing framework will help you overcome these hurdles, and write better, more maintainable code.

94c767fbe5e2ce7ba74e9833c8e03d45?s=128

Damian Nicholson

April 10, 2012
Tweet

Transcript

  1. Ten Things You Should Know About Jasmine

  2. @damian

  3. None
  4. Ruby on Rails JavaScript CSS3 SASS Jasmine RSpec Sahi HTML5

    Web Stack
  5. The Why

  6. Current landscape

  7. Credit http://www.flickr.com/photos/cobalt/4695776093/sizes/l/in/photostream/ Exciting times for us

  8. People like using rich, responsive interfaces

  9. Twitter

  10. GMail

  11. $hit tonne of JS

  12. Credit http://www.flickr.com/photos/henryfaber/5419329074/sizes/l/in/photostream/

  13. The What

  14. No assumptions 1

  15. Framework agnostic Credit http://www.flickr.com/photos/krissen/6340984211/sizes/l/in/photostream/

  16. Doesn’t even require the DOM

  17. BDD 2

  18. describe(“tabs”, ...); describe(“when clicked”, ...); it(“should become active”, ...); expect(tabs.current.className).toEqual(‘active’);

  19. None
  20. Credit http://www.flickr.com/photos/bundu/569055930/sizes/l/in/photostream/ Sleep 3

  21. • Confidence • Discover problems early • Facilitates change

  22. More modular as a byproduct 4

  23. $(‘a’).on(‘click’, function(e) { var activeClass = ‘active’; e.preventDefault(); $(this) .addClass(activeClass)

    .siblings() .removeClass(activeClass); ... }); Jasmine doesn’t really lend itself to testing code written like this
  24. $(‘a’).on(‘click’, function(e) { var activeClass = ‘active’; e.preventDefault(); $(this) .addClass(activeClass)

    .siblings() .removeClass(activeClass); ... }); Fine when building a website, but not a web app
  25. “If its hard to test its a good sign that

    you need to refactor your code”
  26. function Tabs(options) { var defaults = { activeClass: ‘active’ };

    this.options = $.extend({}, defaults, options); this.$tabs = $(‘a’); this.$tabs.on(‘click’, $.proxy(this.handleClick, this)); }; Tabs.prototype.handleClick = function(e) { e.preventDefault(); this.$tabs.removeClass(this.options.activeClass); $(e.target).addClass(this.options.activeClass); }; Far easier to test and maintain
  27. describe(“Tabs”, function() var instance; beforeEach(function() { instance = new Tabs();

    }); describe(“initialize”, function() { it(“should have three tabs”, function() { expect(instance.$tabs.length).toEqual(3); }); ... }); });
  28. describe(“Tabs”, function() { ... describe(“on click”, function() { beforeEach(function() {

    instance.$tabs.first().trigger(‘click’); }); it(“should have an active class”, function() { var activeClass = instance.options.activeClass; expect(instance.$tabs.first().hasClass(activeClass)).toBeTruthy(); }); });
  29. • Simple setup / teardown • Internal state • Separation

    of concerns
  30. Templating 5

  31. describe(“Tabs”, function() { template(‘tabs.html’); describe(“on click”, function() { beforeEach(function() {

    instance.$tabs.first().trigger(‘click’); }); it(“should have an active class”, function() { var activeClass = instance.options.activeClass; expect(instance.$tabs.first().hasClass(activeClass)).toBeTruthy(); }); });
  32. Spies 6

  33. describe(“Tabs”, function() { ... describe(“on click”, function() { var event;

    beforeEach(function() { event = $.Event(‘click’); spyOn(event, ‘preventDefault’); instance.$tabs.first().trigger(event); }); it(“should have called preventDefault on the event”, function() { expect(event.preventDefault).toHaveBeenCalled(); }); });
  34. AJAX 7

  35. describe(“Tabs”, function() { ... describe(“load content in to tab”, function()

    { var request; beforeEach(function() { jasmine.Ajax.useMock(); tabs.loadContent(); // This function call contains an AJAX request request = mostRecentAjaxRequest(); request.response({ foo: ‘bar’ }); }); it(“should respond with foo”, function() { expect(request.foo).toEqual(‘bar’); }); ... });
  36. CLI 8

  37. • Continuous integration • Node.js

  38. Extensible 9

  39. New Matchers

  40. It’s not a hot lady I’m having an affair with

    10
  41. Questions