codecentric

ATDD and Thucydides – part 2 of 2

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

Hylke Stapersma

 

The concept of developing templates for OpenCms 8

OpenCms 8.5.1 got released last week and while test-driving the new edition I thought why not share a little knowledge about how to develop templates for OpenCms 8.x. The concept how it is done (and therefore the way to develop) changed rather significantly and this had been an impediment for days in our last project until we tackled it. This blog post aims to help you understand that new concept.

I want to give you two examples, one for version 7 and one for version 8. Both will have editable areas and the OpenCms 8 example will make use of so called “formatters” and inline editing, both being new state of the art features that were not available previously. These should make the life of content editors easier but developing got more complex, naturally.

(read more…)

Nick Prosch

 

A real ROCA using Bootstrap, jQuery, Thymeleaf, Spring HATEOAS and Spring MVC

What is the best way to build a web application?

I know, tough question, and in the end, there cannot be one definitive answer, because otherwise there wouldn’t exist an armada of different architectures, frameworks and libraries. During the last years, Single Page Applications (SPA) based on JavaScript became more and more popular, and it seemed to me a little bit like it’s the only way to go for the future. It makes sense to have no server-side session, for scalability (Cloud! Commodity hardware!) on the one hand, and for the user experience on the other hand. And there’s no way of avoiding to accept JavaScript as a first class citizen anyway, so why not go JavaScript all the way?
On the other hand there’s one word in the term ‘Single Page App’ that makes me afraid: Single. Everything in one page? Really? I mean, it could be really a lot. Think of a medium or big sized web application with a lot of developers working on it. Initial loading times are a small problem compared to organizing the work: client software design, namespaces, merging, testing. Even if that’s just new to us old Java developers, we still have one application for everything. It’s not easy to exchange certain parts, it’s not easy to integrate with other applications, and it’s not easy to integrate other applications into it.

ROCA – Resource-oriented Client Architecture

So what do you do if you don’t want to build a single page application? While working at a customer I came across ROCA (Resource-oriented Client Architecture) which is a set of rules for a web application architecture. It’s a short list, so before I repeat them here, please read them there.

Ready?

So now you know the rules, but that doesn’t mean you can instantly imagine how such an application would look like. At least I couldn’t. I learned that there are two important aspects:

RESTful style

RESTful communication is stateless, so we have no session state. We have meaningful bookmarkable URIs for each resource and sub-resource, and a resource ideally represents an object from our domain, or a list of objects from our domain. I say ideally, because that’s not a must. In a lot of use cases, a resource made for a web frontend cannot be mapped 1-on-1 to domain objects, but if it does, our life gets easier. To interact with those resources we use the four HTTP methods GET, POST, PUT and DELETE. So if our domain happens to be a movie database, usage could be:

  • GET on /movies for displaying all movies
  • POST on /movies for adding a movie
  • GET on /movies/42 for displaying the movie with id 42
  • PUT on /movies/42 for updating the movie with id 42
  • DELETE on /movies/42 for deleting the movie with id 42

A GET returns HTML markup (possibly through a template engine), PUT and DELETE are tunneled through a POST, and POST, PUT and DELETE return a redirect URI to follow the POST/REDIRECT/GET pattern.

Progressive enhancement

By now we have a Web 1.0 application that works perfectly without JavaScript. In a progressive enhancement style we can add all those little things that make up a Web 2.0 application, like partial page rendering, inline-editing, search term suggestion, instant search, context menus, mouse over previews turning into a form on click, and so on. It means that we probably need more than one representation of a resource, for example one that contains the whole page with all menus, one that contains just the content, and maybe one that presents the data in a popup style.
Progressive enhancement is done in an unobtrusive way, so we don’t have JavaScript generating HTML, we just use JavaScript for rendering, history management, refreshing and validating based on server-generated data.

The movie database – an example application

You learn the most if you try it out – so I built a web application following the ROCA rules (with a little help and inspiration of some people that know more about it than I do). It’s a movie database, and you can find it here on Github. I used Bootstrap, jQuery, Thymeleaf, Spring HATEOAS and Spring MVC for building it, and that’s why:

Bootstrap

I really didn’t have much to do with CSS and web design in general before I did this project, so Bootstrap came as a rescue. Everybody can do good-looking user interfaces with Bootstrap. And in a real world project there would probably be someone professional doing the web design.

jQuery

I really didn’t have much to do with JavaScript before I did this project – wait, did I write this before? Sounds familiar. However, jQuery seems to be the library of choice when working with JavaScript, and it worked out well.

Thymeleaf

If you want to generate HTML on the server in a normal request/response way, a standard way to do this is using some kind of template engine. Thymeleaf uses valid HTML as templates and adds template expressions as additional attributes with a th prefix. This way you can build working mock-ups and integrate them directly into your codebase. People specialised on web design may create CSS, HTML and JavaScript which can be used for presentations, and we can be sure that our product will look the same in the end.

Spring HATEOAS

Spring HATEOAS is a library for dealing with the hypermedia part in RESTful applications. I guess it was intended to use in RESTful web services, but there is no reason for not using it here. We have our domain objects delivered by our services. They have relations to other domain objects. In the browser, those relations are represented by links to another resource or sub-resource, for example the resource /movies/42 has a relation to its list of comments, which can be found following the URI /movies/42/comments. To convert our domain object into a resource, we need to create those links. Spring HATEOAS brings structure into this process by providing a Link and a Resource class, where the latter may contain a domain object and a list of Link objects. Furthermore it contains a ResourceAssembler interface which can be implemented to build special domain-resource-converters for domain classes, doing the conversion in exactly one place. This way it becomes a three-stepped process: getting domain data from a service, converting it into resources and inserting it into the template.

Spring MVC

I needed a request/response style web framework, and Spring MVC is one of them. I wanted to check if it fits well. And also I wanted to write a web application without a line of XML, and since that’s possible with Servlet 3.0 and Spring 3.1, I did it here. Note that you need a container capable of Servlet 3.0 to run the application (Tomcat 7 will do).

What now?

I encourage you to have a look at the code and let it run. Does it feel good? Or is an SPA maybe a better solution? Let me know what you think.

Tobias Flohre