Category Archives: Javascript

Anything about Javascript in general

Automated Javascript unit testing with JsTestDriver

Introduction

In a previous post about unit testing your Javascript, I explained how you can unit test your own Javascript library code with the QUnit test suite. Now that we can unit test our Javascript, it would be cool to automate the process. We’ll accomplish that by using JsTestDriver, a Javascript test runner, built in Java.

What is a “test runner”?

A test runner is something that runs your tests. In my previous blog post on the subject, we wrote an HTML file which then contained references to the library & scripts to run. By opening that HTML file in a web browser, we ran our tests. In this case, the test runner was the browser itself, and the HTML file was a wrapper for your tests.

Having a browser as a test runner is good, because you are then testing your code in that specific browser. However, it is tedious work to open up the HTML wrapper in each and every browser you have available. Testing takes ages this way. What would be better is some sort of “thing” that can run your test code in a lot of browsers, preferably in parallel, with as little effort as possible. That’s where JsTestDriver comes in sight.

How does JsTestDriver work?

JsTestDriver simply works by starting a server, listening on a port (usually port 4224), where you connect browsers to. All the kinds of browsers you want your code tested agains, should connect to the JsTestDriver server. JsTestDriver then “captures” your browser, and puts it available for running tests in. Then you execute your test suite, and each captured browser will execute your test code. Here’s a small schema I copied from their site:

jstestrunner_overview.png

This kind of setup makes it easier to test your code against multiple browsers. Usually you won’t have different browsers on different OS’es available. What can help, is building virtual machines in VirtualBox and installing the browsers in them. Then all you have to do is point these browsers to the same JsTestRunner server instance, and you have your own little test farm.

Setting JsTestDriver server up

First thing you need to do, is download JsTestDriver from the project page over at google. At the time of writing, the most recent version was JsTestDriver-1.2.2.jar. I have a dedicated folder for it, where I also added the Code Coverage plugin. But more on that plugin later.

Get the server running by entering the following in your shell:

	java -jar /path/to/JsTestDriver-1.2.2.jar --port 4224

Now you have to leave your shell open to keep the server running. If all went well, you should now be able to surf to http://localhost:4224 and see the following:

Screen shot 2011-01-24 at 18.46.14.png

You can now go ahead, and add your browser to the list of browsers that will execute the test suite, by clicking the link “Capture This Browser”. You should now see this in your browser:

Screen shot 2011-01-24 at 18.48.21.png

Now your browser is ready and waiting for tests to come in.

Preparing your test suite

JsTestDriver can work with multiple Javascript test suites, but adheres to the JUnit standard. Therefor, if you want to keep on using QUnit, you’ll have to use an adapter. Luckily there’s one readily available, and using the adapter is very easy.

To use the adapter, first go to http://code.google.com/p/js-test-driver/source/browse/#svn/trunk/JsTestDriver/contrib/qunit/src and download equiv.js and QUnitAdapter.js to your test suite. Next you have to tell JsTestRunner where to find these files by adding them into your config file.

For each set of Javascript unit tests you want to run, you have to create a config file for JsTestDriver. In this config file, you specify the location of your files, and optionally which plugins you want to use. Here’s my config file:

server: http://localhost:4224

load:
# Add these lines to load the equiv function and adapter in order, before the tests
- external/equiv.js
- external/QUnitAdapter.js

# Load jQuery external dependency for the TAG library:
- external/jquery.js

