Archive for August 2014

Acceptance Tests using Cucumber

Most of the Systems are buggy due to lack of Acceptance tests, so in today's post I will try to walk you through a simple Cucumber based acceptance test for the following very common JIRA User story.
As a RM User of the System
I want to make sure that entitlements are properly set
So that I am able to Place Orders in the new Order Entry System.
Each test case in Cucumber is called a scenario, and scenarios are grouped into features. Each scenario contains several steps. The good thing about Cucumber is that your JIRA story can be taken as is to form the basis of acceptance test so that Business and Developers can be in talking terms with each other. I am skipping the Maven wiring for the project and jumping directly into the feature that we want to implement in this post.

Step 1 : Describe behavior of the Test in plain English (roles2functions.feature)
Feature: User Entitlement 

  Scenario:
    User of the Bank in certain role would like 
    to access certain functionality of existing System.

    When The logged In User "U12345" has 
       standard "RM" role
    Then "Place Orders" functionality 
       of "OES" application should be available to him/her
There is a scope for enriching this feature description but for the sake of the goal of this post (introducing you to Cucumber), we are good to go.
In this .feature file We’ve translated one of the acceptance criteria we were given in the JIRA task into a Cucumber scenario that we can ask the computer to run over and over again. The keywords Feature, Scenario, When, and Then are the structure, and everything else is documentation.

Step 2 : Implementing Our Step Definitions
package com.gognamunish;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import java.util.List;
import org.junit.Assert;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

/**
 * A very basic implementation for the Acceptance criteria.
 * @author Munish Gogna
 */
public class EntitlementFixtures {

 String role;
 EntitlementService entitlementService = new EntitlementService();

 @When("^The logged In User \"(.*?)\" has standard \"(.*?)\" role$")
 public void the_logged_In_User_has_role(String userId, String role)
   throws Throwable {
  
  Assert.assertNotNull(role);
  Assert.assertNotNull(userId);
                this.role = role;

  List<String> userRoles = entitlementService.getUserRoles(userId);
  assertThat(true, equalTo(userRoles.contains(role)));
 }

 @Then("^\"(.*?)\" functionality of \"(.*?)\" application should be available to him/her$")
 public void functionality_of_application_should_be_available_to(
   String function, String application) throws Throwable {
  Assert.assertNotNull(function);
  Assert.assertNotNull(application);

  List<String> functions = entitlementService
    .getFunctionsForRoleAndApplication(role, application);
  assertThat(true, equalTo(functions.contains(function)));

 }
}

Let's run our Fixtures using Cucumber runner as shown below:
package com.gognamunish;

import org.junit.runner.RunWith;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
public class RunEntitlementTest {
// intentional
}
Well well well - all tests have passed :)
1 Scenarios (1 passed)
2 Steps (2 passed)
0m0.310s

In case if the test is failing the logs will have enough information about the Assertion that was made.

Summary from this post
Software teams work best when the developers and business stakeholders are communicating clearly with one another. A great way to do that is to collaboratively specify the work that’s about to be done using automated acceptance tests (and the good thing about Cucumber is that they can be imported directly from User stories in JIRA).

In the next article I would evaluate Fitnesse for the same feature.
Tuesday, August 26, 2014
Posted by Munish Gogna

Popular Post

Labels

enums (1) java (2) JAX-RS (1) JPA (1) mysql (1) request 2 (1) RESTful (1) sphinx (1) tomcat (1) web service (2) ws (2)