UI Development Standards for Test Automation

Posted on February 1, 2015
By Martin Lienhard

Web Pages

  Page Elements

  1. Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
  2. Set a unique HTML "ID" attribute for primary identification
    1. The "ID" attribute must be unique, so never duplicate an "ID" attribute
    2. This resolves to getElementByID() to locate the element
  3. Set a unique HTML "Name" attribute for secondary identification
    1. If an "ID" attribute cannot be used to uniquely identify an element, then the "Name" attribute must be unique, and not used by another element
    2. The "Name" attribute is helpful for locating groups of elements
    3. This resolves to getElementsByName() to locate the element
  4. Set a unique HTML "Class" attribute as an alternative
    1. If an "ID" or "Name" attribute cannot be used to uniquely identify an element, then the "Class" attribute must be unique, and not used by another element
    2. The "Class" attribute is helpful for locating groups of elements
    3. This resolves to getElementsByClassName() and querySelectorAll() to locate the element
  5. Set a unique HTML 5 custom data attribute as an alternative
    1. If an "ID", "Name", or "Class" attribute cannot be used to uniquely identify an element, then an HTML 5 custom data attribute must be unique, and not used by another element
    2. This resolves to querySelectorAll() to locate the element
  6. Do not create an element that requires the use of an XPath expression to locate the element
    1. On web applications XPath is the slowest expression type to parse by test automation tools and browsers
    2. This is not true for iOS and Android native applications
  7. Do not create an element where it can only be uniquely identified by it's text node
    1. Example:
      <span>John</span>
      <span>Smith</span>
    2. This requires an XPath expression to locate the element by it's text node
    3. Instead add an 'ID' attribute to identify the elements
      <span id='firstName'>John</span>
      <span id='lastName'>Smith</span>

  Wrapping Elements

  1. If the content of an element will change, then wrap the element with a unique parent element
    1. Examples are buttons, links, images, and hybrids:
      <button class="..." />

      <input type="button" value="save" onclick="..." />

      <input type="image" value="save" onclick="..." />

      <img name="save" src="..." onclick="..." />

      <a class="button" alt="save" href="..." />

      <a href="..." > <img src="..." /> </a>

      <div class="button" onclick="..." />
  2. It is common in content-driven applications to frequently change the content on a page, and this includes the element structure
    1. Content Management Systems (CMS) let Marketing teams manipulate the content of an element and publish it to production on-demand
    2. This is a common failure point for automated tests that locate an element by it's attributes

  Web Input Fields

  1. Always use the "ID" attribute
  2. Always set the "type" attribute

  Web Radio Buttons

  1. Always use the "ID" attribute
  2. If the radio button is selected, then always set the "checked" attribute
  3. When grouping mutually exclusive radio buttons:
    1. Give each element a unique "ID" and "value" attribute
    2. Each element can have a common "name" or "class" attribute

  Web Check Boxes

  1. Always use the "ID" attribute
  2. If the check box is checked, then always set the "checked" attribute
  3. When grouping mutually exclusive radio buttons:
    1. Give each element a unique "ID" and "value" attribute
    2. Each element can have a common "name" or "class" attribute

  Web Select Dropdowns

  1. Always use the "ID" attribute
  2. Always set the "selected" attribute on Option elements
  3. Always set the "selected" attribute on the default Option

  Web Links

  1. Ideally all links would have an "ID" attribute
  2. If an "ID" attribute is not used, then query string in the "href" attribute must contain a constant page name that can be used in a CSS Selector
    1. <a href="/index.html">Home</a>
    2. Now the element can be uniquely identified and located by querySelectorAll("a[href*='/index.html']");

  Web Labels

  1. Each label needs a "for" attribute that references another element's "ID" attribute

  Web Text

  1. If the text content needs to be evaluated or verified for testing, then always give it a unique attribute such as an ID, Name, or Class
  2. Do not let the text content elements stand alone without an attribute, as this makes evaluations, verifications, and assertions very difficult - if not impossible to perform

  Structures

    Web Tables and Grids

  1. Every row and column should be attributed by a unique identifier, and a common class
    1. Example table:
      <tr id="row_id_101" class="row_style">
         <td id="column_id_101" class="column_style">...</td>
         <td id="column_id_102" class="column_style">...</td>
      </tr>
      <tr id="row_id_102" class="row_style">
         <td id="column_id_201" class="column_style">...</td>
         <td id="column_id_202" class="column_style">...</td>
      </tr>
    2. Automation will search for all rows by CSS Selector using "class" attribute querySelectorAll(".row_style");
    3. A new object will be generated for each row
    4. The "ID" attribute will be used to uniquely identify each row
  2. Do not nest the unique identifier in a child element of the row
    1. Example list with divisions:
      <li>
         <div>
           <div item_id="101">...</div>
         </div>
         <div>
           <div id="price_0">...</div>
           <div id="quantity_0">...</div>
         </div>
         <div>
           <input id="textbox_01">...</input>
           <select id="dropdown_01">...</select>
         </div>
      </li>
      <li>
         <div>
           <div item_id="102">...</div>
         </div>
         <div>
           <div id="price_1">...</div>
           <div id="quantity_1">...</div>
         </div>
         <div>
           <input id="textbox_02">...</input>
           <select id="dropdown_02">...</select>
         </div>
      </li>
    2. It is incredibly difficult to uniquely identify and locate the child elements for each row
  3. If an "ID" attribute cannot be used to uniquely identify a row or column, then a unique "name", "class", or HTML 5 custom data attribute should be used

    Web Tabs

    Web Inline Frames

  1. If possible, do not use them
    1. iframes can cause problems on mobile browsers
  2. Do not nest iframes inside of another iframe

    Web Pop-up Windows

  1. Always give a constant, unique name for each pop-up window

  URI

    Web Page URL

  1. Pages should have a unique name for validation purposes
    1. Examples:
      index.html
      home.jsp
      home.ftl
      home.aspx
  2. Validating page titles and headers is not a good practice, because of Content Management Systems (CMS) the content can change frequently, so verifying title and headers is not a robust approach to validation


Native Apps

  Android Elements

  1. Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
  2. Set a unique resource ID attribute for primary identification
    1. The "resource-id" attribute must be unique, so never duplicate a "resource-id" attribute
  3. Set a unique accessibility ID attribute for secondary identification
    1. If an "resource-id" attribute cannot be used to uniquely identify an element, then the "content-desc" attribute must be unique, and not used by another element
  4. XPath expressions should be used as an alternative to search for views

  iOS Elements

  1. Every actionable element on a web page or native app should have a unique identifier that test automation tools can easily locate
  2. Set a unique "Name" attribute for primary identification
    1. The "Name" attribute must be unique, so never duplicate a "Name" attribute
  3. Set a unique accessibility ID attribute for secondary identification
    1. If an "Name" attribute cannot be used to uniquely identify an element, then the "Label" attribute must be unique, and not used by another element
  4. XPath expressions should be used as an alternative to search for views