Testing of javacript

Download Testing of javacript

Post on 11-May-2015




2 download

Embed Size (px)


<ul><li>1.Testing Javascript <ul><li>Lei Kang @ Kiwiplan </li></ul></li></ul> <p>2. Do you want... </p> <ul><li>Unit Testing of JavaScript code? </li></ul> <ul><li>Continuous Integration? </li></ul> <ul><li>Automated Testing for JavaScript intensive Web App? </li></ul> <p>3. Are those your itches for Web Development? Text Every good work of software starts by scratching a developers personal itch. -- The Cathedral and the Bazaar by Eric S. Raymond 4. My itches of JavaScript </p> <ul><li>Object Oriented Javascript </li></ul> <ul><li>Javascript with Rubys flavor</li></ul> <ul><li>Distributed Event Registering and Triggering </li></ul> <ul><li>Reflection of Javascript </li></ul> <ul><li>Unit Testing </li></ul> <ul><li>Continuous Integration for Javascript Project </li></ul> <ul><li>Automated Web UI testing </li></ul> <p>5. Todays Story </p> <ul><li>Unit Testing using Rhino and RhinoUnit </li></ul> <ul><li>Continuous Integration using Jenkins(Hudson) </li></ul> <ul><li>Automated Web UI testing using iMacros </li></ul> <p>6. Rhino? 7. Rhino is </p> <ul><li>An open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users. </li></ul> <p>http://www.mozilla.org/rhino/ 8. Rhino now </p> <ul><li>The Mozilla Rhino engine for the JavaScript programming language, is currently included as a feature in the JDK 6 and JRE 6 libraries. </li></ul> <p>9. Rhino can </p> <ul><li>Run JavaScript inside Java </li></ul> <p>ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine jsEngine = mgr.getEngineByName("JavaScript"); try { jsEngine.eval("print('Hello, world!')"); } catch (ScriptException ex) { ex.printStackTrace(); } 10. Rhino can </p> <ul><li>Run Java inside JavaScript </li></ul> <p>importPackage(javax.swing);var optionPane = JOptionPane.showMessageDialog(null, 'Hello, world!'); 11. Rhino can</p> <ul><li>Run in the Terminal: Linux, Windows and MacOS X:jrunscript </li></ul> <ul><li>$ sudo apt-get install rhino; js </li></ul> <p>12. already feeling impatient? </p> <ul><li>Here comesRhinoUnit </li></ul> <p>AnAntbased Javascript testing framework RhinoUnitis run from an ANT scriptdef task using theRhinoengine - and uses all the helpful things that ANT provides for that. 13. What RhinoUnit can do </p> <ul><li>Almost the same APIs with JUnit </li></ul> <ul><li><ul><li>string and object comparisons </li></ul></li></ul> <ul><li><ul><li>regexp comparisons </li></ul></li></ul> <ul><li><ul><li>collection comparisons (contains, containsExactly, etc) </li></ul></li></ul> <ul><li><ul><li>ensure that a function has been called (by wrapping it with assert.mustCall(), or using an assert.functionThatMustBeCalled()). </li></ul></li></ul> <ul><li><ul><li>ensure that an exception is thrown (using shouldThrowException(...) </li></ul></li></ul> <ul><li><ul><li>ensure that the global namespace isn't polluted by poor variable scoping. (I will talk about it later) </li></ul></li></ul> <p>14. A general example /** * Number.times function. 3.times(function(item){...}) ** @param handler function * @returns {Array} */ Number.prototype.times = function(handler) { var results = new Array(); if (this &gt; 0 &amp;&amp; this == parseInt(this)) { for ( var i = 0; i &lt; Math.ceil(this); i++) { results.push(handler(i)); } } else { throw "Illegal number for times() function. Positive integer is required."; } return results; }; we have a simple function like this 15. A general example eval(loadFile("src/com/ciphor/ruby/Number.js")); var testNumber; testCases(test, function setUp(){ testNumber = 12; }, function testNumberTimes(){ var aNumber = new Number(10); var temp = 0; var result = aNumber.times(function(item){ temp++; return aNumber*item; }); assert.that(temp, eq(10)); assert.that(result, isCollectionContainingOnly(0,10,20,30,40,50,60,70,80,90)); } ); Test code goes like this 16. Our Ant build.xml </p> <ul><li>src=" lib/rhinounit/src/rhinoUnitAnt.js " </li></ul> <ul><li>language="javascript"&gt; </li></ul> <ul><li><ul><li><ul><li>haltOnFirstFailure="false"</li></ul></li></ul></li></ul> <ul><li><ul><li><ul><li>rhinoUnitUtilPath="lib/rhinounit/src/rhinoUnitUtil.js"&gt; </li></ul></li></ul></li></ul> <p>I am sure you know how to do the next 17. familiar with this? run-unit-tests : [ rhinounit ] Testsuite: TestCore.js [ rhinounit ] *** Empty TestCase, unavailable for OOAD module. *** [ rhinounit ] Tests run: 1, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestEve.js [ rhinounit ] Tests run: 4, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestReflection.js [ rhinounit ] Tests run: 5, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestRubyArray.js [ rhinounit ] Tests run: 26, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestRubyNumber.js [ rhinounit ] Tests run: 3, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestRubyOO.js [ rhinounit ] Tests run: 7, Failures: 0, Errors: 0 [ rhinounit ] Testsuite: TestRubyString.js [ rhinounit ] Tests run: 12, Failures: 0, Errors: 0 BUILD SUCCESSFUL Total time: 922 milliseconds 18. want to see more? assert.that(actual, predicate) assert.mustCall(onThisObject, thisMethod) assert.mustCallNTimes(onThisObject, numberOfTimes, thisMethod) assert.functionThatMustBeCalled(thisMethod, originalFunction) assert.functionThatMustBeCalledNTimes(thisMethod, numberOfTimes, originalFunction) assert.mustNotCall(onThisObject, thisMethod) assert.functionThatMustNotBeCalled(thisMethod) assert.fail(message) assert.callStack(optionalIgnoreAfterMatching) eq(expected) similar(expected) matches(regExp) isTrue(message) isFalse(message) not(predicate) hasConstructor(expected) isA(expected) isOfType(expected) isCollectionContaining(value, value, value...) isCollectionContainingOnly(value, value, value...) containsInOrder(value, value, value...) isNull(message) eqFloat(expected, accuracy) shouldThrowException(theTest, message, checkException) Assert Object Test Functions http://code.google.com/p/rhinounit/ Test Functions 19. Continuous Integration </p> <ul><li>Why do we need CI? </li></ul> <ul><li>Can we use CI for Javascript Project? </li></ul> <ul><li>Which CI system are we going to use? </li></ul> <ul><li>How to do it? </li></ul> <p>20. Jenkins jenkins-ci.org Jenkins Jenkins 21. Jenkins </p> <ul><li>Formerly known as Hudson </li></ul> <ul><li>Free to use (applause!) </li></ul> <ul><li>Written in Java </li></ul> <ul><li>Distributed by jenkins.war (Easy to deploy) </li></ul> <ul><li>Native package for ubuntu </li></ul> <p>22. How I use it </p> <ul><li>A Javascript Project in Eclipse </li></ul> <ul><li>Using git for version controlling, you need a git plugin for eclipse </li></ul> <ul><li>Source code hosted on GitHub ( github.com ) </li></ul> <ul><li>Unit tested by RhinoUnit (Ant) </li></ul> <p>Interestedin Git? 23. Let Jenkins working with github </p> <ul><li>Install Github plugin </li></ul> <ul><li>Install Git plugin </li></ul> <p>24. Let Jenkins working with github </p> <ul><li>Create a new job for your project </li></ul> <p>25. Let Jenkins working with github </p> <ul><li>Set Ant Target to run </li></ul> <p>26. Let Jenkins working with github </p> <ul><li>Set Git Publisher </li></ul> <ul><li>Optionally push merge results, tags, and/or branches to remote repositories. </li></ul> <p>27. Let Jenkins working with github </p> <ul><li>Generate SSH key and add it to GitHub </li></ul> <ul><li>Set Git autentication info in Jenkins workspace </li></ul> <p>$ git config user.name your.name $ git config user.email your.name@email.com 28. Hooray! 29. 10:24:59Started by user anonymous 10:24:59Checkout:workspace / /var/lib/jenkins/jobs/CiphorJS/workspace - hudson.remoting.LocalChannel@1077aa7 10:24:59Using strategy: Default 10:24:59Last Built Revision: Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master) 10:24:59Checkout:workspace / /var/lib/jenkins/jobs/CiphorJS/workspace - hudson.remoting.LocalChannel@1077aa7 10:24:59GitAPI created 10:24:59Fetching changes from the remote Git repository 10:24:59Fetching upstream changes from /home/lei.kang/workspaces/java/CiphorJS/.git 10:24:59[workspace] $ git fetch -t /home/lei.kang/workspaces/java/CiphorJS/.git +refs/heads/*:refs/remotes/local/* 10:25:00[workspace] $ git ls-tree HEAD 10:25:00Fetching upstream changes from git@github.com:kangleay/CiphorJS.git 10:25:00[workspace] $ git fetch -t git@github.com:kangleay/CiphorJS.git +refs/heads/*:refs/remotes/origin/* 10:25:13[workspace] $ git ls-tree HEAD 10:25:13Seen branch in repository local/master 10:25:13Seen branch in repository origin/master 10:25:13Commencing build of Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master) 10:25:13GitAPI created 10:25:13Checking out Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master) 10:25:13[workspace] $ git checkout -f 711a1c557c248b5e45364d3aafd8a4c98031f8a1 10:25:13[workspace] $ git tag -a -f -m "Hudson Build #37" hudson-CiphorJS-37 10:25:13Recording changes in branch local/master 10:25:14[workspace] $ git whatchanged --no-abbrev -M pretty=raw 711a1c557c248b5e45364d3aafd8a4c98031f8a1..711a1c557c248b5e45364d3aafd8a4c98031f8a1 What is it doing behind? 30. What is it doing behind? 10:25:14[workspace] $ ant -file build.xml run-unit-tests 10:25:14Buildfile: build.xml 10:25:1510:25:15run-unit-tests: 10:25:15[rhinounit] Testsuite: TestCore.js 10:25:15[rhinounit] *** Empty TestCase, unavailable for OOAD module. *** 10:25:15[rhinounit] Tests run: 1, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestEve.js 10:25:15[rhinounit] Tests run: 4, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestReflection.js 10:25:15[rhinounit] Tests run: 5, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestRubyArray.js 10:25:15[rhinounit] Tests run: 26, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestRubyNumber.js 10:25:15[rhinounit] Tests run: 3, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestRubyOO.js 10:25:15[rhinounit] Tests run: 7, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:15[rhinounit] Testsuite: TestRubyString.js 10:25:15[rhinounit] Tests run: 12, Failures: 0, Errors: 0 10:25:15[rhinounit]10:25:1510:25:15BUILD SUCCESSFUL 10:25:15Total time: 0 seconds 10:25:15GitAPI created 10:25:15[workspace] $ git tag -d hudson-CiphorJS-37 10:25:15[workspace] $ git tag -a -f -m "Hudson Build #37" hudson-CiphorJS-37-SUCCESS 10:25:15GitAPI created 10:25:15Pushing HEAD to branch master at repo origin 10:25:15[workspace] $ git push git@github.com:kangleay/CiphorJS.git HEAD:master 10:25:20Finished: SUCCESS 31. What have I done? Commit Git LocalRepository Detected by Build and Test Jenkinsworkspace Git RemoteRepository (GitHub) Publish Success As an open source project, people now can check out source from github and enjoy! 32. Extremely bored? Should I continue? 33. Automated Web UI Testing </p> <ul><li>A lot of options </li></ul> <ul><li>Selenium, Tellurium... </li></ul> <ul><li>For simplicity, iMacros </li></ul> <p>34. iMacros Just DRY Don't Repeat Yourself 35. iMacros Works for both IE and Firefox 36. iMacros Let's do it Actions speak louder than words. 37. Web Testing 38. Web Testing 39. Web Testing 40. Web Testing 41. Web Testing 42. OK, That's the whole story today,Thank you! 43. Reference Rhinohttp://www.mozilla.org/rhino/ RhinoUnithttp://code.google.com/p/rhinounit/ Jenkinshttp://jenkins-ci.org/ iMacroshttps://addons.mozilla.org/en-us/firefox/addon/imacros-for-firefox/ CiphorJShttp://www.ciphor.com/wiki/index.php/CiphorJS 44. Coming soon... </p> <ul><li>Javascript with Ruby flavor </li></ul> <ul><li><ul><li>Ruby Array object </li></ul></li></ul> <ul><li><ul><li>Ruby Number object </li></ul></li></ul> <ul><li><ul><li>Ruby String object </li></ul></li></ul> <ul><li><ul><li>... </li></ul></li></ul> <ul><li>Reflection of Javascript </li></ul> <ul><li>Event Listening Extension </li></ul> <ul><li>CiphorJS project </li></ul> <ul><li>Object oriented way of writing javascript </li></ul> <ul><li><ul><li>Inheritance </li></ul></li></ul> <ul><li><ul><li>Package importing </li></ul></li></ul> <ul><li><ul><li>Interface </li></ul></li></ul> <ul><li><ul><li>... </li></ul></li></ul>


View more >