1. Introduction
Cucumber is a BDD (Behavioral Driven Development) testing framework.
Using the framework to write repetitive scenarios with different permutations of inputs/outputs can be quite time-consuming, difficult to maintain and of course frustrating.
Cucumber came with a solution for reducing this effort by using the concept of Scenario Outline coupled with Examples. In the below section, we will try to take up an example and see how can we minimize this effort.
If you want to read more about the approach and Gherkin language, have a look at this article.
2. Adding Cucumber Support
To add support for Cucumber in a simple Maven project, we will need to add the following dependencies:
<dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-junit</artifactId> <version>1.2.5</version> <scope>test</scope> </dependency> <dependency> <groupId>info.cukes</groupId> <artifactId>cucumber-java</artifactId> <version>1.2.5</version> <scope>test</scope> </dependency> <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest-library</artifactId> <version>1.3</version> <scope>test</scope> </dependency>
Useful links to dependencies from Maven Central: cucumber-junit, cucumber-java, hamcrest-library
Since these are testing libraries, they don’t need to be shipped with the actual deployable – which is why they’re all test scoped.
3. A Simple Example
Let’s demonstrate both a bloated way and a concise way of writing featured files. Let’s first define the logic we want to write a test for:
Let’s first define the logic we want to write a test for:
public class Calculator { public int add(int a, int b) { return a + b; } }
4. Defining Cucumber Tests
4.1. Defining a Feature File
Feature: Calculator As a user I want to use a calculator to add numbers So that I don't need to add myself Scenario: Add two numbers -2 & 3 Given I have a calculator When I add -2 and 3 Then the result should be 1 Scenario: Add two numbers 10 & 15 Given I have a calculator When I add 10 and 15 Then the result should be 25
As seen here, 2 different combinations of numbers have been put to test here the addition logic. Apart from numbers, all the scenarios are exactly the same.
4.2. “Glue” Code
In order to test out these scenarios, i’s essential to define each step with corresponding code, in order to translate a statement into a functional piece of code:
public class CalculatorRunSteps { private int total; private Calculator calculator; @Before private void init() { total = -999; } @Given("^I have a calculator$") public void initializeCalculator() throws Throwable { calculator = new Calculator(); } @When("^I add (-?\\d+) and (-?\\d+)$") public void testAdd(int num1, int num2) throws Throwable { total = calculator.add(num1, num2); } @Then("^the result should be (-?\\d+)$") public void validateResult(int result) throws Throwable { Assert.assertThat(total, Matchers.equalTo(result)); } }
4.3. A Runner Class
In order to integrate features and the glue code, we can use the JUnit runners:
@RunWith(Cucumber.class) @CucumberOptions( features = { "classpath:features/calculator.feature" }, glue = {"com.baeldung.cucumber.calculator" }) public class CalculatorTest {}
5. Rewriting Features Using Scenario Outlines
We saw in Section 4.1. how defining a feature file can be a time-consuming task and more error prone. The same feature file can be reduced to mere few lines using the Scenario Outline:
Feature: Calculator As a user I want to use a calculator to add numbers So that I don't need to add myself Scenario Outline: Add two numbers <num1> & <num2> Given I have a calculator When I add <num1> and <num2> Then the result should be <total> Examples: | num1 | num2 | total | | -2 | 3 | 1 | | 10 | 15 | 25 | | 99 | -99 | 0 | | -1 | -10 | -11 |
When comparing a regular Scenario Definition with Scenario Outline, values no longer need to be hard-coded in step definitions. Values are replaced with parameters as <parameter_name> in step-definition itself.
At the end of Scenario Outline, values are defined in a pipe-delimited table format using Examples.
A sample to define Examples is shown below:
Examples: | Parameter_Name1 | Parameter_Name2 | | Value-1 | Value-2 | | Value-X | Value-Y |
6. Conclusion
With this quick article, we’ve shown how scenarios can be made generic in nature. And also reduce effort in writing and maintaining these scenarios.
The complete source code of this article can be found over on GitHub.