Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Sustainable Software with Jasmine via Cory Flan...

Justin Searls
September 12, 2011

Sustainable Software with Jasmine via Cory Flanigan and Justin Searls

Justin Searls

September 12, 2011
Tweet

More Decks by Justin Searls

Other Decks in Programming

Transcript

  1. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to pain points
  2. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to pain points
  3. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to pain points
  4. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to pain points
  5. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to which leads to
  6. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours which leads to
  7. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours which leads to
  8. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours which leads to
  9. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours which leads to
  10. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours but we value
  11. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital but we value
  12. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital but we value
  13. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital but we value
  14. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital but we value
  15. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital our values are compromised
  16. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital takes too long for finished features to get into production documentation slows progress; key people become bottlenecks communication cost slows down implementation wastes money & good-will; exacerbates quality issues our values are compromised
  17. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital takes too long for finished features to get into production documentation slows progress; key people become bottlenecks communication cost slows down implementation wastes money & good-will; exacerbates quality issues our values are compromised
  18. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital takes too long for finished features to get into production documentation slows progress; key people become bottlenecks communication cost slows down implementation wastes money & good-will; exacerbates quality issues our values are compromised
  19. adding new code breaks existing functionality intent & value of

    the code is unclear HTML & JavaScript become codependent it takes longer to add a new feature than it used to manual regression testing, change control processes rely on documentation, original authors to retain knowledge developers and designers closely coordinate each change hiring more people, working longer hours shipping features to users constantly avoiding commitments to non-critical concerns minimizing time to turn ideas into reality getting the most out of each infusion of capital takes too long for finished features to get into production documentation slows progress; key people become bottlenecks communication cost slows down implementation wastes money & good-will; exacerbates quality issues our values are compromised
  20. vicious cycle more bugs communication drag higher carrying cost slower

    delivery more overtime less feedback more indirection
  21. vicious cycle more bugs communication drag higher carrying cost slower

    delivery more overtime less feedback greater risk more indirection
  22. what if? new code didn’t risk breaking existing functionality? all

    code was sufficiently documented as it was developed? code was modular enough to survive UI changes, multiple client platforms? adding new features became easier over time?
  23. what if? new code didn’t risk breaking existing functionality? all

    code was sufficiently documented as it was developed? code was modular enough to survive UI changes, multiple client platforms? adding new features became easier over time?
  24. what if? new code didn’t risk breaking existing functionality? all

    code was sufficiently documented as it was developed? code was modular enough to survive UI changes, multiple client platforms? adding new features became easier over time?
  25. what if? new code didn’t risk breaking existing functionality? all

    code was sufficiently documented as it was developed? code was modular enough to survive UI changes, multiple client platforms? adding new features became easier over time?
  26. virtuous cycle fewer bugs more autonomy easier to change more

    rapid delivery greater value more confidence
  27. virtuous cycle fewer bugs more autonomy easier to change more

    rapid delivery more balance greater value more confidence
  28. virtuous cycle fewer bugs more autonomy easier to change more

    rapid delivery more balance greater value less risk more confidence
  29. describe('#addTask', function(){ it('appends a div', function(){ var $container = $('<div></div>');

    addTask.call($container); expect($container).toContain('div'); }); });
  30. window.addTask = function(){ this.append('<div></div>'); }; describe('#addTask', function(){ it('appends a div',

    function(){ var $container = $('<div></div>'); addTask.call($container); expect($container).toContain('div'); }); });
  31. describe('#addTask', function(){ it('appends a div', function(){ var $container = $('<div></div>');

    addTask.call($container); expect($container).toContain('div'); }); it('includes a default text label', function(){ var $container = $('<div></div>'); addTask.call($container); expect($container).toHaveText('New Task!'); }); });
  32. window.addTask = function(){ this.append('<div>New Task!</div>'); }; describe('#addTask', function(){ ... it('includes

    a default text label', function(){ var $container = $('<div></div>'); addTask.call($container); expect($container).toHaveText('New Task!'); }); });
  33. describe('#addTask', function(){ it('appends a div', function(){ var $container = $('<div></div>');

    addTask.call($container); expect($container).toContain('div'); }); it('includes a default text label', function(){ var $container = $('<div></div>'); addTask.call($container); expect($container).toHaveText('New Task!'); }); });
  34. describe('#addTask', function(){ var $container; beforeEach(function(){ $container = $('<div></div>'); addTask.call($container); });

    it('appends a div', function(){ expect($container).toContain('div'); }); it('includes a default text label', function(){ expect($container).toHaveText('New Task!'); }); });
  35. describe('#addTask', function(){ var $container; beforeEach(function(){ $container = $('<div></div>'); addTask.call($container); });

    it('appends a div', function(){ expect($container).toContain('div'); }); it('includes a default text label', function(){ expect($container).toHaveText('New Task!'); }); }); jasmine-jquery http://is.gd/jasminejquery
  36. describe('#clicker', function(){ it('triggers the event handler', function(){ var handler =

    jasmine.createSpy('handles clicks'); expect(handler).toHaveBeenCalledWith(event); }); });
  37. describe('#clicker', function(){ it('triggers the event handler', function(){ var handler =

    jasmine.createSpy('handles clicks'); var event = $.Event('click'); expect(handler).toHaveBeenCalledWith(event); }); });
  38. describe('#clicker', function(){ it('triggers the event handler', function(){ var handler =

    jasmine.createSpy('handles clicks'); var event = $.Event('click'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(handler).toHaveBeenCalledWith(event); }); });
  39. var clicker = function(selector, whenClicked){ }; describe('#clicker', function(){ it('triggers the

    event handler', function(){ var handler = jasmine.createSpy('handles clicks'); var event = $.Event('click'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(handler).toHaveBeenCalledWith(event); }); });
  40. var clicker = function(selector, whenClicked){ $(selector).live('click',function(e) { whenClicked(e); }); };

    describe('#clicker', function(){ it('triggers the event handler', function(){ var handler = jasmine.createSpy('handles clicks'); var event = $.Event('click'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(handler).toHaveBeenCalledWith(event); }); });
  41. var clicker = function(selector, whenClicked){ $(selector).live('click',function(e) { whenClicked(e); }); };

    describe('#clicker', function(){ ... it('prevents default browser behavior', function(){ var handler = jasmine.createSpy('handles clicks'); var event = $.Event('click'); spyOn(event,'preventDefault'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(event.preventDefault).toHaveBeenCalled(); }); });
  42. var clicker = function(selector, whenClicked){ $(selector).live('click',function(e) { e.preventDefault(); whenClicked(e); });

    }; describe('#clicker', function(){ ... it('prevents default browser behavior', function(){ var handler = jasmine.createSpy('handles clicks'); var event = $.Event('click'); spyOn(event,'preventDefault'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(event.preventDefault).toHaveBeenCalled(); }); });
  43. describe('#clicker', function(){ it('triggers the event handler', function(){ var handler =

    jasmine.createSpy('handles clicks'); var event = $.Event('click'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(handler).toHaveBeenCalledWith(event); }); it('prevents default browser behavior', function(){ var handler = jasmine.createSpy('handles clicks'); var event = $.Event('click'); spyOn(event,'preventDefault'); $.jasmine.inject('<div class="my-button"></div>'); clicker('.my-button',handler); $('.my-button').trigger(event); expect(event.preventDefault).toHaveBeenCalled(); }); });
  44. describe('#clicker',function(){ var handler, event; beforeEach(function(){ handler = jasmine.createSpy('handles clicks'); event

    = $.Event('click'); spyOn(event,'preventDefault'); $.jasmine.inject('<div class="my-button"></div>'); }); context('when you click the button',function(){ beforeEach(function(){ clicker('.my-button',handler); $('.my-button').trigger(event); }); it('triggers the event handler',function(){ expect(handler).toHaveBeenCalledWith(event); }); it('prevents default browser behavior',function(){ expect(event.preventDefault).toHaveBeenCalled(); }); }); });
  45. describe('#clicker',function(){ var handler, event; beforeEach(function(){ handler = jasmine.createSpy('handles clicks'); event

    = $.Event('click'); spyOn(event,'preventDefault'); $.jasmine.inject('<div class="my-button"></div>'); }); context('when you click the button',function(){ beforeEach(function(){ clicker('.my-button',handler); $('.my-button').trigger(event); }); it('triggers the event handler',function(){ expect(handler).toHaveBeenCalledWith(event); }); it('prevents default browser behavior',function(){ expect(event.preventDefault).toHaveBeenCalled(); }); it('binds `this` to the jQuery result object',function(){ expect(handler.mostRecentCall.object).toBe('.my-button'); }); }); });
  46. var clicker = function(selector, whenClicked){ $(selector).live('click',function(e) { e.preventDefault(); whenClicked.call($(this),e); });

    }; describe('#clicker', function(){ ... context('when you click the button',function(){ ... it('binds `this` to the jQuery result object',function(){ expect(handler.mostRecentCall.object).toBe('.my-button'); }); }); });
  47. window.addTask = function(){ this.append('<div>New Task!</div>'); }; var clicker = function(selector,

    whenClicked){ $(selector).live('click',function(e) { e.preventDefault(); whenClicked.call($(this),e); }); }; clicker('.add-task', addTask);
  48. thank you! [email protected] Boulder UX, Boulder, CO September 12, 2011

    @searls seefl[email protected] @seeflanigan Thanks to Brandon Keepers (@bkeepers) for the Keynote template! find this talk at http://is.gd/jasmineux