I'm Matthew J. Morrison.

A Passionate, professional software developer & hobbyist; Language nerd & regular user of Unix, Python, Ruby & JavaScript.

Fork me on GitHub

UI work is hard, test it!

September 22, 2014

Alright, so I didn't learn this today, but I had a good experience that reinforced my current behavior. Sometimes, I think reinforcement of existing practices can be as valuable as learning new practices. If you can not reinforce existing practices from time to time they may be obsolete.

Today I ran into a scenario where I needed to do some pretty significant refactoring on how some navigation items were being displayed on a web page. Luckily, there were thorough tests around which items should display and when. This made it very easy to completely reimplement how the navigation items were being displayed.

Writing integration tests against a UI is valuable, as long as the tests remain decoupled from the structure of the presentation. By "decoupled from the structure of the presentation" I mean that tests should refer to html id and class attributes rather than elements or relationships between elements. As a quick example:

Try to avoid doing something like this:

click "table tr:eq(2) span button:eq(1)"

Instead do something like this:

click "#add-button"

It is a minimal amount of effort to add a few id attributes here and there and it makes the tests infinitely more readable. Also, you should use semantic names for things like id and class names. Name something based on what it does, not what it is. Do not call something red-button, instead call it cancel-button. You can have something that is both, like the following example:

<button id="cancel-button" class="red-button">Cancel</button>

Use the id attribute to uniquely identify an element as to what it is and what it does (in this case our button will 'cancel') and use the class attribute to define it's appearance (in this case the button is 'red').

We must learn to live together as brothers or perish together as fools. - Martin Luther King, Jr.