Pages

Tuesday, January 6, 2015

                  Cucumber with TestNg Part-1


What is Cucumber?

Cucumber is a BDD (Behaviour driven development) tool. People having misunderstanding about cucumber that it is only a testing tool.  However, it’s also used in acceptance testing, functional requirements and software documentation which must be understandable for non-technical people as a tool.


What is BDD:

 Every software/Application/system have its own behaviour or requirement as per the domain (e-Commerce, Banking, Finance etc.). The behaviour of software is documented and software team (Dev, QA and BA) will use this document to develop the software and follow a process that involves several roles in the team. This process is called BDD.


Need of Cucumber:


Cucumber was developed due to the frustration of ambiguous requirements and misunderstanding between the client and software team who deliver it. The vision behind creating cucumber was to develop a language and a process or a tool that would provide a single source of expected software behaviour.


Audience of cucumber:

The main purpose of creating cucumber was to target technical and non-technical people. The three amigos i.e. BA, Dev and QA are the audience of cucumber. Business analyst sits down with programmers and testers to discuss a feature to be implemented. The three amigos come up with examples of how the software should behave, and write it down as cucumber scenarios.

Scope of cucumber in software development life cycle:

One of the first adopters of Cucumber says it well:

“Your cucumber features should drive your implementation, not reflect it.”

The meaning of above statement is that the features of cucumber should be written before the code implementation. Cucumber features born as software requirements because most important contributors to requirements are not Programmers or Testers- they are Business Analysts. The primary responsibility of programmers and testers during this activity is to clear their doubts and make sure they understand everything.



Hands on with cucumber:

 Cucumber works with Ruby, Java, .NET, Flex or web applications written in any language. In Testing, cucumber mainly use in acceptance testing where test script written in BDD approach. As I am taking this example of java so cucumber comes with both unit testing frameworks Junit and Testng. I found people have already written more blogs on cucumber-junit. That’s where I got an idea to write a blog on cucumber with testng.

Cucumber mainly depends on three things:

1.  Feature File contains the features which are written in plain English and describe features which would cover in test script. The example of feature file is mentioned below:



Content of Feature file:

  • Feature: Feature describes current test script which is going to execute.

  • Scenario: Scenario describes the step and expected result for specific test case.

  • Tags: Tags is useful to describe specific test script that would be executed. @Search is the example of tags in above feature file.

  • Annotations:  Annotation is a manner in which a function should be executed. Commonly used annotations in cucumber are:

    • Given:  Given specifies action to initiate first step of scenarios.
    • When: When specifies the test action to be performed.
    • And: And specifies to perform multiple actions or multiple inputs.
    • Then:  Then specifies the expected outcome of the test. 
    • But: But specifies the unexpected outcome of the test.

2.    Step Definitions file is the actual implementation of how test script will execute as per given steps in feature file.

   3.  Runner File is responsible to run all step definitions mentioned in step definition file.


         First Step: To work with cucumber user have too create maven type project and use below maven dependencies in pom.xml.
<dependencies> 

 <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-java</artifactId>
       <version>2.44.0</version>
</dependency>

        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>1.1.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>1.1.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-jvm-deps</artifactId>
            <version>1.0.3</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-testng</artifactId>
            <version>1.1.5</version>
            <scope>test</scope>
        </dependency>
           
    </dependencies>




Second Step:  Write feature which we are going to test in Feature file in BDD format. Feature file extension should be “.feature” e.g. “abc.feature”. Here I am taking search functionality of BBC, it search India and will verify it. Below is sample feature file. Keep this file in "src/test/resources" project folder.

Feature: Search India on BBC website and verify search.

@Search
  Scenario: Search India on BBC website and verify it.
    Given I open the firefox browser
    And I navigating to BBc website
    Then I click at search textbox
    And I enter "India" in search textbox
    And I click at Search button
    Then I should be taken to search page
    And I verify India on search page


Third Step: Create step definitions file which will actually implement test steps of feature file. In step definition file we create one function for each step of feature file which is annotated with annotation mentioned in feature file. Each function provides definition to achieve the corresponding step. Keep below file in "src/test/java" project folder.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import cucumber.api.java.en.And;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;

public class BbcSearchStepDefs {
       public WebDriver driver = null;
       By searchTextbox = By.id("blq-search-q");
       By searchButton = By.id("blq-search-btn");
       By resultTextbox = By.cssSelector("input.search-q.ac_input");
       WebDriverWait waitVar = null;

       @Given("^I open the firefox browser$")
       public void I_open_the_firefox_browser() throws Throwable {
             driver = new FirefoxDriver();
             driver.manage().window().maximize();
             waitVar = new WebDriverWait(driver, 30);
       }

       @And("^I navigating to BBc website$")
       public void I_navigating_to_BBc_website() throws Throwable {
             driver.get("http://www.bbc.com/");
             waitVar.until(ExpectedConditions
                           .presenceOfElementLocated(searchTextbox));
       }

       @Then("^I click at search textbox$")
       public void I_click_at_search_textbox() throws Throwable {
             waitVar.until(ExpectedConditions
                           .presenceOfElementLocated(searchTextbox));
             driver.findElement(searchTextbox).click();
       }

       @And("^I enter \"([^\"]*)\" in search textbox$")
       public void I_enter_India_in_search_textbox(String search) throws Throwable {
             search = "India";
             waitVar.until(ExpectedConditions
                           .presenceOfElementLocated(searchTextbox));
             driver.findElement(searchTextbox).sendKeys(search);
       }

       @And("^I click at Search button$")
       public void I_click_at_Search_button() throws Throwable {
              waitVar.until(ExpectedConditions.presenceOfElementLocated(searchButton));
             driver.findElement(searchButton).click();
       }

       @Then("^I should be taken to search page$")
       public void I_should_be_taken_to_search_page() throws Throwable {
              waitVar.until(ExpectedConditions
                           .presenceOfElementLocated(resultTextbox));
             Assert.assertTrue(driver.getTitle().contains("Search"));

       }

       @And("^I verify India on search page$")
       public void I_verify_India_on_search_page() throws Throwable {
             waitVar.until(ExpectedConditions
                           .presenceOfElementLocated(resultTextbox));
             String expectedResult = driver.findElement(resultTextbox).getAttribute(
                           "value");
             Assert.assertEquals(expectedResult, "India");

       }
}


Fourth Step:  Create a Runner file as mentioned below. Keep below file in "src/test/java" project folder.

@CucumberOptions(features="src/test/resources")
public class RunCukesTest extends AbstractTestNGCucumberTests {
}


Features parameters contain the path where .feature file is exist. In my case it is in Src/test/resources folder.





8 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I went through this blog and found it really meaningful and simple too. This blog took away my misunderstanding about Cucumber.


    Thanks to Mr Ansari for this blog.
    I hope Part 2 will be there soon.

    ReplyDelete
  3. simple and short intro about cucumber.. great job done dude.. keep it up

    ReplyDelete
  4. Can u tell me the list of imports in Runner file?

    ReplyDelete
    Replies
    1. Hi Amit,

      Sorry for late response.

      These are the imports for Runner file.

      import cucumber.api.CucumberOptions;
      import cucumber.api.testng.AbstractTestNGCucumberTests;


      Regards,

      Muzzamil

      Delete
  5. Thanks Alot I find it very useful.

    ReplyDelete