Monday, March 23, 2009

Start testing your Javascript server-less

Are you still launching tomcat to test your javascript code? You shouldn't.

When applying the MVC pattern, HTML as always been considered to be part of the View, which is only correct from a server point of view. In browser-land HTML is the Model, the Controller is our javascript code, and the View is - well, it can be your chrome, your CSS, whatever. The important thing is, there are two MVCs involved:



Two years ago we started applying some simple rules for javascript development:

  • No javascript code generated by the server. Nil. Zero. Nada. That would only make things harder to port and reuse. Instead, the server generates the HTML attributes (some standard and some not) to be used by javascript code. Combine this with progressive enhancement and you will have an almost functional interface to add your javascript icing.

  • Javascript is always tested using static HTML files, which represent the approved API between server and client software. You can test easily your javascript code, and the server only has to stick to this API.

  • Javascript unit testing may be added later. We use UnitTest, but there are others: JQuery, Firebug, TestMonkey... the list goes on. Notice that I am not considering Selenium here, as we are not testing interfaces but javascript code.





No matter the programming language, life is easier if you do not try to generate your Controller. Now your test environment can be 100% static.

These simple rules have made our lives so much easier. Instead of the classic mixup of technologies to test Ajax interfaces, there is just a javascript test engine and some html files to test things up (including some static JSON response examples). Before this, something like testing our validation code was a killing effort. This can still be integrated with ant or maven without requiring a java server in the middle.

Going static include some additional advantages:

  • You can interact with the interface by hand. When the tests are done, you still have a working HTML page to pick at.

  • You can trace and debug any failing assertion using Firebug or the IE debugger.

  • There is no roundtrip to the server. Things can only be fixed up to the HTML API, so there is no point in thinking in java at this point.



Think Divide-And-Conquer, but separating client from server using HTML. Once all javascript code is tested, you can start integrating things with the java server just by generating the expected HTML.

3 comments:

Anonymous said...

This is actually a really good idea.

Ale Sarco said...

Hi Nacho, you usually come with good ideas, but I don't quite understand this one. Can you provide a minimum example?

Nacho Coloma said...

Sure. As a (simplified) example, suppose you want to validate user input in the browser. Instead of creating a tagfile:

foo.jsp:
<tags:validateNumber name="amount" max="100" min="5"/>

validateNumber.tag:
<input name="${name}" id="${name}"/>

<script>
new NumberValidator("${name}", { min: ${min}, max: ${max} });
</script>

It's easier if you stick to the established HTML API:

foo.jsp:
<input name="amount" max="100" min="5" class="number"/>

generic.js:
$$('.number').each(function(e) {
new NumberValidator(e, {
min: e.getAttribute('min'),
max: e.getAttribute('max')
});
});

Notice that I do not have to generate any javascript code. In this example, generic.js is a static file, common to the entire application. I just generate the expected HTML. If I want to test the NumberValidator code, I can do so with a static HTML file.

This is exactly what we are doing here

As an added bonus, if I want to replace ALL my javascript code from prototype to jQuery or YUI, I do not have to change a single line of JSP code, just static javascript. I can say that because we had to do something similar in a real life project.

Post a Comment