4.1. Start with the existing report

Writing tests is part of the overall development cycle, and therefore begins with a good feature request or bug report:


User Issue Report
Title: Suggested text is not a link (fp12345)

When performing a search on the website, the search engine identifies suspected typos and suggests an alternate search.

1 GOTO http://example.ca/search.html
2 Enter webteam
3 Click Search
Expected
The suggested spelling "Web Team" should be a link to perform that search
Actual
The text is present, but it is not a link

The key to this bug report is that it contains explicit steps that are able to reproduce the error (the basics of a good bug report), and steps to reproduce an error are a test of the system that should be formalized.

While this report is very clear as to what is going on, it still remains for a developer to determine why it is happening. After a technical Analysis, the Issue needs to be redefined taking into account the technical information:

Bug Description Report
Title: "Did you mean" text should be a link (rm54321)

Related FP12345

When performing a search on the website, the search engine identifies suspected typos and suggests an alternate search. In the case that the suggested text is multiple words, a link is generated with a space in the url:

http://example.ca/search.html?q=web team

This is an invalid URL and should read:

http://example.ca/search.html?q=web+team

Because the link is invalid, the web engine's link checking routines determine it to be an invalid URL and does not apply it.

Test
1 GOTO http://example.ca/search.html?q=webteam
Expected
The suggested spelling “Web Team” should be a valid link

Drawing directly from the user's issue report, we are able to clearly define the problem in technical terms as well as generate a simpler, and more reliable, test to determine that we have corrected the problem. Using this definition of a successful test, we can begin creating an automated Unit Test.

package ca.company.web.test.pages;

public class Search extends BaseTest {

  @Test(enabled=false,testName="rm1242")
  public void testSearchSpellCheck() {
  }

}

The basic construction of this is based on several conventions in our system:

The package and classname are the full path the webpage we are testing. In the case of a component it would be the path to the component. In this case, the page
/content/example/en/home/search
corresponds to
ca.company.web.test.pages.Search
It is also worth noting that the TestClass inherits from BaseClass, which is an internal class created specifically for the Company that contains several routines useful to testing at the Company in general.

The decorator Test has been used to pass messages about the test to the TestNG engine.
@Test
the presence of the @Test marker tells the engine that this is a test
testName=rm1242
gives a specific name to the test. This allows us to identify it in relation to the bug that identified it.

There are several other useful parameters that can be applied. It is recommended that you read the TestNG Documentation for more information.

By convention, all test functions start with the word “test” in lowercase. This allows us to group test routines separately from administrative routines in the same class. Also tests are the only functions that are to be public. While TestNG is not actually affected by this, for documentation purposes we can allow JavaDoc to pick up on all public functions, and know that it is only getting tests.

Once we have the test in place, the next step is to document the test. In an effort to keep all of our testing notes and regression test listing in one place, we use JavaDoc’s capabilities to put documentation and code in the same place. This means we can document our tests as well as maintain the code in conjunction with one another.

Currently, the eclipse project is the repository for all test cases.

The test definition in the comments should be a well formatted HTML document, describing the test to be performed. It should include a title (H1), description (paragraphs) and a detailed list outlining the steps to be performed. There should always be a standardized format for these test descriptions, this helps ensure they are always completely filled out, increases the rapidity which new people can follow them, and allows experienced individuals to retrieve information at a glance.

package ca.company.web.test.pages;


/**
 * Suite of tests for the Search Page
 * <p>
 * The Search page is one of the prime navigation points for company’s system
 * </p>
 * <pre>
 * $Id$
 * $URL$
 * </pre>
 */
public class Search extends BaseTest {

  /**
   * <h1>rm1242: "Did you mean" text should be a link</h1>
   * <p>
   * When performing a search on the website, the search engine 
   * identifies suspected typos and suggests an alternate search. 
   * In the case that the suggested text is multiple words, a link
   * is generated with a space in the url:
   * <blockquote><pre>http://example.ca/search.html?q=web team</pre></blockquote>
   * </p>
   * <p>
   * This is an invalid URL and should read:
   * <blockquote><pre>http://example.ca/search.html?q=web+team</pre></blockquote>
   * </p>
   * <p>
   * Because the link is invalid, CQ's Link Checker determines it 
   * to be an invalid URL and does not apply it.
   * </p>
   * <p>
   * Procedure:
   * <ol>
   * <li>GOTO: http://example.ca/search.html?q=webteam</li>
   * </ol>
   * RESULT: 
   * <ul>
   *  <li>search suggests "Did you mean: web team"</li>
   *  <li>"web team" should be a link</li>
   * </ul>
   * </p>
   * 
   */
  @Test(testName="rm1242")
  public void testSearchSpellCheck() {
    throw new ManualTestException();
  }
}

In the above example, note the throwing of “ManualTestException”. This Exception inherits from TestNG’s “SkipException”. It tells the test engine not to disable the test, but to report that the test must be run manually. From a Documentation point of view, this test definition is complete. A manual tester can pick up the JavaDocs and see that a test must be undertaken to verify system validity.

At this point, running the test will return a “yellow” indicator, and state that the test must be run manually. If you look at the JavaDoc view in Eclipse, the steps to manually verify this will be laid out.