Skip to content

February 22, 2012

Managing state between steps

by The Silver Teaspoon

Sometimes it’s useful to be able to pass information between steps. For example, you might need to check that a client’s details that were entered into a registration form appear correctly on a confirmation page later on.

You could do this by storing the values in local variables, as illustrated in the following example:

@Test
public void "Search property when creating ad"() {
    login.login_as(UserAccount.A_DIVISION_WITHOUT_OPENS);
    property_owner.chooses_to_place_a_new_ad()
    property_owner.selects_ad_category_and_style("Houses For Sale", "Premium Ad Style")
    def publicationName = pages[PublicationDatesPage].publicationName;
    def publicationDate = pages[PublicationDatesPage].publicationDate;
    property_owner.presses_continue()

    publication_manager.select_first_existing_property()
    property_owner.publish_ad()

    def displayedPublicationName = pages[ConfirmationPage].getPublicationDate();
    def displayedPublicationDate = pages[ConfirmationPage].getPublicationName();
    assertThat(displayedPublicationDate, is(publicationDate));
    assertThat(displayedPublicationName, is(publicationName));
 }

The problem with this approach is that it tends to clutter up the steps, and it also leaks implementation details into the high-level tests. Another approach is to use the Thucydides test session, which is essentially a hash map allowing you to store variables for the duration of a single test. You can obtain this session map using the Thucydides.getCurrentSession() static method.

In the following example, we store the publication name and date, obtained from the current web page, in the test session.

@Step
public void notes_publication_name_and_date() {
    PublicationDatesPage page = pages().get(PublicationDatesPage.class);
    String publicationName = page.getPublicationName();
    DateTime publicationDate = page.getPublicationDate();

    Thucydides.getCurrentSession().put("publicationName", publicationName);
    Thucydides.getCurrentSession().put("publicationDate", publicationDate);
}
Then, in a step invoked later on in the test, you can check the values stored in the session:
public void checks_publication_details_on_confirmation_page() {
    ConfirmationPage page = pages().get(ConfirmationPage.class);
    String selectedPublicationName = (String) Thucydides.getCurrentSession().get("publicationName");
    DateTime selectedPublicationDate = (DateTime) Thucydides.getCurrentSession().get("publicationDate");
    assertThat(page.getPublicationDate(), is(selectedPublicationName));
    assertThat(page.getPublicationName(), is(selectedPublicationDate));
}
The end result is a more concise and high-level test:
@Test
public void "Search property when creating ad"() {
    login.login_as(UserAccount.A_DIVISION_WITHOUT_OPENS);
    property_owner.chooses_to_place_a_new_ad()
    property_owner.selects_ad_category_and_style("Houses For Sale", "Liner + Large Header + Attention Getter")
    property_owner.notes_publication_name_and_date()
    property_owner.presses_continue()
    publication_manager.select_first_existing_property()
    property_owner.publish_ad()
    property_owner.checks_publication_details_on_confirmation_page()
 }
Thucydides test session data is stored in a ThreadLocal variable, so it will work if tests are run in parallel. The test session is cleared at the start of each test, so test data stored from previous tests cannot interfere with the current test. If no variable is found with the requested name, the test will fail.
It is always preferable to keep the high-level acceptance tests as general as possible: using and comparing temporary variables at the test level clutters and distracts from the overall understanding of the test. Using the Thucydides test sessions can go a long way helping to do this.
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments

%d bloggers like this: