Sunday 27 March 2016

Cucumber BDD using Java

In this blog I will be sharing with you the BDD framework using cucumber-jvm,

Cucumber-JVM is based on cucumber's Behavior Driven Development (BDD) framework which is used to write acceptance tests for web application, in Java. It allows automation of functional validation in easily readable and understandable format called Gherkin (like plain English) to Business Analysts, Developers, Testers and other stake holders.
Here I'll give you the initial start that you needed to kick-start your cucumber framework,
I've created a simple program against which I'll create my test cases in cucumber, this will make anyone easy to get the idea behind. This may look like integration testing, but the capabilities are not limited only to this.
About the class that to be tested: its a simple class that maintains the Stock-count of mangoes, it has a single private instance variable that holds the value, and other public methods to access and manipulate the value. Below is the class.


1) MangoesCalculatorImplementation.java
  1. package com.kar.automation.javaApi;
  2. public class MangoesCalculatorImplementation {
  3. private int StockCount;

  4. public int getStockCount() {
  5. return StockCount;
  6. }
  7. public void setStockCount(int stockCount) {
  8. StockCount = stockCount;
  9. }
  10. public void addStock(int stock){
  11. StockCount+=stock;
  12. }
  13. public void removeStock(int stock){
  14. StockCount-=stock;
  15. }
  16. }

Now look at my project setup and copy the classes from here into the respective classes.

create a maven project, and create a package 'com.kar.automation.javaApi' under 'src/test/java'. put all the classes one by one under that package with the same name.

*note: usually only the test related classes are put under 'src/test/java' but as this is to learn things in the simplest way, I've put every class under one place.


2)pom.xml

Get the required libraries(Cucumber and Junit).  Use the below POM.xml definitions.paste the below definitions in your Maven pom.xml file and do a "mvn-clean-install" to get your repo updated.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.kar.cukes</groupId>
  <artifactId>1001-learn-bdd</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>MyCucumberBDD</name>
  <description>BDD</description>
  
  <dependencies>
    <dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-java</artifactId>
<version>1.2.3</version>
    </dependency>
    <dependency>
      <groupId>info.cukes</groupId>
      <artifactId>cucumber-junit</artifactId>
      <version>1.2.4</version>
      <scope>test</scope>
     </dependency>
     <dependency>
        <groupId>net.masterthought</groupId>
        <artifactId>cucumber-reporting</artifactId>
        <version>0.0.24</version>
     </dependency>
   </dependencies>
</project>

3) CalculatorTest.java
  1. package com.kar.automation.javaApi;

  2. import junit.framework.Assert;
  3. import cucumber.api.java.After;
  4. import cucumber.api.java.Before;
  5. import cucumber.api.java.en.Given;
  6. import cucumber.api.java.en.Then;
  7. import cucumber.api.java.en.When;

  8. public class CalculatorTest {

  9. MangoesCalculatorImplementation calcImpl;

  10. @Before
  11. public void preSetup(){
  12. calcImpl=new MangoesCalculatorImplementation();
  13. }

  14. @After
  15. public void postSetup(){
  16. calcImpl=null;
  17. }

  18. @Given("^I have (\\d+) mangoes in my bag$")
  19. public void i_have_mangoes_in_my_bag(int StockCount) throws Throwable {
  20.    calcImpl.setStockCount(StockCount);
  21. }

  22. @When("^I add (\\d+) more to it$")
  23. public void i_add_more_to_it(int addmangoes) throws Throwable {
  24.    calcImpl.addStock(addmangoes);
  25. }

  26. @When("^I remove (\\d+) mangoes from it$")
  27. public void i_remove_mangoes_from_it(int remMangoes) throws Throwable {
  28.    calcImpl.removeStock(remMangoes);
  29. }

  30. @SuppressWarnings("deprecation")
  31. @Then("^the mangoes count should be (\\d+)$")
  32. public void the_mangoes_count_should_be(int ExpectedCount) throws Throwable {
  33.    Assert.assertEquals(ExpectedCount, calcImpl.getStockCount());
  34. }
  35. }


there is a simple way to generate the above method definitions @When/@Given/@Then, you need to run the Test-trigger class without creating the above class, which I'll cover later **.


