So I’m on this new cool Google Web Toolkit (GWT
) project of ours now. Part of the UI
consists of a series of HTML
labels that is the view to our model. Since our model has a tree structure, we use the visitor pattern to create this UI
.
This all works beautifully, except when it doesn’t, i.e. when there is a bug. With all the recursion and the sometimes convoluted HTML
that is required to achieve the desired effect, hunting down bugs isn’t always easy.
So it was about time to write some unit tests. Normally, I write the tests first. But I was added to this project, and there weren’t any tests yet. So I decided to introduce them. Now, it is often easier to start with tests than add them later. If you don’t start out by writing tests, you usually end up with code that is not easily testable. That was also the case here.
Making the code testable
So my first job was to make sure the code became testable. I started out by separating the creation of the HTML
labels from the visitor code, since I didn’t want my tests to depend on GWT
. So I introduced a simple TextStream
:
public interface TextStream { void add(String text); }
The visitor code is injected with this text stream and calls the add()
method with some HTML
markup. Normally, this TextStream
is a HtmlLabelStream
:
public class HtmlLabelStream implements TextStream { private final FlowPanel parent; public HtmlLabelStream(final FlowPanel parent) { this.parent = parent; } public void add(final String text) { parent.add(new HTML(text)); } }
But my test case also implements the TextStream
interface, and it injects itself into the visitor. That way, it can collect the output from the visitor and compare it with the expected output.
Simplifying testing
Now I got a whole lot of HTML
code that I needed to compare to the desired output. It was hard to find the deviations in this, since the required HTML
is rather verbose.
So I decided to invest some time in transforming the incoming HTML
into something more readable. For instance, to indent some piece of text, the HTML
code contains something like this:
<div style="padding-left: 20px">...</div>
For each indentation level, 10px
were used. So I decided to strip the div
, and replace it with the number of spaces that corresponds to the indentation level. I repeated the same trick for a couple of other styles. In the end, the output became much easier to read, and thus much easier to spot errors in. In fact, it now looks remarkably similar to what is rendered by the browser.
This certainly cost me time to build. But it also won me time when comparing the actual and expected outputs. And adding a new test is now a breeze. Which is just the sort of incentive I need for my fellow team mates to also start writing tests…