Showing posts with label JUnit. Show all posts
Showing posts with label JUnit. Show all posts

Saturday, February 29, 2020

Spring Boot + Cucumber + Selenium

In this post I will demonstrate how to configure Spring Boot application in to Behavioral testing with Cucumber using selenium.


Prerequisites 
  1. You should have install java 1.8 or above.
  2. You should have Eclipse installed in your PC.
  3. Your PC should setup Maven installed and configured.


Lets create project 

Create maven project with following dependencies. I have highlighted the selenium and cucumber dependencies.


<?xml version="1.0" encoding="UTF-8"?>
<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.nirmal.springbootcucumber</groupId>
<artifactId>bdd_cucumber</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<name>bdd_cucumber</name>
<description>BDD tests with Cucumber, Selenium and Spring Boot</description>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
<relativePath />
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-server</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-spring</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>info.cukes</groupId>
<artifactId>cucumber-junit</artifactId>
<version>1.2.5</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
</plugins>
</build>
</project>


For maven installation purposes I will add Spring Boot initializer class as show in below. 


package com.nirmal.springbootcucumber;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AppRunner {

public static void main(String[] args) {
SpringApplication.run(AppRunner.class, args);
}
}


Now application and perform maven install command.



Configure cucumber on Tests 

First we have to add test initializer class which do initialization part of test framework. I have created the package com.nirmal.springbootcucumber under test folder.


package com.nirmal.springbootcucumber;

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

@RunWith(Cucumber.class)
@CucumberOptions(features="Features",glue="com.nirmal.springbootcucumber.StepDefinition"})
public class Runner
{

}

Note that in here I user two annotations which have following responibilites

@RunWith(Cucumber.class)
This will specifies this class need consider as test runner. Also we have provided cucumber as parameter, which says this should run as cucumber test


@CucumberOptions(features="Features",glue="com.nirmal.springbootcucumber.StepDefinition"})
This annotation provide basic configuration details related to cucumber
The first parameter, called features, provides the location of the feature file. Similarly, the second parameter, called glue, provides the path of the step definition class.




Create feature file and define cucumber steps on Tests 


Lets create new folder call "Feature" under our project folder and put the feature file that I'm going to demonstrate in this post.



Feature: Google page loading and Searching

Scenario: Google page loading and Searching

Given Open the Firefox and launch the application

When Click on clickable item "//*[@id='tsf']/div[2]/div[1]/div[1]/div/div[2]/input"

Then Enter the value on "//*[@id='tsf']/div[2]/div[1]/div[1]/div/div[2]/input" as "Beautiful Sri Lanka" and press enter

Then click on item with xpath "//*[@id='gb']/div/div[1]/a"

Then Enter the value on "//*[@id='identifierId']" as "validemailid" and press enter

Then Enter the value on "//*[@id='password']/div[1]/div/div[1]/input" as "test" and press enter

Then go back to previous URL

Then go back to previous URL

Then click on item with xpath "//*[@id='logo']/img"


Then lets download the chrome driver for this example. You can latest web driver from following URL. Then extract in to you local folder. I will extracted in in to "C:\driver\chromedriver_win32"

Then lets create the steps for this feature file. For that I'll create new class class com.nirmal.springbootcucumber.StepDefinition.Steps under the test.

package com.nirmal.springbootcucumber.StepDefinition;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.concurrent.TimeUnit;

public class Steps {

    WebDriver driver;
   
    @Given("^Open the Firefox and launch the application$")
    public void open_the_Firefox_and_launch_the_application() throws Throwable
    {
 System.setProperty("webdriver.chrome.driver", "C:\\driver\\chromedriver_win32\\chromedriver.exe");
       driver= new ChromeDriver();

       driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
       
       driver.manage().window().maximize();
       driver.get("http://www.google.com/");
    }
    
    @When("^click on item with selector \\\"([^\\\"]*)\\\"")
    public void  click_on_item_with_selector(String selector) throws Throwable
    {
       driver.findElement(By.cssSelector(selector)).click();;
    }

    @When("^click on item with xpath \\\"([^\\\"]*)\\\"")
    public void  click_on_item_with_xpath(String xpathExpression) throws Throwable
    {
       driver.findElement(By.xpath(xpathExpression)).click();
    }
    
