testing of javacript

Post on 11-May-2015

4.305 Views

Category:

Documents

2 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Testing Javascript

Lei Kang @ Kiwiplan

Do you want...

Unit Testing of JavaScript code?

Continuous Integration?

Automated Testing for JavaScript intensive Web App?

Are those your itches for Web Development?

Every good work of software starts by scratching a developer’s personal itch.

-- The Cathedral and the Bazaarby Eric S. Raymond

My itches of JavaScript

Object Oriented Javascript

Javascript with Ruby’s flavor

Distributed Event Registering and Triggering

Reflection of Javascript

Unit Testing

Continuous Integration for Javascript Project

Automated Web UI testing

Today’s Story

Unit Testing using Rhino and RhinoUnit

Continuous Integration using Jenkins(Hudson)

Automated Web UI testing using iMacros

Rhino?

Rhino isAn open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users.

http://www.mozilla.org/rhino/

Rhino now

The Mozilla Rhino engine for the JavaScript programming language, is currently included as a feature in the JDK 6 and JRE 6 libraries.

Rhino can

Run JavaScript inside Java

ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine jsEngine = mgr.getEngineByName("JavaScript"); try { jsEngine.eval("print('Hello, world!')"); } catch (ScriptException ex) { ex.printStackTrace(); }

Rhino can

Run Java inside JavaScript

importPackage(javax.swing); var optionPane = JOptionPane.showMessageDialog(null, 'Hello, world!');

Rhino can Run in the Terminal: Linux, Windows and MacOS X: jrunscript

$ sudo apt-get install rhino; js

already feeling impatient?

Here comes RhinoUnit

An Ant based Javascript testing framework

RhinoUnit is run from an ANT scriptdef task using the Rhino engine - and uses all the helpful things that ANT provides for that.

What RhinoUnit can doAlmost the same APIs with JUnit

• string and object comparisons

• regexp comparisons

• collection comparisons (contains, containsExactly, etc)

• ensure that a function has been called (by wrapping it with assert.mustCall(), or using an assert.functionThatMustBeCalled()).

