Agile Zone is brought to you in partnership with:

I am a programmer and architect (the kind that writes code) with a focus on testing and open source; I maintain the PHPUnit_Selenium project. I believe programming is one of the hardest and most beautiful jobs in the world. Giorgio is a DZone MVB and is not an employee of DZone and has posted 637 posts at DZone. You can read more from them at their website. View Full User Profile

We cannot avoid testing JavaScript anymore

04.11.2011
| 9073 views |
  • submit to reddit

You have to test your web application. Since the current year is 2011 and not 2002, you're going to use Ajax requests in it, and a certain amount of JavaScript code. JUnit, PHPUnit, NUnit and other frameworks perfect for server-side languages cannot directly test your JavaScript code, since they cannot execute it.

No problem, we grab a tool which uses browsers for accessing web pages and can execute JavaScript via their included interpreters. Selenium is probably the most famous testing framework for JavaScript-based application: you define where to click and when to wait for some seconds, and hopefully its bar will become red when there is a regression, and not too often due to the brittleness of the test suite.

But probably JavaScript is not an afterthought for me and you. You have pieces of presentation and business logic written in JavaScript. Half or more of your code is JavaScript and maybe you're even using some on the server-side with Node.js.

Unit testing of JavaScript code becomes an imperative, as we want to write xUnit tests for our JavaScript classes instead of heavy, slow and brittle user-interface tests.

So let's take a look at which tools are available for doing so: writing tests is not difficult, but a bunch of assertion methods and a base test case help.

In-browser

An old idea, also present in Selenium, is using the browser's DOM and interpreter for executing JavaScript. You load a .html page, and this page loads scripts and execute tests, displaying a red or green bar at the end of the process.

FireUnit is a Firefox plugin created by John Resig (of jQuery fame) in 2008. JsUnit is an almost classic tool for JavaScript testing, started as a port of JUnit to the browser environment.

Later on, JsUnit became Jasmine.

Jasmine is oriented to Behavior-Driven Development, and does not rely on the DOM, on browsers or particular frameworks. You can use it for example on server-side JS, like with Node.js code.

describe("Jasmine", function() {
it("makes testing JavaScript awesome!", function() {
// code a la xUnit
});
});

Jasmine also provides a SpecRunner.html for running the suite with a browser, in case that's the fastest way for you.

For frameworks

YUI Test is a testing framework originally created for the tests of the Yahoo's JavaScript framework, but it can now be used also for code not from the YUI library. It is a derivated from JUnit.

DOH (Dojo Objective harness) is the official tool for testing Dojo and related code. It fits nicely into the dojo.require()/dojo.provide() mechanisms for loading classes:

//Declare out the name of the test module to make dojo's module loader happy.
dojo.provide("my.test.module");

doh.register("MyTests", [
  function assertTrueTest(){
    doh.assertTrue(true);
    doh.assertTrue(1);
    doh.assertTrue(!false);
  }
]);

There is also an unofficial testing framework for ExtJS, for the ones of you who chose it.

Headless

The majority of JavaScript testing frameworks are in-browser: but what if you want to run them in a command line environment, like a Continuous Integration server?

You can get an headless build running with Mozilla Rhino and Envjs for example. Rhino is an implementation of a JavaScript virtual machine not linked to a particular browser, while Envjs provides a fake browser environment.

However, when you have an in-browser testing framework (which is simpler to write), you can test directly on the browsers and in many different ones (IE, Firefox, Chrome, ...). Your code will never run in production in Rhino, but only in Firefox, Chrome, Safari and so on.

The best of both worlds: JsTestDriver

Primarily, JsTestDriver is a runner and not a framework in itself. It is available for free and it has been created by Google. It addresses the hard part of JavaScript testing: not writing the tests but executing them.

JsTestDriver captures different browsers, and runs the suite in them just like Selenium. But JsTestDriver runs programmatic xUnit tests written by you, not by interacting with a user interface. Tests are easier to write and do not break every time you change a class name.

JsTestDriver is written in Java (it's a .jar), and it's accessible from the command line. The server component runs on the 9876 port, while clients can connect to the server in order to perform tests. The client may also be integrated with an IDE such as Eclipse.

The separation between clients and servers, which follows Selenium's example, allows parallelization of the test on multiple machines.

This is a sample test taken from the documentation of JsTestDriver:

GreeterTest = TestCase("GreeterTest");

GreeterTest.prototype.testGreet = function() {
  var greeter = new myapp.Greeter();
  assertEquals("Hello World!", greeter.greet("World"));
};

It's easy, it's fast and reliable. You can start unit testing in JavaScript now.

Published at DZone with permission of Giorgio Sironi, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)