Developing UI in JavaScript using TDD Principles Developing UI in JavaScript using TDD Principles javascript javascript

Developing UI in JavaScript using TDD Principles


I've done some TDD with Javascript in the past, and what I had to do was make the distinction between Unit and Integration tests. Selenium will test your overall site, with the output from the server, its post backs, ajax calls, all of that. But for unit testing, none of that is important.

What you want is just the UI you are going to be interacting with, and your script. The tool you'll use for this is basically JsUnit, which takes an HTML document, with some Javascript functions on the page and executes them in the context of the page. So what you'll be doing is including the Stubbed out HTML on the page with your functions. From there,you can test the interaction of your script with the UI components in the isolated unit of the mocked HTML, your script, and your tests.

That may be a bit confusing so lets see if we can do a little test. Lets to some TDD to assume that after a component is loaded, a list of elements is colored based on the content of the LI.

tests.html

<html><head><script src="jsunit.js"></script><script src="mootools.js"></script><script src="yourcontrol.js"></script></head><body>    <ul id="mockList">        <li>red</li>        <li>green</li>    </ul>   </body><script>    function testListColor() {        assertNotEqual( $$("#mockList li")[0].getStyle("background-color", "red") );        var colorInst = new ColorCtrl( "mockList" );        assertEqual( $$("#mockList li")[0].getStyle("background-color", "red") );    }</script></html>

Obviously TDD is a multi-step process, so for our control, we'll need multiple examples.

yourcontrol.js (step1)

function ColorCtrl( id ) { /* Fail! */    }

yourcontrol.js (step2)

function ColorCtrl( id ) {    $$("#mockList li").forEach(function(item, index) {        item.setStyle("backgrond-color", item.getText());    });    /* Success! */}

You can probably see the pain point here, you have to keep your mock HTML here on the page in sync with the structure of what your server controls will be. But it does get you a nice system for TDD'ing with JavaScript.


I've never successfully TDDed UI code. The closest we came was indeed to separate UI code as much as possible from the application logic. This is one reason why the model-view-controller pattern is useful - the model and controller can be TDDed without much trouble and without getting too complicated.

In my experience, the view was always left for our user-acceptance tests (we wrote web applications and our UATs used Java's HttpUnit). However, at this level it's really an integration test, without the test-in-isolation property we desire with TDD. Due to this setup, we had to write our controller/model tests/code first, then the UI and corresponding UAT. However, in the Swing GUI code I've been writing lately, I've been writing the GUI code first with stubs to explore my design of the front end, before adding to the controller/model/API. YMMV here though.

So to reiterate, the only advice I can give is what you already seem to suspect - separate your UI code from your logic as much as possible and TDD them.