SF jQuery Conf: Packaging Code With Testable J Query Plugins
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

SF jQuery Conf: Packaging Code With Testable J Query Plugins

on

  • 2,164 views

Test drive development of Javascript code by packaging code as jQuery plugins as use a unit testing tool.

Test drive development of Javascript code by packaging code as jQuery plugins as use a unit testing tool.

Statistics

Views

Total Views
2,164
Views on SlideShare
2,161
Embed Views
3

Actions

Likes
4
Downloads
19
Comments
0

1 Embed 3

http://staging9.inceptum.eu 3

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • Boy meets girl joke <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • Did it really do something? Preconditions? <br /> On Load timing <br /> What if the markup is dynamic <br /> As the page grows, how is this going to work? <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • Claim only a single name in the jQuery namespace <br /> Accept an options argument to control plugin behavior <br /> Provide public access to default plugin settings <br /> Provide public access to secondary functions (as applicable) <br /> Keep private functions private <br /> Support the Metadata Plugin <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • There are others... this one is good <br /> - PUT FILES HERE <br /> _ WRITE TST HERE <br /> OPEN IN BROWSER <br /> RUN ON COMMAND LINE <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • Loosely coupled to the markup (but still CSS) <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />
  • <br />

SF jQuery Conf: Packaging Code With Testable J Query Plugins Presentation Transcript

  • 1. Packaging Your Code with Testable jQuery Plugins Andy Peterson      Testing, Plugins, Integrating, etc     Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 2. You jQuery Plugins? Tested Javascript? Selenium or other UI tests? Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 3. Andy Peterson started with commercial & enterprise desktop software (Mac), then consulting agile practices and disciplines Javascript-- dabbled for the last few years, but over the last 9 months, feel like it’s become a part of my professional practice Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 4. Software services company with offices in San Francisco and Los Angeles. 20 people We're an agile shop, focus on RoR & Java webapp dev along with more mobile 1/2 our work is bootstrapping startups Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 5. Why am I here? We didn't have a good story about Javascript testing Which led us to develop practices Which fed back into how we approach Javascript coding in general Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 6. Agenda Javascript testing is hard. Why? demo The Trick: UNIT test + Plugins problems & solutions Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 7. We Don’t Try Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 8. Why We Don’t Try Never did it before Had a bad experience Patterns unclear No infrastructure App’s not complicated enough Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 9. Too May Tools http://www.slideshare.net/jeresig/understanding-javascript-testing Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 10. Nobody Else Does Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 11. And when we tried... Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 12. page.[dynamic] <html> <head> <link href=”site.css” type=”text/stylesheet” /> <script src=‘page.js’ type=”text/javascript”> </script> <body> <h1>Joe’s Page</h1> ... </body> </html> Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 13. page.js $(function() { $(‘h1’).css(‘color’,‘red’); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 14. Test on the Page? Screw.Unit(function() { it(‘should change to red’, function() { expect($(‘h1’).css(‘color’)).to(equal,‘red’); }); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 15. Brings Up Lots of Qs How do I get the markup (if dynamic)? “on ready” timing What happens when other things happen on this page? As it evolves? How do I know it really did something? (Pre-conditions) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 16. Whew! Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 17. Why is it so complicated? We’re trying to build integration tests-- page markup + lifecycle multiple javascript sources Lots of pieces to integrate browsers, test engines, integration servers, developer machines Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 18. Simplify??? Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 19. Plugins + Unit Test it’s a good solution to lots of problems
  • 20. Plugins Solve Separate from “on doc ready” timing clear testing pattern provide good modularity pattern decoupled, abstract, encapulation Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 21. Plugins are Easy to Write (function($) { $.fn.myPlugin = function(req, opts) { return this.each(function() { $(this).myStuff... }); } })(jQuery); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 22. jQuery Plugin Writing http://docs.jquery.com/Plugins/ Authoring http://www.learningjquery.com/ 2007/10/a-plugin-development- pattern look at event patterns Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 23. Unit Testing Solves “test one piece at a time” Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 24. Requirements for a Tool... Easy to Install instant feedback & fast for TDD or BDD reliable & automate(able) mocking & stubbing minimal paradigm or language shift any browser Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 25. Which Javascript Testing Library? Lots to choose from QUnit xUnit Style: JSUnit, YUITest, etc.  BDD Style: JSSpec, JSpec, Jasmine, ScrewUnit  Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 26. We Picked Blue Ridge (not by me) Conventions (+ Rails Tools) ScrewUnit (BDD) in & out of browser with Rhino + env.js Provides: TDD, Reliable, headless, little paradigm shift, now multi-browser NOTE: maven plugin too! Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 27. Install ./script/plugin install git://github.com/relevance/blue- ridge.git ./script/generate blue_ridge rake test:javascripts Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 28. How do we test makeRed? Javascript UNIT tests source markup (fixture) + code under test = reliable, easy entry Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 29. Rewrite as Plugin jquery.make_red.js jQuery.fn.makeRed = function() { this.css(‘color’,‘red’); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 30. HTML “Fixture” for Test fixtures/make_red.html <head> <title>Make Red Results</title> <link rel="stylesheet" href="screw.css" type="text/css" charset="utf-8"/> <script type="text/javascript" src="../../../vendor/plugins/ blue-ridge/lib/blue-ridge.js"></script> </head> <body> <h1 style=‘color: pink’ >gotta test...</h1> </body> Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 31. Test with “Fixture” / make_red_spec.js / require("spec_helper.js"); require(".../make_red.js"); / code we are testing / Screw.Unit(function() { before(function() { expect($(‘h1’).css(‘color’)).to_not(equal,‘red’); " $('h1').makeRed(); }); it(‘should change to red’, function() { expect($(‘h1’).css(‘color’)).to(equal,‘red’); }); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 32. Test with “Fixture” Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 33. Test with “Fixture” $ rake spec:javascript (in /Users/ndp/demo) Running application_spec.js with fixture 'fixtures/ application.html'... . 1 test(s), 0 failure(s) 0.076 seconds elapsed Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 34. Link to on Page <html> <head> <script src=”.../jquery.make_red.js” /> <script type=”text/javascript”> $(function() { $(‘h1’).colorRed(); }); </script> Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 35. Implications of Unit Testing (over Integration Testing) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 36. Must modularize code (using events is a good approach) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 37. Build “Fixture” HTML seems a little counter-intuitive Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 38. Alternatives to Fixtures generate dynamically w/ Javascript generate -- figure out how to render your views “bake out” -- eg.    http://pivotallabs.com/users/jb/blog/ articles/1152-javascripttests-bind-reality- Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 39. May need simple integration tests anyhow (but much less) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 40. Tricks & Gotchas? Plugin + Unit Testing Gotchas
  • 41. Remember Javascript PLUGIN Fixture (Input) HTML markup Test of Plugin Individual Units Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 42. Unit Tests Perfect for DOM Manipulation Business rules (This gets you 80-90% there!) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 43. Plugin Becomes Complex Use Tests to aid in Refactoring Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 44. On Doc Ready Big Can use “controller” pattern Can use “composing” plugin (not testing doc ready) Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 45. Ajax EZ: Stub/Mock out $.ajax $.ajax = function(url, fn) { / assert called correctly / } test success: fn separately Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 46. Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 47. How to test? $.fn.clockify = function() { setInterval(function() { this.html(Time().toString()); }, 1000); } ... / test: / describe('clockify', function() { before(function() { $('p').clockify(); }); it('should update every second', function() { / ??? / }); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 48. Separate setInterval() $.fn.clockify = function() { var $j = this; setInterval(function() { $j.updateClock(); }, 1000); return this; } $.fn.updateClock = function() { this.each(function(i, e) { $(e).html((new Date()).toString()); }); } Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 49. Separate setInterval() describe('clockify', function() { before(function() { setInterval = mock_function(setInterval); }); it('should call setInterval with 1000', function() { setInterval.should_be_invoked(). with_arguments(null, 1000).exactly(1); $('p').clockify().html('running'); }); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 50. Or Even... $.fn.interval = function(fn, millis) { var $this = this; setInterval(function() { $this.each(function() { fn.apply(this); }, millis); return this; } $.fn.updateClock = function() { return this.html((new Date()).toString()); } $.fn.clockify = function() { return this.interval(function() { $(this).updateClock(); }, 1000); } Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 51. Testing Animations Opts skip stub use integration testing tools Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 52. Animations: Turning Off jQuery.fx.off = true Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 53. Animations: Configure $.fn.masterRadios = function(settings) { settings = $.extend({}, $.fn.masterRadios.defaults, settings); ... $form.find('.spesh').each(function(index, elem) { settings.showFn.call($(elem)); }); } $.fn.masterRadios.defaults = { hideFn: jQuery.fn.hide, showFn: jQuery.fn.show }; Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 54. Input Markup is Complex (therefore don’t want “fixture”) Simplify Semantic Markup? Can Generate within Javascript (Safely) Separate Concerns Refactor? Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 55. Markup Evolves Less of a problem than it seems Sometimes you just need integration tests Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 56. Drag & Drop Don’t try to script whole drag process Unit test draggable, droppable Events Trigger & Bind Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 57. Plugins “Draw Inside the Lines” $(‘div.specific’).plugin() shouldn’t affect other nodes in the doc Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 58. Expect No Change <html> <body> <div class=‘control’> ... <div id=‘fixture’> ... <div class=‘control’> ... Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 59. Expect No Change var control; / remember! / before(function() { control = $('.control').html(); }); after(function() { expect($('.control').html()).to(equal, control); }); Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 60. Unit Tests v. Small Files Keep code modular Put units of JS in their own files (LOTS) Share small JS with HTML pages Tests Lots of options to combine at deploy time! Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 61. CSS? Include CSS in tests Helps visualize Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 62. What about JS Classes? Hmm... Use object literals closures DOM nodes Is this enuf? Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 63. Limitations Not testing doc ready Nor Markup generation Nor integration of the two THUS: Selenium-- but simpler Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 64. Other Benefits (besides testing) Can move HTML generation where it is most appropriate Can move business logic to client Less “chatty” apps Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 65. Our Experience 3 projects definitely a net value add Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 66. Summary prefer UNIT tests over INTEGRATION tests for ease of testability and development package as jQuery Plugins work through tricky problems Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 67. Carbon Five We get to work on diverse projects and learn lots of new technologies. We're always looking for both seasoned developers and junior programmers to work, please feel free to talk to me now or email me Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson
  • 68. Thanks! andy@carbonfive.com http://github.com/ndp Andy Peterson • andy@carbonfive.com • SF jQuery Conf • April 2010 Copyright (c) 2010 Andrew J. Peterson