Friday, 4 May 2018

Cucumber: Scenario outline

If multiple scenarios are following same steps, but with different inputs and different outputs, then we can model them using scenario outline in efficient way.

Let me explain with an example.

BallGame.feature
Feature: Example of Scenario_outline

 Scenario: Remove 10 balls from the box
 
  Given A box of 100 balls
  When I taken 10 balls out of the box
  Then 90 balls remaining in the box
  
 Scenario: Remove 20 balls from the box
 
  Given A box of 200 balls
  When I taken 20 balls out of the box
  Then 180 balls remaining in the box
  
 Scenario: Remove 30 balls from the box
 
  Given A box of 100 balls
  When I taken 30 balls out of the box
  Then 70 balls remaining in the box
As you closely observe above scenarios, all these three scenarios following same steps.

By using Scenario Outline, Examples with tables and < > delimited parameters, we can rewrite above feature file in more compact and efficient way.

BallGame.feature

Feature: Example of Scenario_outline
 
 Scenario Outline: Remove balls from the box
 
  Given A box of <noOfBalls>
  When I taken <noOfBallsTaken> balls out of the box
  Then <remainingBalls> balls remaining in the box

  Examples:
   | noOfBalls | noOfBallsTaken | remainingBalls |
   |   100     |     10         |    90          |
   |   200     |     20         |    180         |
   |   100     |     30         |    70          |


Gherkin generates below Skelton for above feature file. I used place holders in the scenario outline using <> (Angular brackets). Real values in the Examples, are substituted in scenario outline steps.

@Given("^A box of (\\d+)$")
public void a_box_of(int arg1) throws Exception {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@When("^I taken (\\d+) balls out of the box$")
public void i_taken_balls_out_of_the_box(int arg1) throws Exception {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@Then("^(\\d+) balls remaining in the box$")
public void balls_remaining_in_the_box(int arg1) throws Exception {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

Find the below working application.

BoxUtil.java

package com.sample.util;

public class BoxUtil {

 public static int getRemainingBalls(int noOfBalls, int noOfBallsTaken){
  return noOfBalls - noOfBallsTaken;
 }
}

BallGameTest.java
package com.sample.test;

import static org.junit.Assert.assertEquals;

import com.sample.util.BoxUtil;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class BallGameTest {
 int totalNoOfBalls;
 int ballsTaken;
 
 @Given("^A box of (\\d+)$")
 public void a_box_of(int arg1) throws Exception {
  this.totalNoOfBalls = arg1;
 }

 @When("^I taken (\\d+) balls out of the box$")
 public void i_taken_balls_out_of_the_box(int arg1) throws Exception {
  this.ballsTaken = arg1;
 }

 @Then("^(\\d+) balls remaining in the box$")
 public void balls_remaining_in_the_box(int arg1) throws Exception {
  assertEquals(arg1, BoxUtil.getRemainingBalls(totalNoOfBalls, ballsTaken));
 }

}


TestRun.java

package com.sample.main;

import org.junit.runner.RunWith;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(monochrome = true, features = "src/test/java/com/sample/features", glue = "com.sample.test", plugin = {
  "pretty" })
public class TestRun {

}

When you ran the application as junit test, you can get below messages in console.

Feature: Example of Scenario_outline

  Scenario Outline: Remove balls from the box # src/test/java/com/sample/features/BallGame.feature:3
    Given A box of <noOfBalls>
    When I taken <noOfBallsTaken> balls out of the box
    Then <remainingBalls> balls remaining in the box

    Examples: 

  Scenario Outline: Remove balls from the box # src/test/java/com/sample/features/BallGame.feature:11
    Given A box of 100                        # BallGameTest.a_box_of(int)
    When I taken 10 balls out of the box      # BallGameTest.i_taken_balls_out_of_the_box(int)
    Then 90 balls remaining in the box        # BallGameTest.balls_remaining_in_the_box(int)

  Scenario Outline: Remove balls from the box # src/test/java/com/sample/features/BallGame.feature:12
    Given A box of 200                        # BallGameTest.a_box_of(int)
    When I taken 20 balls out of the box      # BallGameTest.i_taken_balls_out_of_the_box(int)
    Then 180 balls remaining in the box       # BallGameTest.balls_remaining_in_the_box(int)

  Scenario Outline: Remove balls from the box # src/test/java/com/sample/features/BallGame.feature:13
    Given A box of 100                        # BallGameTest.a_box_of(int)
    When I taken 30 balls out of the box      # BallGameTest.i_taken_balls_out_of_the_box(int)
    Then 70 balls remaining in the box        # BallGameTest.balls_remaining_in_the_box(int)

3 Scenarios (3 passed)
9 Steps (9 passed)
0m0.266s



Previous                                                 Next                                                 Home

No comments:

Post a Comment