Developing Behavior-Driven Tests for JEE Web Applications with Jbehave – Part II
December 30, 2019
By:
Dani Shemesh
,
Following Part I of this series we now discuss the Java implementation.
Writing Stories and Java Implementation
The following is a discussion of some Volcano test cases and their Java implementation.
Registration story
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:
Carry the Jbehave @Given annotation
The String parameter of the annotation should match the text described in the step, while the user name (i.e.) ‘dani shemesh’ is replaced with a variable $user
To capture the user parameter, the function receives a String parameter, following the @Named annotation
The @Given implementation of this scenario is a dummy for obvious reasons.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Next is the implementation of the registration step where we cache the user details:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
And the verification step, where the user should be able to log in and have a live token.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
Re-use the java implementation of the log-in method (reuse @Given methods)
Avoid creating a new user and log-in before each scenario (reuse @When actions)
This brings up unexpected challenges from an OOP point of view. Before discussing them, let’s explain why
The Jbehave environment
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.
Re-use the @Given methods
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Implement tests for similar entities in the same class
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Re-use actions with Dependency Injection using Spring
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.
We’ll use ‘org.springframework’ artifacts for the Spring integration:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
To make our test classes to be singleton spring beans, using the @Service annotation:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
to identify the test classes beans under com.fullgc.jbehave namespace, using @ContextConfiguration annotation and a spring-context xml file:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
To inject the resources to the test classes, using the @Autowired annotation and the following Thucydides artifact
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
For the integration of the bean classes and with Jbehave, using SpringIntegration class.
The UserAccount test class now looks like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters