Overview

ATDD and Thucydides – part 2 of 2

2 Comments

In the previous post I described you can use ATDD for closing the gap between business, tester and development, in the second part of the post I will describe Thucydides a powerful tool for doing ATDD.

Thucydides

For testing applications on the web, selenium can be used. Selenium is a framework that allows tests to be written to work on multiple browsers in a generic way. These tests can be defined by recording them in the browser or to be written down in code. When recording selenium tests a problems can occur when the state changes of the web application, an expected element could become unavailable and fail your test. When defining tests in code, it could be possible that tests lose their readability for testers and people who represent the domain.

Keeping tests readable, reusable and repeatable could be a challenge, Thucydides is a selenium extension that allows people from the domain, developers and testers to have those tests. Thucydides is build around the idea that the tests tell the story of the application and are readable for everyone, Thucydides is a ATDD testing framework for the web.

Thucydides keeps the tests readable and reusable by making use of stories, features, acceptance criteria (tests) and steps. Stories define a high level description of a set of features for example user management. A story can be defined in features for example creating and removing a user. These features have acceptance criteria for example “a user manager is able to sort users on the user overview page”. A acceptance criteria is a collection of steps that have to be done to perform the action.

Implementing tests or acceptance criteria, different test languages/tools can be chosen Thucydides supports test tools like EasyB, jBehave and JUnit.  When implementing tests with Thucydides the following concepts are in important:

  • Page(model), a representation of a web page where for example links and buttons are considered properties of a page. The state of a page is represented in a page(model).
  • Steps, a grouping(library) of actions that can be performed on a page. For example clicking on a link on a page.
  • Test, a collection of steps defining a user operation and verify if the operations were done correctly.

The big difference for only choosing selenium is the ability to have steps. Steps adds a abstraction level, that allows the implementer of tests to create a library of operations that can be done on a web page. These libraries can be reused in other tests.

For running Thucydides tests maven is used, maven is a framework that allows to automate build, documentation and reporting processes. After configuring Thucydides in the project pom.xml, tests can be run by using the following command. ‘mvn verify’ (Make sure the web application is available while starting the tests.)

Reporting and documentation are an important part of Thucydides, the reports represent the implementation state of the application. The will also tell the (historic) story of the application, which acceptance criteria are met, a which steps are taken to meet these acceptance criteria. In the reports a drilldown is possible from stories to the actual steps that have be taken to test the story.

Example of a Thucydides report:

