Cucumber test framework is a tool for running automated acceptance tests written in a behavior-driven development (BDD) style. Cucumber test framework is written in the Ruby programming language. Cucumber projects are available for other platforms beyond Ruby. Some use Ruby Cucumber with a bridge into the target language (e.g. cuke4php and cuke4lua). Others use the Gherkin parser but implement everything else in the target language. Cucumber allows the execution of feature documentation written in business-facing text.

Cucumber works with Ruby, Java, .NET, Flex or web applications written in any language. It has been translated to over 40 spoken languages. – http://cukes.info/

The language that Cucumber understands is called Gherkin. Here is an example: – https://github.com/cucumber/cucumber/wiki

Feature: Search courses
Courses should be searchable by topic
Search results should provide the course code

Scenario: Search by topic
Given there are 240 courses which do not have the topic "biology"
And there are 2 courses A001, B205 that each have "biology" as one of the topics
When I search for "biology"
Then I should see the following courses:
| Course code |
| A001        |
| B205        |

While Cucumber can be thought of as a “testing” tool, the intent of the tool is to support BDD. This means that the “tests” (plain text feature descriptions with scenarios) are typically written before anything else and verified by business analysts, domain experts, etc. non technical stakeholders. The production code is then written outside-in, to make the stories pass.

Cucumber itself is written in Ruby, but it can be used to “test” code written in Ruby or other languages including but not limited to Java, C# and Python.

I will show an example how cucumber test framework – cucumber-jvm fits with cucumber-java and cucumber-junit.

You may also like to read:

Cucumber data table – convert one column table to list

Cucumber data table – convert two column table to map

Cucumber data table – convert three column table to list

Cucumber framework with Mule ESB

First create a blank maven project in Eclipse. You put values for Group Id, Artifact Id, Packaging, Name and Description. For example,

Group Id - com.jeejava
Artifact Id - cucumber
Packaging - jar
Name - Cucumber Project
Description - This project is for testing cucumber test framework

Click “Finish”.

Now open the pom.xml file and add the following dependencies for cucumber  test framework and junit.

<dependencies>
    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>1.0.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>info.cukes</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>1.0.11</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
</dependencies>

A standard Maven project directory structure will have a source folder src/test/resources, this is the directory where you should create your .feature files. So let’s create a feature for adding two numbers.

Create a file called add.feature in src/test/resources. You can of course create packages in this source folder to organize your feature files. I have put the feature file under com.jeejava.cucumber package. So the full path for the feature file is src/test/resources/com/jeejava/cucumber/add.feature.

Now let’s write our first simple scenario. We want to test that when two numbers are added together we will get the expected result.

src/test/resources/com/jeejava/cucumber/add.feature

Feature: Addition of two numbers

Scenario: Add two numbers
Given I input numbers 10 and 20 into the calculator
When I press add
Then I should get the result 30 on the screen

The above first scenario describes the steps that will have to be executed successfully for the Scenario to pass.

We will run the .feature using a JUnit Runner, which we are having from the Cucumber-Junit Library.

So all we need to do is to create a blank test class, and annotate it with JUnit’s @RunWith annotation as follows:

package com.jeejava.cucumber;

import org.junit.runner.RunWith;

import cucumber.junit.Cucumber;

@RunWith(Cucumber.class)
@Cucumber.Options(format = { "pretty", "html:target/cucumber.json" })
public class TestAdd {

}

You can now run TestAdd.java like you would any other JUnit test.

The console output:

Feature: Addition of two numbers

  Scenario: Add two numbers                             # in\webtuts\cucumber\add.feature:3
    Given I input numbers 10 and 20 into the calculator
    Given I input numbers 10 and 20 into the calculator
    When I press add
    When I press add
    Then I should get the result 30 on the screen
    Then I should get the result 30 on the screen

You can implement missing steps with the snippets below:

@Given("^I input numbers (\\d+) and (\\d+) into the calculator$")
public void I_input_numbers_and_into_the_calculator(int arg1, int arg2) throws Throwable {
    // Express the Regexp above with the code you wish you had
    throw new PendingException();
}

@When("^I press add$")
public void I_press_add() throws Throwable {
    // Express the Regexp above with the code you wish you had
    throw new PendingException();
}

@Then("^I should get the result (\\d+) on the screen$")
public void I_should_get_the_result_on_the_screen(int arg1) throws Throwable {
    // Express the Regexp above with the code you wish you had
    throw new PendingException();
}

Take a look at the JUnit Tab in your Eclipse IDE, the scenario steps were actually skipped, they were not executed because no step definitions were found. You’ll see some very helpful information about the scenario that was executed and the steps which were skipped.

The output also has shown you default implementations for the step definitions, how nice is that!

Let’s create a class for the step definitions. At this point if you run the below class you will see each step throwing PendingException() because the implementation for each step is still pending.

package com.jeejava.cucumber;

import cucumber.annotation.en.Given;
import cucumber.annotation.en.Then;
import cucumber.annotation.en.When;
import cucumber.runtime.PendingException;

public class AddStepDefinition {
    @Given("^I input numbers (\\d+) and (\\d+) into the calculator$")
    public void I_input_numbers_and_into_the_calculator(int arg1, int arg2)
            throws Throwable {
        // Express the Regexp above with the code you wish you had
        throw new PendingException();
    }

    @When("^I press add$")
    public void I_press_add() throws Throwable {
        // Express the Regexp above with the code you wish you had
        throw new PendingException();
    }

    @Then("^I should get the result (\\d+) on the screen$")
    public void I_should_get_the_result_on_the_screen(int arg1)
            throws Throwable {
        // Express the Regexp above with the code you wish you had
        throw new PendingException();
    }
}

At this point we are ready to implement the step definitions for cucumber test framework. Let’s start with the steps.

package com.jeejava.cucumber;

import static org.junit.Assert.assertTrue;
import cucumber.annotation.en.Given;
import cucumber.annotation.en.Then;
import cucumber.annotation.en.When;

public class AddStepDefinition {
    private int num1;
    private int num2;
    private int total;

    @Given("^I input numbers (\\d+) and (\\d+) into the calculator$")
    public void I_input_numbers_and_into_the_calculator(int arg1, int arg2)
            throws Throwable {
        num1 = arg1;
        num2 = arg2;
        assertTrue("The total is not zero.", total == 0);
    }

    @When("^I press add$")
    public void I_press_add() throws Throwable {
        total = num1 + num2;
    }

    @Then("^I should get the result (\\d+) on the screen$")
    public void I_should_get_the_result_on_the_screen(int arg1)
            throws Throwable {
        assertTrue("The expected total was 30, but actually is: " + total,
                total == arg1);
    }
}

Now run AddTest.java and you will see that all test steps have been passed.

The AddStepDefinition class could be refactored because num1, num2 etc. variables should not be declared here and it’s just for testing purpose.

You may also like to read:

Cucumber data table – convert one column table to list

Cucumber data table – convert two column table to map

Cucumber data table – convert three column table to list

Cucumber framework with Mule ESB

Thanks for reading.

Tags:

I am a professional Web developer, Enterprise Application developer, Software Engineer and Blogger. Connect me on Roy Tutorials | TwitterFacebook Google PlusLinkedin | Reddit

Leave a Reply

Your email address will not be published. Required fields are marked *