    @Then("^go back to previous URL")
    public void go_back_to_previous_URL() throws Throwable {
    driver.navigate().back();
    }


    @When("^div vivible and clickable with xpath \\\"([^\\\"]*)\\\"")
    public void  div_vivible_and_clickable(String xpathExpression) throws Throwable
    {
       driver.findElement(By.xpath(xpathExpression)).isDisplayed();
       driver.findElement(By.xpath(xpathExpression)).isEnabled();
    }



    @Then("^Enter the value on \"([^\"]*)\" as \"([^\"]*)\" and press enter")
    public void enter_the_value_on_and_pressenterFor(String xpathExpression, String value) throws Throwable
    {
        driver.findElement(By.xpath(xpathExpression)).sendKeys(value);
        driver.findElement(By.xpath(xpathExpression)).sendKeys(Keys.ENTER);
    }


    @When("^Click on clickable item \\\"([^\\\"]*)\\\"")
    public void Click_on_clickable_item(String xpathExpression) throws Throwable
    {
        driver.findElement(By.xpath(xpathExpression)).click();
    }

}


Make sure to configure your chrome driver path (Which you have downloaded in previous step) in open_the_Firefox_and_launch_the_application method as show in above class.


Lets run cucumber Test 

Then double click on run debug configuration button as show in below figure

click on run debug configuration button

Then double click on JUnit under then select the main test class as "com.nirmal.springbootcucumber.Runner" then click ok.



Then you can run the configuration buy click on run button



Then selenium will load the Chrome instance in your local PC and follow the instruction we have given in the feature file. After successful test run you should be able to see similar output as below.

Test result after Successful execution of feature steps 


You can access the updated code base from following GitHub URL.

You ca

Friday, December 14, 2018

Spring boot REST API test with JUnit

In my previous blog post I have created Spring Boot REST API for simple CRUD operation demonstration. In this post I'm demonstrating how to use  JUnit testings in the REST API.

Prerequisites 
  1. You should have install java 1.8 or above.
  2. You should have Eclipse installed in your PC.
  3. Your PC should setup Maven installed and configured.
  4. You should have REST API developed for testing I'm using REST api which I developed on previous post. (You can checkout previous code from here)



Spring Boot dependency 

First of all lets add the dependency in to POM file related to the JUnit test. All required dependencies comes under the spring-boot-starter-test. Just need to add following part on the existing pom file.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>


Test Class creation

Lets create "TestRestAPI" under the src/test/java folder.

In the class level we need to have following annotations

@RunWith(SpringJUnit4ClassRunner.class)
Indicates that the class should use Spring's JUnit facilities

@SpringBootTest(classes = AppInitializer.class) 
Specify the springboot initializing class

@WebAppConfiguration
It’s used to denote that the ApplicationContext which is bootstrapped for the test should be an instance of WebApplicationContext.


Then we have @Before method with following content. This will initialize our MockMvc variable using application context.

        @Before
public void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}


Whole TestRestAPI class implementation can be see on following github location.

In that Test class I have added following methods in order to test deferent scenarios in the application.

bookEqualsMethodTest
This method will test whether our equals method on Book model class work as expected.

searchNonExistingBook
This method will test whether correct out put return when searching not existence book searched on the system.

saveBookWithoutMandotoryFieldIsbn
This method will test whether correct output return when ISBN number empty or null when saving Book.

saveBookWithoutMandotoryFieldName
This method will test whether correct output return when book name empty or null when saving Book.

saveBookWithoutCorrectBookDetails
This method will test whether correct output return when correct book saved on the system.


saveBookWithoutCorrectBookDetailsAndDeleteWithNullIsbm
This method will test the expected output when try to perform delete operation with null ISBM number.

saveBookWithoutCorrectBookDetailsAndDelete
This method will test the expected output when try to perform delete operation with correct ISBM number.


In order to run the JUnit Test you can right click on the "TestRestAPI" and click on Run As -> JUnit Test as show on bellow.


Then on the result can be seen on the JUnit section.



Also there is another feature where we can see the code coverage of the unit test. In order to see the code coverage we have to run unit test with code coverage. In order to run it you can go to Run menu bar and click on coverage.




Then on the coverage area you can see the Unit Test coverage and also if you click on specific class on the coverage area you can see the areas which has not been tested on the unit test. As show on bellow figure.



You can download whole project with JUnit test in following git hub location.