Channels ▼
RSS

Testing

Project of the Month: Thucydides


Implementing the Tests

As work progresses, you will flesh out the details. However, acceptance tests are high-level communication tools, and we don't want to dive into the technical details too soon. Doing so would make the tests too rigid and fragile.

Instead, we describe the test in more high-level terms, as a series of reusable steps, in a similar manner to the way a tester would plan a manual test script. You can think of this process as using a custom testing DSL for your application. Once we have laid out these steps, we will move on to implementing the details.

Here is what our test steps look like in this example:

using "thucydides"

thucydides.tests_story SearchForArtifactsByName
thucydides.uses_steps_from DeveloperSteps

scenario "A developer looks for an existing Maven artifact by name and group id", {
    given "the developer is on the Maven Central search page", {
        developer.opens_the_search_page()
    }
    when "the user searches for artifacts with the name 'thucydides'", {
        developer.searches_for 'Thucydides'
    }
    then "the thucyidides core artifact should appear in the results list", {
        developer.should_see_artifacts_where(the("ArtifactId", is("thucydides")),
                                             the("GroupId", is("net.thucydides")))
    }
}

Steps are implemented as Java methods. In this case, the steps are implemented in a Java class called DeveloperSteps. The thucydides.uses_steps.from instruction creates and configures an instance of this class, and makes it available in the easyb story as the developer variable.

It is also perfectly possible to implement the acceptance criteria as plain JUnit tests. The test we just saw could also be implemented as shown here:

@RunWith(ThucydidesRunner.class)
@Story(Application.Search.SearchForArtifactsByName.class)
public class WhenSearchingForArtifacts {

    @Managed
    WebDriver driver;

    @ManagedPages(defaultUrl = "http://search.maven.org")
    public Pages pages;

    @Steps
    public DeveloperSteps developer;

    @Test
    public void should_search_for_artifacts_by_name() {
        developer.opens_the_search_page();
        developer.searches_for("Thucydides");
        developer.should_see_artifacts_where(
                                     the("ArtifactId", is("thucydides")),
                                     the("GroupId", is("net.thucydides")));

    }
}

The test steps are just normal annotated Java methods, implemented in a fairly ordinary class that are referred to as a "Step Library." The simplest way to create a Step Library class is to extend the ScenarioSteps class, as shown in the following example:

public class DeveloperSteps extends ScenarioSteps {

    public DeveloperSteps(Pages pages) {
        super(pages);
    }

    @Step
    public void opens_the_search_page() {
        onSearchPage().open();
    }

    @Step
    public DeveloperSteps searches_for(String search_terms) {
        onSearchPage().enter_search_terms(search_terms);
        onSearchPage().starts_search();
        return this;
    }

    @Step
    public void should_see_artifacts_where(PropertyMatcher... matchers) {
        shouldMatch(onSearchResultsPage().getSearchResults(), matchers);
    }

    private SearchPage onSearchPage() {
        return getPages().get(SearchPage.class);
    }

    private SearchResultsPage onSearchResultsPage() {
        return getPages().get(SearchResultsPage.class);
    }

}

The methods in a Step Library can either implement the test details directly or, for more complex test cases, break the step down further into sub-steps.


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