For training purposes we’ve created a training application that is based on Weinburg-Myers triangle program example. This training application contains examples of wide range of tests. This training application also contains examples making use of Thucydides. (For running tests please read the README file on github https://github.com/codecentric/TDDTrainingApplication/blob/master/README.md)

The Thucydides concepts are also available in the training application, we use a page model for the representation of a web page.

public class TriangleCalculationPage extends PageObject {
 
public TriangleCalculationPage(WebDriver driver) {
super(driver);
}
 
@FindBy(name = "triangleSide1")
private WebElement inputSide1;
 
@FindBy(name = "triangleSide2")
private WebElement inputSide2;
 
@FindBy(name = "triangleSide3")
private WebElement inputSide3;
 
@FindBy(css = "button[type='submit']")
private WebElement submitButton;
 
public boolean hasInputSide1() {
return element(getInputSide1()).isCurrentlyVisible();
}
 
public boolean hasInputSide2() {
return element(getInputSide2()).isCurrentlyVisible();
}
 
public boolean hasInputSide3() {
return element(getInputSide3()).isCurrentlyVisible();
}
 
public boolean hasSubmitButton(){
return element(getSubmitButton()).isCurrentlyVisible();
}
 
}

In the TDD training application there are steps to defined for operation that can be done on a web page.

public class TriangleCalculationSteps extends ScenarioSteps{
 
public TriangleCalculationSteps(Pages pages) {
super(pages);
}
 
@Step("Open triangle calculation form")
public void openTriangleCalculationForm(){
getPages().get(TriangleCalculationPage.class).open();
}
 
@Step("Fill in triangle sides")
public void fillInTriangleSides(String triangleSide1,String triangleSide2,String triangleSide3){
TriangleCalculationPage triangleCalculationPage = getPages().currentPageAt(TriangleCalculationPage.class);
triangleCalculationPage.getInputSide1().clear();
triangleCalculationPage.getInputSide2().clear();
triangleCalculationPage.getInputSide3().clear();
triangleCalculationPage.getInputSide1().sendKeys(triangleSide1);
triangleCalculationPage.getInputSide2().sendKeys(triangleSide2);
triangleCalculationPage.getInputSide3().sendKeys(triangleSide3);
}
 
@Step("Submit triangle calculation form")
public void submitTriangleSideForm(){
TriangleCalculationPage triangleCalculationPage = getPages().currentPageAt(TriangleCalculationPage.class);
triangleCalculationPage.getSubmitButton().click();
}
 
@Step("Should see the error page")
public void shouldBeAtErrorPage(){
Assert.assertTrue("Should see the error page", getPages().isCurrentPageAt(TriangleCalculationErrorPage.class));
}
 
@Step("Should see the success page")
public void shouldBeAtSuccessPage(){
Assert.assertTrue("Should see the success page", getPages().isCurrentPageAt(TriangleCalculationSuccessPage.class));
}
 
@Step("Expect triangle type on success page")
public void expectTriangleTypeOnSuccessPage(TriangleType triangleType){
TriangleCalculationSuccessPage triangleCalculationSuccessPage = getPages().currentPageAt(TriangleCalculationSuccessPage.class);
Assert.assertTrue("Triangle success page should have triangle type element",triangleCalculationSuccessPage.hasTriangleTypeSpan());
Assert.assertThat("Triangle type is not correct",triangleType, Matchers.equalTo(TriangleType.valueOf(triangleCalculationSuccessPage.getTriangleTypeSpan().getText())));
}
 
}

By having these steps and pagemodels the following stories / scenarios can now be tested. These tests can by run with JUnit for example.

@RunWith(ThucydidesRunner.class)
@Story(Application.TriangleCalculation.Success.class)
public class TriangleCalculationSuccessStory {
 
@Managed(uniqueSession = true)
public WebDriver webDriver;
 
@Getter
@ManagedPages
public Pages pages;
 
@Steps
public TriangleCalculationSteps steps;
 
@Test
@Title("Test triangle type EQUILATERAL")
public void testNonNumericEquilateral() {
fillInTriangleCalculationForm("2", "2", "2", TriangleType.EQUILATERAL);
}
 
@Test
@Title("Test triangle type ISOSCELES")
public void testNonNumericInputSide2() {
fillInTriangleCalculationForm("2", "3", "2", TriangleType.ISOSCELES);
}
 
@Test
@Title("Test triangle type SCALENE")
public void testNonNumericInputSide3() {
fillInTriangleCalculationForm("2", "3", "4", TriangleType.SCALENE);
}
 
private void fillInTriangleCalculationForm(String side1, String side2, String side3, TriangleType triangleType) {
steps.openTriangleCalculationForm();
steps.fillInTriangleSides(side1, side2, side3);
steps.submitTriangleSideForm();
steps.shouldBeAtSuccessPage();
steps.expectTriangleTypeOnSuccessPage(triangleType);
}
 
}

Conclusion

ATDD allows domain representatives, testers and developers to work in a more uniform way by having tests written down in a uniform language everybody understands. A uniform language or DSL can be interpreted by people and machines, which allows for readability and repeatability.

For acceptance testing web application frameworks like Thucydides and Fitness can be used. Thucydides allows tests or acceptance criteria to be written for different test tools like EasyB, jBehave or JUnit.

Links

Thucydides
TDD Training application
TDD Weinburg-Myers example
ATDD
DSL
EasyB
Cucumber
JBehave
Selenium
Fitnesse

Kommentare

  • Andreas Ebbert-Karroum

    So what problem does Thucysomething exactly solve? It can be integrated with JBehave and I tend to claim that the tests that I automate with JBehave are maintainable and readable.

    At the same time I *don’t* want the domain experts to mess with the automation side of the tests. If at all they write the stories and scenarios in JBehave. What happens inside the test (the Steps in JBehave) in my experience is usually something a domain expert is neither curious about nor talented in.

    From the Thucy website I concluded that there are a few useful annotations (like @FindBy for fields) and a better reporting than JBehave, which is not too difficult. But that’s about it.

    • Hylke Stapersma

      I agree with you, I don’t think that the domain experts should mess with automation side of the tests. In my opion is the result of the dialog between domain experts, testers and developers more valuable. Thucydides is a framework that allow you to have that dialog automated.

Comment

Your email address will not be published. Required fields are marked *