Following Part I of this series we now discuss the Java implementation.
The following is a discussion of some Volcano test cases and their Java implementation.
Let’s zoom in on the first story, which is the Volcano registration story file:
Narrative:
As a volcano enthusiast, Dani would like to register to Volcano Social Network.
Scenario:
A new user is signs-up for the volcano system.
Given Dani Shemesh is a Volcano enthusiast
When Dani signs-up for Volcano with the user name: dani and the password: 123456
Then Dani is able to log-in with the user name: dani and the password: 123456
Note that the story is written in the third person. This allows us to capture the subject (i.e. the user) later.
The ‘Given’ is linked with a Java method. The method should:
The @Given implementation of this scenario is a dummy for obvious reasons.
Next is the implementation of the registration step where we cache the user details:
And the verification step, where the user should be able to log in and have a live token.
Note that we have used a cache to store the new user’s details in the registration step.
Considering other future user actions, such as “change password” and “add a friend”, the user is required to be logged-in, meaning that this would be a given step:
Given dani is logged-in…
Now, we want to:
This brings up unexpected challenges from an OOP point of view. Before discussing them, let’s explain why
Though we are writing in Java, we are not in an OOP scope, but in Jbehave’s scope.
When JBehave begins, it registers all the implemented methods and their parameters. It then reads the steps in each scenario for each story and maps them to the appropriate method in the code behind. Here, all their values are in the memory and are executed one by one. The memory is cleaned after each story.
This one is easy. Instead of inheritance/composition, we can place the @Given methods wherever we like, and Jbehave will identify it. So, we’ll create a dedicated class for given methods, dealing with user scenarios:
We can once again take advantage of the Jbehave environment to place test implementations with similar characters together, even if they implement steps of different stories, for example:
To reuse actions, in our case the user that we created and logged in with in the “registration” step, needs to be cached. We cannot put the cache in a global variable or static at some place, since we are working with different classes and the memory cleans up after each story.
Luckily, Jbehave supports some of the most popular, Java-based, dependency injection plugins. The most popular is probably Spring, and we’ll use it to inject the resources (i.e. the cache) we need for reusing actions.
We’ll use ‘org.springframework’ artifacts for the Spring integration:
To make our test classes to be singleton spring beans, using the @Service annotation:
to identify the test classes beans under com.fullgc.jbehave namespace, using @ContextConfiguration annotation and a spring-context xml file:
To inject the resources to the test classes, using the @Autowired annotation and the following Thucydides artifact
For the integration of the bean classes and with Jbehave, using SpringIntegration class.
The UserAccount test class now looks like this:
Note that the new user is cached and reused for a “change password” action.
(We use the cache in the same fashion as the ‘add friend’ story, which we won’t cover here, but can be found in the ‘Volcano’ repository)
The other test classes should be modified in a similar fashion.
The spring context:
In Part III we’ll learn how to launch the web app in compile time, run the tests and generate summary reports.