Sunday, December 20, 2015

Start Coding With Cucumber JVM

Now we know the basic terms and different component of cucumber. Here we will create a simple program using cucumber-jvm. We will follow the below steps to create a simple projects using cucumber-jvm.

So cucumber-jvm must have three parts
  1. Code Runner Class
  2. Feature File
  3. Glue Code Or Step Generation File.

Step 1:

@RunWith   annotation:

 We need help from JUnit to run cucumber tests. So we need to use @RunWith annotation to call the cucumber class from normal JUnit class and pass Cucumber.class as a parameter in @RunWith annotation and put this annotation above the class name means before the class declaration starts.

So after using this annotation in JUnit class it should look like below :

@RunWith(Cucumber.class)
public class Runner {
}


@CucumberOptions:

features and glue option :

 If we think logically then we can understand that we also need to send the feature file location and glue code or step generation file location. It can be possible using @CucumberOptions annotation and passing feature file location using features={"./newtest.feature"} and passing glue code or step generation file location or package name using
glue ={"com/automation/steps"}.

We can pass multiple features or step generation file in the same project then we pass the multiple file separated by comma then features option should be looks like below 
 features={"./newtest.feature","./newtest1.feature"}

and glue should be looks like:  
 glue ={"com/automation/steps","com/automation/anothersteps"}

So in summary @CucumberOptions should be looks like below
@CucumberOptions( features={"./newtest.feature"},glue ={"com/automation/steps"})

plugin option:

plugin option is used for creating different type of  reporting. Different types of  reports created under the target folder so syntax for creating different type of report is describe below :
        Syntax for html report is                :plugin = {"html:target/cucumber-html-report"}
       
Syntax for json report is                 :plugin = {"json:target/cucumber.json"}         
        Syntax for text report is                  :plugin = {"pretty:target/cucumber-pretty.txt"}
       
Syntax for json usage report is       :plugin = {"usage:target/cucumber-usage.json"}
       
Syntax for xml report is                  :plugin = {"junit:target/cucumber-results.xml"}
Here we also mention the different type of reports format with comma separated option. So @CucumberOption should be looks like below with different type of  reporting option.

@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        })


So at last our runner class should be looks like below:


import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.SnippetType;
import cucumber.api.junit.Cucumber;
@RunWith(Cucumber.class)
@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        },features={"./newtest.feature"},
            glue ="com/automation/steps",
            dryRun=false,monochrome = true, snippets= SnippetType.CAMELCASE)

public class Runner {
}


Step 2:


Now we create a .feature file for a sample. Here we create a scenario where we add two number as 1 and 6 and result should be 7. So our feature file looks like below:

Feature: This is a sample feature file

    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Result should be 7

 

Step 3:


 So we are now creating our glue or step definition file for this particular step file. Glue code or step definition file is nothing but a java file. Step definition file should be looks like below :

public class Test {
    int input1,input2,total;
    @Given("^Two number as (\\d+) and (\\d+)$")
    public void twoNumberGivenAsAndAnotherIs(int firstInput, int secondInput) throws Throwable {
        input1 = firstInput;
        input2 = secondInput;
    }

    @When("^We add this two given number$")
    public void weAddThisTwoGivenNumber() throws Throwable {
        total = input1+input2;
    }

    @Then("^Result should be (\\d+)$")
    public void resultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, total);
    }

}

 Regular expression is used on each annotation so we are now try to understand the meaning of the below regular expression:
^  =  This is used to mentioned that string is starting from here.
$  =  This is used to mentioned that string ends here.
+  =  This is used to find one or more time.
\d =  This is used to represent digit.
\   =  This expression represent the escape characters.

So now question is how we will create the basic structure of glue or step definition file? 

It is very easy we just run the cucumber Runner class after creating the feature file then we observe that something written over the console pane of the eclipse it should be looks like below :

You can implement missing steps with the snippets below:

@Given("^Two number as (\\d+) and (\\d+)$")
public void twoNumberAsAnd(int arg1, int arg2) throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@When("^We add this two given number$")
public void weAddThisTwoGivenNumber() throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}

@Then("^Result should be (\\d+)$")
public void resultShouldBe(int arg1) throws Throwable {
    // Write code here that turns the phrase above into concrete actions
    throw new PendingException();
}


 Now we remove the comments and PendingException() and implement our logic.

[Note: If we observe deeply then we can understand the method name of auto generated code follow the camel notation because we mention snippets= SnippetType.CAMELCASE on @CucumberOptions annotation on cucumber runner class. Default it follow the underscore notaion for method name]

So our complete code looks like below:

Runner Class :

 

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

@RunWith(Cucumber.class)

@CucumberOptions(
        plugin = {
                "html:target/cucumber-html-report",
                "json:target/cucumber.json",
                "pretty:target/cucumber-pretty.txt",
                "usage:target/cucumber-usage.json",
                "junit:target/cucumber-results.xml",
        },features ={"./sample.feature"},
           glue ={"com/automation/steps"},snippets= SnippetType.CAMELCASE)

public class Runner {
}

 

Feature File :

 

Feature: This is a sample feature file

    Scenario: This is a scenario for Adding two number.
        Given Two number as 1 and 6
        When We add this two given number
        Then Result should be 7  

 

Glue Code Or Step Definition File:

 

import org.junit.Assert;
import cucumber.api.DataTable;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class SumFeatureTest {

    int input1,input2,total;
    @Given("^Two number as (\\d+) and (\\d+)$")
    public void twoNumberGivenAsAndAnotherIs(int firstInput, int secondInput) throws Throwable {
        input1 = firstInput;
        input2 = secondInput;
    }

    @When("^We add this two given number$")
    public void weAddThisTwoGivenNumber() throws Throwable {
        total = input1+input2;
    }

    @Then("^Result should be (\\d+)$")
    public void resultShouldBe(int expectedTotal) throws Throwable {
        Assert.assertEquals("Not Matched: ", expectedTotal, total);
    }
}

No comments:

Post a Comment