Channels ▼
RSS

JVM Languages

Project of the Month: Thucydides


Working with Page Objects

For Web tests, it is a common best practice to hide the more technical implementation details about the Web page being tested inside a class, known as a "Page Object." This class presents the business behavior performed by that page. This separation of concerns makes the tests cleaner and more readable, and makes test maintenance much easier.

Selenium 2 provides excellent support for the Page Object pattern, and Thucydides makes it easy to work with Selenium 2 page objects in your test steps. For example, the getPages() method in the aforementioned example provides a number of methods that help instantiate and query Page Objects. And the PropertyMatcher class used in the should_see_artifacts_where() step makes it easy to match or filter page fields or table contents using standard Hamcrest matchers.

The Page Objects themselves extend the PageObject class, but look very much like typical Selenium 2 page objects:

@DefaultUrl("http://search.maven.org/")
public class SearchPage extends PageObject {


    @FindBy(id="query")
    private WebElement search;

    @FindBy(id="queryButton")
    private WebElement searchButton;
    
    public SearchPage(WebDriver driver) {
        super(driver);
    }

    public void enter_search_terms(String searchTerms) {
        search.sendKeys(searchTerms);
    }

    public void starts_search() {
        searchButton.click();
    }
}

Thucydides also provides a few useful helper classes and methods to make writing Page Objects easier. The following example illustrates some of the extra support provided for working with HTML tables. The rowsFrom() method used in the getSearchResults() method, for example, retrieves the rows of a table in the form of a list of maps, where each row is represented as a map of String values, indexed by the table column headings.

import static net.thucydides.core.pages.components.HtmlTable.filterRows;
import static net.thucydides.core.pages.components.HtmlTable.rowsFrom;

public class SearchResultsPage extends PageObject {

    WebElement resultTable;

	public SearchResultsPage(WebDriver driver) {
		super(driver);
	}

    public List<Map<String, String>> getSearchResults() {
        return rowsFrom(resultTable);
    }

    public WebElementFacade resultTable() {
        return element(resultTable);
    }

    public void clickOnFirstRowMatching(PropertyMatcher... matchers) {
        List<WebElement> matchingRows = filterRows(resultTable, matchers);
        WebElement targetRow = matchingRows.get(0);
        WebElement detailsLink = targetRow.findElement(By.xpath(".//a[contains(@href,'artifactdetails')]"));
        detailsLink.click();
    }
}

Viewing the Results

You can run these tests just as you would any normal JUnit or easyb test, either from within your IDE or as part of your build process. However much of the value of Thucydides comes from its reports, which provide both a detailed, narrative documentation for your acceptance criteria and a high-level view of the features and stories currently being implemented.

To generate the full Thucydides report, you run the mvn thucydides:aggregate command from the command line. For this to work, make sure you have the "net.thucydides.maven.plugins" plugin group defined in your Maven "settings.xml" file, as in the following example:

<settings>
    <pluginGroups>     
        <pluginGroup>net.thucydides.maven.plugins</pluginGroup>
        …
    </pluginGroups
</settings>

Each executed test produces a narrative report, which illustrates both the test result and the steps that make up this test. The steps are illustrated by screenshots (as shown back in Figure 3), making it easy to get an accurate picture of how a particular feature has been implemented. These reports make up part of the "living documentation" of your system.

At a higher level, the Features and Stories treemap views give a vision of the current state of your features, both in terms of how many stories have been completed (and how many there are to go), and in terms of the relative complexity of each feature and story. Indeed, the number and complexity of the acceptance criteria can be used as an effective metric to measure the relative amount of work required to implement each feature. In addition, this can be used to track project progress in the "History" view.

Conclusion

Thucydides is an open source library designed to make writing and documenting automated acceptance tests easier, and indeed, it provides several powerful tools that make writing high-level tests easier. But its reporting capabilities take it much further, giving it the ability to both produce living documentation of your application's features and requirements, and to objectively report on project status and progress.

To learn more about the Thucydides framework, visit the Thucydides wiki for an introductory tutorial, or check out more details in the Thucydides User's Manual.


John Ferguson Smart is the CEO of Wakaleo Consulting, a company that provides consulting, training, and mentoring services in Enterprise Java and Agile Development and Testing practices. John is also the author of Java Power Tools and Jenkins: The Definitive Guide.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video