John is an experienced consultant specialising in Enterprise Java, Web Development, and Open Source technologies, currently based in Sydney, Australia. Well known in the Java community for his many published articles, and as author of Java Power Tools and Jenkins: The Definitive Guide, and founder of the open source Thucydides Automated Acceptance Test Library project, John helps organisations to optimize their Java development processes and infrastructures and provides training and mentoring in agile development, automated testing practices, continuous integration and delivery, and open source technologies in general. John is the CEO of Wakaleo Consulting, and runs several Training Courses on open source Java development tools and best practices. John is a DZone MVB and is not an employee of DZone and has posted 125 posts at DZone. You can read more from them at their website. View Full User Profile

Getting started with Thucydides – using the Thucydides Maven Archetypes

11.02.2011
| 3806 views |
  • submit to reddit

Thucydides is an open source library that lets you use WebDriver/Selenium 2 to write better acceptance tests. . The easiest way to start a new Thucydides project is to use the Maven archetype. Two archetypes are currently available: one for using Thucydides with JUnit, and another if you also want to write your acceptance tests (or a part of them) using easyb.

From the command line, you can run mvn archetype:generate and then select the net.thucydides.thucydides-easyb-archetype archetype from the proposed list of archetypes. Or you can use your favorite IDE to generate a new Maven project using an archetype.

$ mvn archetype:generate
...
Define value for property 'groupId': : com.mycompany
Define value for property 'artifactId': : webtests
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  com.mycompany: :
Confirm properties configuration:
groupId: com.mycompany
artifactId: webtests
version: 1.0-SNAPSHOT
package: com.mycompany
 Y: :
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2:33.290s
[INFO] Finished at: Fri Oct 28 07:20:41 NZDT 2011
[INFO] Final Memory: 7M/81M
[INFO] ------------------------------------------------------------------------

This will create a simple Thucydides project, complete with a Page Object, a Step library and two test cases, one using JUnit, and one using easyb. Before going any further, take the project for a spin: go into the generated project directory, run the tests and generate the reports:

$ mvn test thucydides:aggregate

This should run some web tests and generate a report in target/site/thucydides directory (open the index.html file). You should see a report like this one:

If you drill down into the individual test reports, you will see an illustrated narrative for each test:

Now for the details. the project directory structure is shown here:

+ src
   + main
      + java
         + com.mycompany.pages
            - HomePage.java   

   + test
      + java
         + com.mycompany.pages
            + requirements
               - Application.java
            + steps
               - EndUserSteps.java
            - SearchByKeywordStoryTest.java 

      + stories
         + com.wakaleo.webtests.wikipedia
            - SearchingForCats.story

This project is designed to provide a starting point for your Thucydides acceptance tests, and to illustrate some of the basic features. The tests come in two flavors: easyb and JUnit. easyb is a Groovy-based BDD (Behaviour Driven Development) library which works well for this kind of test. The sample easyb story can be found in the SearchingForCats.story file, and looks something like this:

	using "thucydides"

	thucydides.uses_default_base_url "http://www.wikipedia.com"
	thucydides.uses_steps_from EndUserSteps
	thucydides.tests_story SearchBySingleKeyword

	scenario "Searching for cats", {
	    given "the user is on the home page", {
	        end_user.is_on_the_wikipedia_home_page()
	    }
	    when "the end user searches for 'cats'", {
	        end_user.searches_by_keyword('cats')
	    }
	    then "they should see the corresponding article", {
	       end_user.should_see_article_with_title("Cat - Wikipedia, the free encyclopedia")
	    }
	}

A cursory glance at this story will show that it relates a user searching for entries on cats on Wikipedia. However only the “what” is expressed at this level – the details are hidden inside the test steps and, further down, inside page objects.

If you prefer pure Java tests, the JUnit equivalent can be found in the SearchByKeywordTest.java file:

@Story(SearchBySingleKeyword.class)
@RunWith(ThucydidesRunner.class)
public class SearchByKeywordStoryTest {

    @Managed(uniqueSession = true)
    public WebDriver webdriver;

    @ManagedPages(defaultUrl = "http://www.wikipedia.com")
    public Pages pages;

    @Steps
    public EndUserSteps endUser;

    @Test
    public void searching_by_keyword_cat_should_display_article_about_cats() {
        endUser.is_on_the_wikipedia_home_page();
        endUser.searches_by_keyword("cats");
        endUser.should_see_article_with_title("Cat - Wikipedia, the free encyclopedia");

    }

}

As you can see, this is a little more technical but still very high level.

The step libraries contain the implementation of each of the steps used in the high-level tests. For complex tests, these steps can in turn call other steps. The step library used in this example can be found in EndUserSteps.java:

public class EndUserSteps extends ScenarioSteps {

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

    @Step
    public void searches_by_keyword(String keyword) {
        enters(keyword);
        performs_search();
    }

	@Step
	public void enters(String keyword) {
        onHomePage().enter_keywords(keyword);
	}

    @Step
    public void performs_search() {
        onHomePage().starts_search();
    }

    private HomePage onHomePage() {
        return getPages().currentPageAt(HomePage.class);
    }

    @Step
	public void should_see_article_with_title(String title) {
        assertThat(onHomePage().getTitle(), is(title));
	}

    @Step
    public void is_on_the_wikipedia_home_page() {
        onHomePage().open();
    }
}

Page Objects are a way of encapsulating the implementation details about a particular page. Selenium 2 has particularly good support for page objects, and Thucydides leverages this. The sample page object can be found in the HomePage.java class:

	@DefaultUrl("http://www.wikipedia.org")
	public class HomePage extends PageObject {

		private WebElement searchInput;

		@FindBy(name="go")
		private WebElement searchButton;

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

		public void enter_keywords(String keyword) {
			searchInput.sendKeys(keyword);
		}

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

The final piece in the puzzle is the Application.java class, which is a way of representing the structure of your requirements in Java form, so that your easyb and JUnit tests can be mapped back to the requirements they are testing:

	public class Application {
	    @Feature
	    public class Search {
	        public class SearchByKeyword {}
	        public class SearchByAnimalRelatedKeyword {}
	        public class SearchByFoodRelatedKeyword {}
	        public class SearchByMultipleKeywords {}
	        public class SearchForQuote{}
	    }

	    @Feature
	    public class Backend {
	        public class ProcessSales {}
	        public class ProcessSubscriptions {}
	    }

	    @Feature
	    public class Contribute {
	        public class AddNewArticle {}
	        public class EditExistingArticle {}
	    }
	}

This is what enables Thucydides to generate the aggregate reports about features and stories.

 

From http://weblogs.java.net/blog/johnsmart/archive/2011/10/31/getting-started-thucydides-%E2%80%93-using-thucydides-maven-archetypes

Published at DZone with permission of John Ferguson Smart, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Amara Amjad replied on Sun, 2012/03/25 - 2:29am

Hi John,

I tried following process but no "index.html" is generated:

1. $ mvn archetype:generate

2. Selected "thucydides-easyb-archetype" or "thucydides-simple-archetype"

3. $ mvn test thucydides:aggregate

What's wrong? Need additional settings?

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.