4) RunTest.java

  1. package com.kar.automation.javaApi;
  2. import org.junit.runner.RunWith;

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

  5. @RunWith(Cucumber.class)
  6. @CucumberOptions(format={"pretty", "html:target/cucumber"},
  7. features="src/test/resources")
  8. public class RunTest {

  9. }
** you need to run the above RunTest.class to auto generated below step definitions(you'll get the step definitions in the console output) use them by copy pasting.



5)SimpleCalculator.feature

Here I have a Feature that has two test scenarios(written in Gherkin syntax), this deals with addition and removal of mangoes from the stock. Each Given/Then/When  is linked with the corresponding method in the 'CalculatorTest.java' class. 

put this file under 'src/test/resources' package as shown in the project setup in the above image.


Feature: Mangoes stock maintenance app

  Scenario: Add and Remove mangoes-test-01
    Given I have 25 mangoes in my bag
    When I add 10 more to it
    Then the mangoes count should be 35
    When I remove 20 mangoes from it
    Then the mangoes count should be 15
    
    
  Scenario: Add and Remove mangoes-test-02
    Given I have 100 mangoes in my bag
    When I add 25 more to it
    Then the mangoes count should be 125
    When I remove 50 mangoes from it
    Then the mangoes count should be 75


Now we are all set to run the first BDD test cases using cucumber-jvm.
Run the RunTest.java class as junit test. Once the Test runs successfully, you'll get both Junit and cucumber reports.
***************************************************************************************************************************************************

Junit Report shows two scenarios and status of each step, all are green here (successful)

















 This is an additional report provided by a third-party cucumber plugin, available under target/cucumber/index.html.















*****************************************************************************************************************************************************
Read through my blog on jenkins integration and integrate this test for a nightly run.

Saturday 12 March 2016

REST API testing using RestAssured

In this post I will be sharing my knowledge on testing REST APIs using RestAssured Framework.

Background: REST APIs can be tested in many ways, like using SOAPUI, Fiddler, PostMan, Chrome client,.. etc..  but these have limitations to automate in real-time testing even though SOAPUI and Fiddler provide some support, when it comes to continuous integration and delivery model organizations move away from tools, instead they use expertise to build their automated test cases using open-source libraries, one such is RestAssured.

you can download this library from here and put that under your build-path via your IDE(Eclipse).
get your REST API method and other header information from your design documents.


package defaultPackage;
import java.util.HashMap;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
import com.jayway.restassured.RestAssured;
import com.jayway.restassured.path.json.JsonPath;
import com.jayway.restassured.response.Response;
public class TestRestAssured1 {

@Test
public void GetMyStockDetails() {

HashMap<String,String> m=new HashMap<String,String>();
m.put("Accept", "application/json");
m.put("Authorization", "appKeyToken=Framework001&appKey=0xxxxxxxxxxxx0");

           Response res = RestAssured.with().headers(m).get("http://1xx.xx.xx.xx7:8x/v1/Mystock/all/050017924/07A103");

AssertJUnit.assertEquals(200, res.getStatusCode());
String json = res.asString();
System.out.println(json);


System.out.println(res.header("X-CustomMessage"));
JsonPath jp = new JsonPath(json);

System.out.println(jp.get("[0].quantity.unitOfMeasure"));
System.out.println(jp.get("product.description"));

AssertJUnit.assertEquals("Choco", jp.get("product.description"));
AssertJUnit.assertEquals("Packet", jp.get("[0].quantity.unitOfMeasure"));
AssertJUnit.assertEquals("1", jp.get("id"));
}
}


use this code to test your REST API method, just replace the URL and the header details in the above code, Put all your headers(Authorization, Accept, content-type, Language, X-API version etc) inside the map and pass them as a single entity as above.

your json response will be available as string, use it to validate against your expected values,

The concept is same as any http client library usage, but this framework is completely developed for testing, this has enormous apis for validating many things, and also this comes with inbuilt JSON extractor using jsonpath as demoed above. 

You can integrate this with the framework which I've shared on Apache-http client, you just replace the Apache-http code with the above RestAssured code, and use parameterization for driving the tests from an excel or DB.