Tuesday, December 15, 2009

Automated testing of Javascript as part of your build

Have you got 100% test coverage on your Java code? That is very commendable.

But perhaps you still get the feeling that there is a lot of functionality in all that front end Javascript you have been writing that really should be tested too?

Well here's how to setup automated testing of your Javascript functions that runs as part of your build along with all your other unit and integration tests. (It is based on the QUnit library, which is the best option I have evaluated.)

The Maven Dependencies you'll need:
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.w3c.css</groupId>
<artifactId>sac</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>


Create a new JUnit test that will run the Javascript test:

import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import junit.framework.TestCase;

import java.io.File;

public class MyJavascriptUnitTest extends TestCase {
private static final String JAVASCRIPT_TESTS_HTML = new File("src/test/javascript/assert/javascriptTests.html").getAbsolutePath();

public void testJavascriptTestResults() throws Exception {
final WebClient webClient = new WebClient();
final HtmlPage page = webClient.getPage("file://" + JAVASCRIPT_TESTS_HTML);
assertEquals("pass", page.getElementById("banner").getAttribute("class"));
}
}




Here's what javascriptTests.html looks like:

<html>
<head>
<script src="jquery-latest.js"></script>
<link media="screen" href="testsuite.css" type="text/css" rel="stylesheet">
<script src="testrunner.js"></script>
<script type="text/javascript" src="../../../main/webapp/javascripts/fileUnderTest.js"></script>

<script>

$(document).ready(function() {
// **** Add tests here ****
module("Currency Formatting");

test("formatCurrency", function() {
equals(formatCurrency("1"), "$1");
equals(formatCurrency("123"), "$123");
});

});

</script>
</head>

<body>

<h1>JavaScript Tests</h1>

<h2 id="banner"></h2>

<h2 id="userAgent"></h2>
<ol id="tests"></ol>
<div id="main"></div>
</body>
</html>


In this example, fileUnderTest.js is your file that you want to test, in this case it contains a function called formatCurrency().

module() is just a way to group related javascript tests for reporting purposes.

If you have IntelliJ, you can use WebPreview to open javascriptTests.html - and get instant feedback! And I mean instant - no reloading of anything needs to happen, just modify your Javascript and the WebPreview will instantly show you if it passes or fails.

Listed below are the other files referred to, for your convenience. You don't need to use these exact files, but it will help get you started:

testsuite.css
testrunner.js
jquery-latest.js

Monday, December 14, 2009

Project estimates are hilarious...

Taken from a publicly available August 2005 newsletter:

In early 2005, the QFRS undertook the development and implementation of the Operations Management System (OMS)...

The implementation of OMS is being staged over three phases with a scheduled completion date of mid 2006.

Despite being in full active development since that newsletter, OMS is currently scheduled for an initial deployment with a cut-down number of features to a small subset of users in March 2010.

Thursday, December 10, 2009

Toolin' around with web applications (Part 2)

The site below describes the technique that I think makes more sense than our current crop of server side web frameworks (at least for building a reasonably-sized modern web application):

Thin Server Architecture

Also google "SOFEA" if this appeals to you.

Monday, December 7, 2009

Australia Post requires the www?

It has been like this as long as I can remember:

post.com.au <- doesn't resolve
www.post.com.au
<- resolves

How could this go unnoticed for so long by such a huge company with such a good (short) domain name?