Testing HTML

There's no clear route as to how to provide testing hooks in your HTML. Here are my three suggestions for how to mark up HTML for easy testability, in the absence of a component-based framework.

From an HTML/CSS perspective, this is a style guide decision, rather than a 'best practices' one. This is the same for a lot of HTML/CSS stuff, because they were never built to be tested in this way.

My personal style guide starts here.

Approach 1: id

  <div id="myThing">I'll show first.</div>

  <script type="text/javascript">
    var myThing = document.getElementById('myThing');
    myThing.innerHTML = "I'll show now";

By this logic, it's totally OK to use id attributes for JavaScript-led testing. Capybara doesn't use JavaScript to tell if elements are on a page, though, so id doesn't seem the right attribute to use.

Approach 2: class

  <div class="the_thing">I'll show first.</div>

  <script type="text/javascript">
    // getElementsByClassName returns an array containing the .the_thing element
    var myThing = document.getElementsByClassName("the_thing")[0];
    myThing.innerHTML = "I'll show now";

By this logic, class is the right attribute to use for non-JavaScript testing.

However, this approach to using classes relies on two assumptions:

There is a third route, which seems messy but is potentially better.

Approach 3: data- attribute

  <div data-testinghook="myThing">I'll show first.</div>

  <script type="text/javascript">
    // querySelectorAll returns an array containing the element
    var myThing = document.querySelectorAll('[data-testinghook="myThing"]')[0];
    myThing.innerHTML = "I'll show now";

That last one seems fairly messy, though, and it'll make your HTML look awful (which is actually not as bad as it sounds).

Which one should I use?

My 2 cents - use suggestion number 2. This ties neatly together with my philosophy of using the class structure to define a group of elements' purpose in CSS.