• ensure that an exception is thrown (using shouldThrowException(...)

• ensure that the global namespace isn't polluted by poor variable scoping. (I will talk about it later)

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 > 0 && this == parseInt(this)) {

for ( var i = 0; i < 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

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

Our Ant build.xml<project name="CiphorJS" basedir="." default="run-unit-tests">

<scriptdef name="rhinounit" src="lib/rhinounit/src/rhinoUnitAnt.js" language="javascript">

<attribute name="options"/><attribute name="ignoredglobalvars"/><attribute name="haltOnFirstFailure"/><attribute name="rhinoUnitUtilPath"/><element name="fileset" type="fileset"/>

</scriptdef>

<target name="run-unit-tests"><rhinounit options="{verbose:true, stackTrace:true}"

haltOnFirstFailure="false" rhinoUnitUtilPath="lib/rhinounit/src/rhinoUnitUtil.js">

<fileset dir="test"><include name="Test*.js"/>

</fileset></rhinounit>

</target></project>

I am sure you know how to do the next

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: 0BUILD SUCCESSFULTotal time: 922 milliseconds

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

Continuous Integration

Why do we need CI?

Can we use CI for Javascript Project?

Which CI system are we going to use?

How to do it?

Jenkins

jenkins-ci.org

JenkinsJenkins

Jenkins

Formerly known as Hudson

Free to use (applause!)

Written in Java

Distributed by jenkins.war (Easy to deploy)

Native package for ubuntu

How I use it

A Javascript Project in Eclipse

Using git for version controlling, you need a git plugin for eclipse

Source code hosted on GitHub (github.com)

Unit tested by RhinoUnit (Ant)

Interested in Git?

Let Jenkins working with githubInstall Github plugin

Install Git plugin

Let Jenkins working with github

Create a new job for your project

Let Jenkins working with github

Set Ant Target to run

Let Jenkins working with github

Set Git Publisher

Optionally push merge results, tags, and/or branches to remote repositories.

Let Jenkins working with github

Generate SSH key and add it to GitHub

Set Git autentication info in Jenkins workspace

$ git config user.name “your.name”$ git config user.email “your.name@email.com”

Hooray!

10:24:59 Started by user anonymous10:24:59 Checkout:workspace / /var/lib/jenkins/jobs/CiphorJS/workspace - hudson.remoting.LocalChannel@1077aa710:24:59 Using strategy: Default10:24:59 Last Built Revision: Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master)10:24:59 Checkout:workspace / /var/lib/jenkins/jobs/CiphorJS/workspace - hudson.remoting.LocalChannel@1077aa710:24:59 GitAPI created10:24:59 Fetching changes from the remote Git repository10:24:59 Fetching upstream changes from /home/lei.kang/workspaces/java/CiphorJS/.git10: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 HEAD10:25:00 Fetching upstream changes from git@github.com:kangleay/CiphorJS.git10:25:00 [workspace] $ git fetch -t git@github.com:kangleay/CiphorJS.git +refs/heads/*:refs/remotes/origin/*10:25:13 [workspace] $ git ls-tree HEAD10:25:13 Seen branch in repository local/master10:25:13 Seen branch in repository origin/master10:25:13 Commencing build of Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master)10:25:13 GitAPI created10:25:13 Checking out Revision 711a1c557c248b5e45364d3aafd8a4c98031f8a1 (local/master)10:25:13 [workspace] $ git checkout -f 711a1c557c248b5e45364d3aafd8a4c98031f8a110:25:13 [workspace] $ git tag -a -f -m "Hudson Build #37" hudson-CiphorJS-3710:25:13 Recording changes in branch local/master10:25:14 [workspace] $ git whatchanged --no-abbrev -M –pretty=raw 711a1c557c248b5e45364d3aafd8a4c98031f8a1..711a1c557c248b5e45364d3aafd8a4c98031f8a1

What is it doing behind?

What is it doing behind?10:25:14 [workspace] $ ant -file build.xml run-unit-tests10:25:14 Buildfile: build.xml10:25:15 10:25:15 run-unit-tests:10:25:15 [rhinounit] Testsuite: TestCore.js10:25:15 [rhinounit] *** Empty TestCase, unavailable for OOAD module. ***10:25:15 [rhinounit] Tests run: 1, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestEve.js10:25:15 [rhinounit] Tests run: 4, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestReflection.js10:25:15 [rhinounit] Tests run: 5, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestRubyArray.js10:25:15 [rhinounit] Tests run: 26, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestRubyNumber.js10:25:15 [rhinounit] Tests run: 3, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestRubyOO.js10:25:15 [rhinounit] Tests run: 7, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 [rhinounit] Testsuite: TestRubyString.js10:25:15 [rhinounit] Tests run: 12, Failures: 0, Errors: 010:25:15 [rhinounit] 10:25:15 10:25:15 BUILD SUCCESSFUL10:25:15 Total time: 0 seconds10:25:15 GitAPI created10:25:15 [workspace] $ git tag -d hudson-CiphorJS-3710:25:15 [workspace] $ git tag -a -f -m "Hudson Build #37" hudson-CiphorJS-37-SUCCESS10:25:15 GitAPI created10:25:15 Pushing HEAD to branch master at repo origin10:25:15 [workspace] $ git push git@github.com:kangleay/CiphorJS.git HEAD:master

10:25:20 Finished: SUCCESS

What have I done?

Commit Git Local Repository Detected by

Build and TestJenkins

workspace

Git Remote Repository(GitHub)

PublishSuccess

As an open source project, people now can check out source from github and enjoy!

Extremely bored?Should I continue?

Automated Web UI Testing

A lot of options

Selenium, Tellurium...

For simplicity, iMacros

iMacros

Just DRYDon't Repeat Yourself

iMacros

Works for both IE and Firefox

iMacros

Let's do itActions speak louder than words.

Web Testing

Web Testing

Web Testing

Web Testing

Web Testing

OK, That's the whole story today, Thank you!

Reference

Rhino http://www.mozilla.org/rhino/

RhinoUnit http://code.google.com/p/rhinounit/

Jenkins http://jenkins-ci.org/

iMacros https://addons.mozilla.org/en-us/firefox/addon/imacros-for-firefox/

CiphorJS http://www.ciphor.com/wiki/index.php/CiphorJS

Coming soon...

Javascript with Ruby flavor

• Ruby Array object

• Ruby Number object

• Ruby String object

• ...

Reflection of Javascript

Event Listening Extension

CiphorJS project

Object oriented way of writing javascript

• Inheritance

• Package importing

• Interface

• ...

top related