# Load the files we want to test:
- lib/tag.js
- lib/tag/*.js

# Load the tests:
- tests/tag.js
- tests/tag/*.js

As you can see, first I load the files necessary for the QUnit adapter. Then I load jQuery, because it’s a dependency for my own library. Next all files of my library are loaded, and lastly the unit tests. Save this file as “jsTestDriver.conf” alongside your other files.

Limitations

The QUnitAdapter does a nice job converting the QUnit tests to something JsTestDriver can understand. However, it is not possible to do asynchronous tests with JsTestDriver. This means that any test where you use the “start()” and “stop()” functionality of QUnit, you will get an error. Keep this in mind when running your tests. They may run fine when you use the browser as your test runner, but fail when you use JsTestDriver.

Running your tests

Now you have to open up a new shell, and just enter the following:

java -jar /path/to/JsTestDriver-1.2.2.jar --config /path/to/jsTestDriver.conf --tests all

If you’re familiar with PHPUnit, you should see similar output:

Screen shot 2011-01-24 at 19.09.54.png

A dot represents a passed test. An “F” means a Failed test, and “E” indicates that an error happened.

If you have more browsers installed, just go ahead and capture them by surfing to http://localhost:4224. If you then run your test suite again, you’ll see just how many of your tests passed/failed/errored in each browser.

Code coverage

Unit tests are all great, but it’s even better if you had an idea about which parts of your code were actually executed, and which parts were skipped. There is a plugin for this available at the project website. Download, and copy coverage-1.2.2.jar in a “plugins” directory alongside the JsTestDriver-1.2.2.jar file.

Now we need to add it to the jsTestDriver.conf for our test suite:

server: http://localhost:4224

load:
# Add these lines to load the equiv function and adapter in order, before the tests
- external/equiv.js
- external/QUnitAdapter.js

# Load jQuery external dependency:
- external/jquery.js

# Load the files we want to test:
- lib/tag.js
- lib/tag/*.js

# Load the tests:
- tests/tag.js
- tests/tag/*.js

# Code coverage
plugin:
- name: "coverage"
  jar: "/path/to/plugins/coverage-1.2.2.jar"
  module: "com.google.jstestdriver.coverage.CoverageModule"

With the config updated, it’s time to run the tests again. We run the same command as previously mentioned, but with the added option to specify a code coverage output folder.

java -jar /path/to/JsTestDriver-1.2.2.jar --config /path/to/jsTestDriver.conf --tests all --testOutput /path/to/coverage/output

If the specified output directory doesn’t exist yet, it will be created, and in it you will now find some XML files and a jsTestDriver.conf-coverage.dat file in the directory you specified. These files contain all the data of the coverage report, exported into the a format that can be used by other programs to show you a nice overview. If you have LCOV installed on your system, you can convert the .dat file easily to a readable HTML file by entering this command:

genhtml /path/to/jsTestDriver.conf-coverage.dat.

If you now open up the generated index.html file in your favorite browser, you get something like this:

LCOV - jsTestDriver.conf-coverage.dat_1295967277319.png

With this coverage report, you can see which parts of your code were executed during the unit tests, and more importantly, which parts weren’t. It’s up to you now, to update your unit tests to get your coverage percentage higher. We would all love to achieve 100% coverage, but I think that if you have about 70% coverage, your library is already well tested.

Conclusion

With JsTestDriver, it’s possible to quite easily automate your Javascript unit testing in more browsers. The process of capturing browsers, and then distributing the unit tests in parallel to them certainly speeds up the whole unit testing itself. Code coverage is very nice to have, as it presents you with a document you can show your client or employer.

The only downside I have discovered so far, is the lack of the ability to create asynchronous tests. Especially with so much website functionality relying on AJAX to update the interface, you really miss this feature. On the other hand, you can construct your code in such a way, that not testing AJAX functionality doesn’t necessarily result in big chunks of code without coverage. Only thing left is to get as many Virtual Machines and browsers connected to the JsTestDriver server, and get testing!

Unit testing your Javascript: Just Do It

Nike’s slogan is the only one fit for the issue I’m about to raise in this article: Unit testing. Deep down, everyone knows the benefits from unit testing your code. Unit testing can give you that warm feeling when you go to bed, knowing that the changes you made, didn’t break previously working code. It makes you happy and it gives you confidence.

Yet, a lot of us (including me) don’t actually start unit testing our code. There are a number of reasons for that, but I’ll have none of that now. Because now, I’m going to show you just how easy it is to unit test your Javascript. I’ll be using QUnit, made by John Resig, creator of jQuery. Even though I’ve just begun using QUnit, the code I presented in my previous three blog posts, has really benefitted greatly from it.

read more »

Building your own Javascript library (part 3)

Goal

In this final part of the series, I’m going to create a Publish/Subscribe provider for my new framework. With this so-called pubsub provider, it will be possible for any function to create or fire an event. Any other function may then listen for that event, and will get triggered when the event occurs. My main goal is to make sure that this provider is easy to use, not only for plugins, but also for regular functionality. Besides that, I also want to have my code as loosely coupled as possible. For that, I’m going to use a little bit of Dependency Injection + lazy loading. All this to make sure that plugins are as agnostic as possible about the outside world. If you want to know more, please read on! read more »

Building your own Javascript library (part 2)

Goal

In this second installment of my 3-part library-building journey, I’m going to make the core plugin for the library. This plugin will contain utility methods. Stuff that can be used, either by other plugins, or just by regular Javascript code. So far, I haven’t needed many utility methods, so this chapter will be rather short. If you’re ready, read on!

read more »

Building your own Javascript library (part 1)

Goal

There are two programming languages I like: PHP and Javascript. In this mini series, I will explore Javascript and jQuery, and build my own library/framework. I won’t re-invent the wheel here. I’ll just make a collection of methods and functionality I need, making use of some functionality in jQuery.

The goal of the first part of my mission is to create a small, lightweight, self-contained, easily extensible base for my framework. Recently I created my own little company, called “The Analog Guy”. I’ll just call my library “TAG”.

read more »