How to use FileHandler Class to take Screenshot in Selenium WebDriver

 HOME

In the previous post, I have explained how to capture screenshots in Selenium using FileUtils. In this post, will see another way of capturing the screenshots in Selenium.

FileHandler is new Class in Selenium which help us to store screenshots, create directory and so on. You can get full documentation of FileHandler here

Step 1- Import the new package which is

import org.openqa.selenium.io.FileHandler;

Step 2 – To capture a screenshot in Selenium, we can make use of an interface, called TakesScreenshot. This method indicates the driver, that it can capture a screenshot and store it in different ways

TakesScreenshot ts = (TakesScreenshot) driver;

Step 3 – In order to capture screenshot and store it in a particular location, there is a method called “getScreenshotAs“, where OutputType defines the output type for a screenshot.

File source = ts.getScreenshotAs(OutputType.FILE);

Step 4- Call copy method of FileHandler Class which is static method and will ask two argument First is src and another is destination. Code will look like 

FileHandler.copy(source, new File("/Screenshots/SeleniumScreenshot" + System.currentTimeMillis() + ".png"));

Let’s see this in a Selenium program:-

import java.io.File;
 
import java.io.IOException; 
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.io.FileHandler;
 
public class ScreenshotExample {
      public static void main(String[] args) throws IOException {

            System.setProperty("webdriver.gecko.driver", "src\\test\\resources\\webdrivers\\window\\geckodriver.exe");
            WebDriver driver = new FirefoxDriver();

            // Maximize the window
            driver.manage().window().maximize();
            driver.get("https://configureselenium.blogspot.com/");

            // Convert web driver object to TakeScreenshot
            TakesScreenshot ts = (TakesScreenshot) driver;

            // Call getScreenshotAs method to create image file
            File source = ts.getScreenshotAs(OutputType.FILE);

            // Copy file at destination
            FileHandler.copy(source, new File("./Screenshots/SeleniumScreenshot" + System.currentTimeMillis() + ".png"));
            System.out.println("the Screenshot is taken");

            // close the current browser
            driver.quit();
      } 
 
}

A folder with name “Screenshots” created and the screenshot placed in that folder as you can see the image below

The Screenshot looks like something as shown below

How to Capture Screenshot in Selenium Webdriver

 HOME

In Automation, it is advisable to take screenshots of failed test cases for further analysis and proof of failure. Selenium provides the capability to take screenshot. But, before we see how to capture Screenshot in Selenium, we need to add a dependency in the Maven project.

Recently Selenium has done some changes in recent version so if you are using Selenium 3.6.0 then you need to add below jar to project or if you are using then you can provide below dependency in project.

https://mvnrepository.com/artifact/commons-io/commons-io

To capture a screenshot in Selenium, we can make use of an interface, called TakesScreenshot. This method indicates the driver, that it can capture a screenshot and store it in different ways

TakesScreenshot ts = (TakesScreenshot) driver;

In order to capture screenshot and store it in a particular location, there is a method called “getScreenshotAs“, where OutputType defines the output type for a screenshot.

File source = ts.getScreenshotAs(OutputType.FILE);

Copy file to Desired Location

FileUtils.copyFile(source, newFile("./Screenshots/Selenium" + System.currentTimeMillis() + ".png"));

Let’s see the complete program

import java.io.File;
 
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
 
public class ScreenshotDemo {
      public static void main(String[] args) throws IOException {
                        
          System.setProperty("webdriver.chrome.driver", "src\\test\\resources\\webdrivers\\window\\chromedriver.exe");
          WebDriver driver = new ChromeDriver();
                        
          // Maximize the window
          driver.manage().window().maximize();
          driver.get("https://configureselenium.blogspot.com/");
                        
          // Convert web driver object to TakeScreenshot
          TakesScreenshot ts = (TakesScreenshot) driver;
                        
          // Call getScreenshotAs method to create image file
           File source = ts.getScreenshotAs(OutputType.FILE);
                        
          // Copy file at destination
          FileUtils.copyFile(source, new File("./Screenshots/Selenium" + System.currentTimeMillis() + ".png"));
           System.out.println("the Screenshot is taken");
                        
          // close the current browser
          driver.quit();
     }
 
}

A folder with name Screenshots created and the screenshot is placed in that folder as you can see the image below

The Screenshot looks like something below

If you don’t want to use Maven Dependency common-io, then you can use FileHandler from

import org.openqa.selenium.io.FileHandler;
 
FileHandler.copy(source, new File("C:\\Screenshots\\Selenium" + System.currentTimeMillis() + ".png"));

How to Download & Install Java JDK 11 in Windows

HOME

The Java Development Kit(JDK) allows you to code and run Java programs. The JDK is essentially a toolkit that provides the necessary components to write, compile, and run Java programs. It includes the Java Runtime Environment (JRE), compilers, and various tools such as debuggers and documentation generators. In this tutorial, we show you how to install Java 11 on Windows and set up the environment variable JAVA_HOME

Download Java

1. Refer to the link to download JDK11. Here, I have a 64-bit system and windows operating system, so I selected –  jdk-11.0.16.1_windows-x64_bin.exe

2. Click on the name – jdk-11.0.816.1_windows-x64_bin.exe, and a dialog box as shown below will appear.

3.  If you do not have an Oracle account, then go to the AdoptOpenJDK link . AdoptOpenJDK uses infrastructure, build and test scripts to produce prebuilt binaries from OpenJDK™ class libraries and a choice of either OpenJDK or the Eclipse OpenJ9 VM. All AdoptOpenJDK binaries and scripts are open sources licensed and available free.

Select appropriate version and JVM.

Here, I have selected Version – OpenJDK 11 and JVM as HotSpot. Click on the blue download button. It will take you to the new location.

4.  Select the appropriate Operating System, Architecture, Package Type & Version. I have selected OS as Windows, Architecture as x64, Package Type as JDK, and Version as 11. Select the .zip extension and download the exe.

5. Once the file is downloaded, Right-click and extract the files to the desired location. I have placed it in C: driver under Program Files.

How to set Java JDK 11 Path in Windows 10?

1.  Type – “View Advance” in the search option and we will see the option – View Advanced system setting. 

2. In System Properties dialog, select Advanced tab and click on the Environment Variables button.

3. In “Environment variables” dialog, system variables. Click on the New button. Add a JAVA_HOME variable and specify the variable value. Mention the path where the Java folder is located.

4. Update System Path. In the “Environment Variables” window, go to “System variables.” Select Path and click Edit. Add the path of Java with bin.

To verify, if JAVA is installed properly or not, open command prompt and type

java - version

To verify, if JAVA_HOME is configured properly or not, open command prompt and type

echo %JAVA_HOME%

Data Driven Testing using Scenario Outline in Cucumber

HOME

In the previous tutorial, I explained the various types of Reports available in Cucumber. In this tutorial, I will explain how we can do Data-Driven Testing in Cucumber. Cucumber inherently supports Data-Driven testing by the use of the Scenario Outline and Examples section.  Using these keywords, Cucumber allows for easy Data-Driven testing to be complete where no changes need to be made to the Java file (StepDefinition file).

Pre-Requisite

  1. Cucumber – 6.10.4
  2. Java – 11
  3. Selenium – 3.141.59
  4. Junit – 4.13.2 ( You can use TestNG also)
  5. Cucumber JUnit – 6.10.4 (If using TestNG, then replace this with Cucumber TestNG)

The project folder structure and code should be in the below state.

In case, the project uses Maven, we need to add the below dependencies to the project.

<?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>org.example</groupId>
    <artifactId>CucumberDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <cucumber.version>6.10.4</cucumber.version>
        <selenium.version>3.141.59</selenium.version>
        <junit.version>4.13.2</junit.version>
        <maven.compiler.source.version>11</maven.compiler.source.version>
        <maven.compiler.target.version>11</maven.compiler.target.version>
    </properties>


    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>


            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${maven.compiler.source.version}</source>
                    <target>${maven.compiler.target.version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>


Below is an example of Scenarios with a different set of data (no Scenario Outline).

  @InvalidCredentials1
  Scenario: Login with invalid username and password

    Given User is on Home page
    When User enters username as "Admin1" and password as "admin1"
    Then User should be able to see an "Invalid credentials"

  @InvalidCredentials2
  Scenario: Login with blank username

    Given User is on Home page
    When User enters username as "" and password as "admin123"
    Then User should be able to see an "Username cannot be empty"

  @InvalidCredentials3
  Scenario: Login with invalid credentials

    Given User is on Home page
    When User enters username as "Admin" and password as ""
    Then User should be able to see an "Password cannot be empty"

The stepdefinition corresponding to the above feature file is

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ScenarioOutlineDefinitions {

    WebDriver driver;

    @Given("User is on Home page")
    public void userOnHomePage() {

        System.setProperty("webdriver.chrome.driver",
                "C:\\Users\\Vibha\\Software\\chromedriver_win32\\chromedriver.exe");

        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");
    }

    @When("User enters username as {string} and password as {string}")
    public void entersCredentials(String userName, String passWord) throws InterruptedException {

        System.out.println("Username Entered");
        driver.findElement(By.name("txtUsername")).sendKeys(userName);

        System.out.println("Password Entered");
        driver.findElement(By.name("txtPassword")).sendKeys(passWord);

        driver.findElement(By.id("btnLogin")).submit();

    }

    @Then("User should be able to see an {string}")
    public void verifyErrorMessage(String expectedErrorMessage) throws InterruptedException {

        String actualErrorMessage = driver.findElement(By.id("spanMessage")).getText();
        System.out.println("Error Message :" + actualErrorMessage);
        Assert.assertEquals(actualErrorMessage,expectedErrorMessage);

        //close the browser
        driver.quit();

    }
}

TestRunner Class

 Run the test by Right Click on TestRunner class and Click Run As  > JUnit Test Application.

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

@RunWith(Cucumber.class)
@CucumberOptions(monochrome = true, plugin = "pretty", features = "src/test/resources/Features/ScenarioOutline.feature",
        glue = "definitions")

public class CucumberRunnerTest {
}

Below is the output of the above program:

Data Driven Testing using Scenario Outline

Scenario Outline – It is used to repeat the same tests by passing different values or arguments to Step Definition

Examples – All scenario outlines have to be followed with the Examples section. This contains the data that has to be passed on to the scenario in Feature File.

We can repeatedly do something like the above and check for each parameter that we want to test, but that will make tests hard to maintain with many repetitions. Instead, we can use a Scenario Outline to add different inputs or arguments to the same scenario. We can re-write it like this:

Feature:  Example of Scenario Outline

  @InvalidCredentials
  Scenario Outline: Login with invalid credentials

    Given User is on Home page
    When User enters username as "<username>" and password as "<password>"
    Then User should be able to see an "<errorMessage>"

    Examples:
      | username   | password | errorMessage             |
      | Admin1     | admin1   | Invalid credentials      |
      |            | admin123 | Username cannot be empty |
      | Admin      |          | Password cannot be empty |

Note:-  The table must have a header row corresponding to the variables in the Scenario Outline steps.

The Example’s section is a table where each argument variable represents a column in the table, separated by “|”. Each line below the header represents an individual run of the test case with the respective data. As a result, if there are 2 lines below the header in the Examples table, the script will run 2 times with its respective data.

When Cucumber starts to run this program, first, it will map parameters from the data table to placeholders like, and soon in the Feature File. The corresponding StepDefinition of Feature file is mentioned above. The steps can use delimited parameters that reference headers in the examples table. The cucumber will replace these parameters with values from the table before it tries to match the step against a step definition. There is no change in the StepDefinition as mentioned in the above example.

import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class ScenarioOutlineDefinitions {

    WebDriver driver;

    @Given("User is on Home page")
    public void userOnHomePage() {

        System.setProperty("webdriver.chrome.driver",
                "C:\\Users\\Vibha\\Software\\chromedriver_win32\\chromedriver.exe");

        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.get("https://opensource-demo.orangehrmlive.com/");
    }

    @When("User enters username as {string} and password as {string}")
    public void entersCredentials(String userName, String passWord) throws InterruptedException {

        System.out.println("Username Entered");
        driver.findElement(By.name("txtUsername")).sendKeys(userName);

        System.out.println("Password Entered");
        driver.findElement(By.name("txtPassword")).sendKeys(passWord);

        driver.findElement(By.id("btnLogin")).submit();

    }

    @Then("User should be able to see an {string}")
    public void verifyErrorMessage(String expectedErrorMessage) throws InterruptedException {

        String actualErrorMessage = driver.findElement(By.id("spanMessage")).getText();
        System.out.println("Error Message :" + actualErrorMessage);
        Assert.assertEquals(actualErrorMessage,expectedErrorMessage);

        //close the browser
        driver.quit();

    }
}

TestRunner Class

 There are no changes in TestRunner class also.

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

@RunWith(Cucumber.class)
@CucumberOptions(monochrome = true, plugin = "pretty", features = "src/test/resources/Features/ScenarioOutline.feature",
        glue = "definitions")

public class CucumberRunnerTest {
}

Below is the output in Console:

Congratulations. We have seen an example of Scenario Outline. I hope this is helpful. Happy Learning!!

Cucumber Tutorial – Cucumber Reports

HOME

The previous tutorial is all about  JUnit Test Runner. In this tutorial, will show you how to generate reports in Cucumber. 

Cucumber with JUnit gives us the capability to generate reports in the form of HTML, XML, JSON & TXT. Cucumber frameworks generate very good and detailed reports, which can be share with all stakeholders. 

Let’s generate the Cucumber Report

Step 1 − Create a Maven project named MyCucumberProject in Eclipse.

Step 2 − Create a feature file named MyHoliday.feature under src/test/resources

Step 3 − Create a StepDefinition named MyHolidayDefinitions.java under src/test/java

Step 4 − Create a TestRunner class under src/test/resources

Step 5 − Run JUnit TestRunner class by right click Run As -> JUnit

Write the following code for Feature File

Feature: Book Flight and Hotel for Vacation

@BookOneWayFlight
Scenario: Book Flight for one way trip

  Given I live in Dublin with 2 adults and 2 kids
  And I want to book one way flight ticket from Dublin to London on 22nd Jan 2020
  When I search online
  Then TripAdvisor should provide me options of flights on 22nd Jan 2020
  And Cost of my flight should not be more than 50 Euro per person
  And Tickets should be refundable
 
@BookHotel
Scenario: Book Hotel for one the trip

  Given I need 1 room with 2 double beds
  And I want to book hotel from 22nd Jan 2020 to 25th Jan 2020
  When I search online
  Then TripAdvisor should provide me options of hotels for time period of 22nd Jan 2020 to 25th Jan 2020
  And Fare of my room should not be more than 200 Euro per night
  And Breakfast should be included in the room fare

Below is the full program, which shows the step definition of above mentioned feature 

import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;

public class MyHolidayDefinitions {

          @Given("^I live in Dublin with 2 adults and 2 kids$")
          public void needFlight() {
                   System.out.println("I live in Dublin with 2 adults and 2 kids");
          }

          @Given("^I need 1 room with 2 double beds$")
          public void needRoom() {
                   System.out.println("I need 1 room with 2 double beds");
          }

          @When("^I search online$")
          public void onlineSearch() {
                   System.out.println("I search online");
          }

          @Then("^TripAdvisor should provide me options of flights on 22nd Jan 2020$")
          public void searchFlightInTripAdvisor() {
                   System.out.println("TripAdvisor should provide me options of flights on 22nd Jan 2020");
          }

         @Then("^Cost of my flight should not be more than 50 Euro per person$")
          public void flightFare() {
                   System.out.println("Cost of my flight should not be more than 50 Euro per person");
          }

          @Then("^TripAdvisor should provide me options of hotels for time period of 22nd Jan 2020 to 25th Jan 2020")
          public void searchRoomInTripAdvisor() {
                   System.out.println(
                                      "TripAdvisor should provide me options of hotels for time period of 22nd Jan 2020 to 25th Jan 2020");
          }

          @And("^I want to book one way flight ticket from Dublin to London on 22nd Jan 2020$")
          public void ticketType() {
                   System.out.println("I want to book one way flight ticket from Dublin to London on 22nd Jan 2020");
          }

          @And("^I want to book hotel from 22nd Jan 2020 to 25th Jan 2020$")
          public void stayDuration() {
                   System.out.println("I want to book hotel from 22nd Jan 2020 to 25th Jan 2020");
          }

          @And("^Fare of my room should not be more than 200 Euro per night$")
          public void roomFare() {
                   System.out.println("Fare of my room should not be more than 200 Euro per night");
          }

          @And("^Breakfast should be included in the room fare$")
          public void includeBreakfast() {
                   System.out.println("Breakfast should be included in the room fare");
          }

          @And("^Tickets should be refundable$")
          public void refunableTicket() {
                   System.out.println("Tickets should be refundable");
          }
}

Cucumber HTML Reports

For HTML reports, add html:target/cucumber-reports to the @CucumberOptions plugin option.

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/Feature/MyHoliday.feature", 
plugin = { "pretty","html:target/cucumber-reports" }, tags = { "" })

public class TestRunner {
}

We have specified the path of the Cucumber report, which we want it to generate it under the target folder. This will generate an HTML report at the location mentioned in the formatter

HTML Report Output

Cucumber Json Reports

For Json reports, add json:target/cucumber-reports/Cucumber.json to the @CucumberOptions plugin option.

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/Feature/MyHoliday.feature", 
plugin = { "pretty","json:target/cucumber-reports/Cucumber.json" }, tags = { "" })

public class TestRunner {
}

JSON Report Output

Cucumber JUNIT XML Report

For JUNIT reports, add junit:targe/cucumber-reports/Cucumber.xml to the @CucumberOptions plugin option.

import org.junit.runner.RunWith;

import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(features = "src/test/resources/Feature/MyHoliday.feature", 
plugin = { "pretty","junit:target/cucumber-reports/Cucumber.xml" }, tags = { "" })

public class TestRunner { 
}

Cucumber JUnit XML Report

Constant Throughput Timer in JMeter

HOME

What is Throughput?

Throughput is calculated as requests/units of time. The time is calculated from the start of the first sample to the end of the last sample. This includes any intervals between samples, as it is supposed to represent the load on the server.

The formula is: Throughput = (number of requests) / (total time)

Suppose we want to run the load test with constant throughput in JMeter, then JMeter has a group of elements, which are called “Timers”.  And one of them has the obvious title – “Constant Throughput Timer”. That is what we need. 

What is Constant Throughput Timer?

This timer allows us to keep total throughput constant. Constant Throughput Timer is only capable of pausing JMeter threads in order to slow them down to reach the target throughput, so make sure you have enough threads in order to guarantee the desired amount of requests per second. Also, be aware that the Constant Throughput Timer is precise enough only on a minute level, so you need to properly calculate the ramp-up period and let your test run long enough. Of course, if the server is not able to handle such a load, the throughput will be lowered. Throughput may decrease if other timers contradict the Constant Throughput timer.

Constant Throughput Timer will introduce random delays between requests in such a way that a load/stress of required throughput is sent to the application.

Screenshot of Control Panel of Constant Throughput Timer

Create a Test Plan in JMeter

Step 1 –  Add Thread Group

Select Test Plan on the tree

Add Thread Group                     

To add Thread Group: Right-click on the “Test Plan” and add a new thread group: Add -> Threads (Users) -> Thread Group

In the Thread Group control panel, enter Thread Properties as follows: 

Number of Threads: 1 – Number of users connects to the target website

Loop Count: Infinite  – Number of times to execute testing

Ramp-Up Period:

Duration: 5 sec

Step 2 –  Adding JMeter elements  

The JMeter element used here is HTTP Request Sampler. In HTTP Request Control Panel, the Path field indicates which URL request you want to send

Add HTTP Request Sampler

 To add: Right-click on Thread Group and select: Add -> Sampler -> HTTP Request

Below-mentioned are the values used in HTTP Request to perform the test

Name – HTTP Request 

Server Name or IP – localhost

Port– 8010

Method– POST

Path– /demo/helloworld

Step 3 –  Add Constant Throughput Timer

To add: Right-click on Thread Group and select: Add -> Timer-> Constant Throughput Timer

Add Target Throughput: 600 (means 600 requests in 60 sec, so 10 requests per sec) Select Calculate Throughput based on – this thread only (More details about the option are present.

Step 4 – Adding Listeners to Test Plan

Listeners – They show the results of the test execution. They can show results in a different format such as a tree, table, graph, or log file

We are adding the View Result Tree listener

View Result Tree – View Result Tree shows the results of the user request in basic HTML format

To add: Right-click Test Plan, Add -> Listener -> View Result Tree

We are adding a Summary Report listener

Summary Report – The summary report creates a table row for each differently named request in your test. This is similar to the Aggregate Report, except that it uses less memory.

To add: Right-click Test Plan, Add -> Listener -> Summary Report

Step 5 – Save the Test Plan

To Save: Click File Select -> Save Test Plan as ->Give the name of the Test Plan. It will be saved as .jmx format.

Step 6  – Run the Test Plan

Click on Green Triangle as shown at the top to run the test.

Step 7 – View the Execution Status

Click on Summary Report to see the status of Run. As we can see in the summary report, 50 requests are executed as 10 requests per sec (10*5=50 requests).

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

Install Apache JMeter in Ubuntu

HOME

What is Apache JMeter?

The Apache JMeter™ application is open-source software, a 100% pure Java application designed to load test functional behaviour and measure performance. 

It can use to simulate a heavy load on a server, group of servers, network or object to test its strength or to analyze overall performance under different load types.

In this tutorial, will discuss how to install JMeter in Ubuntu. For example, I’ll use Ubuntu Desktop 18.04.

We need to install Java, before installing Apache JMeter. 

How to Install Java in Ubuntu Desktop 18.04

The command below will display the version of Java installed on the system

java --version

The command below will download Java on the system in headless mode

sudo apt-get install openjdk-11-jre-headless

How to Install Apache JMeter in Ubuntu Desktop 18.04

After Java is installed, copy the link to the archive with the latest version of Apache JMeter from the official site http://jmeter.apache.org/download_jmeter.cgi and download it:

wget http://apache.volia.net//jmeter/binaries/apache-jmeter-5.2.1.tgz

Extract the archive:

tar -xf apache-jmeter-5.2.1.tgz

How to run Apache JMeter in Ubuntu?

The command below will run the test named – PerfTest.jmx in Apache Ubuntu

./apache-jmeter-5.2.1/bin/jmeter.sh -n -t ./PerfTest.jmx

The output of JMeter Test will look like as below. 

We can see the summary of the test which include Total number of Requests processed, Total Execution Time, Throughput, Average time taken to process a request, Minimum time taken to process a request, maximum time taken to process a request and error percentage.

Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!

Additional Tutorials

 How to send POST requests in JMeter
JMeter Authorization with access token
 Install Apache JMeter in Ubuntu
Constant Throughput Timer in JMeter
How to generate Random Variables in JMeter

SpringBoot Integration Test

HOME

1. What is SpringBoot?

Spring Boot is an open-source micro framework, which provides Java developers with a platform to get started with an auto configurable production-grade Spring application. 

  • Comes with embedded HTTP servers like Tomcat or Jetty to test web applications.
  • Adds many plugins that developers can use to work with embedded and in-memory databases easily. Spring allows you to connect easily with database and queue services like Oracle, PostgreSQL, MySQL, MongoDB, Redis, Solr, ElasticSearch, Rabbit MQ and others.

2. Integration Testing of Spring Boot Application

Integration testing of SpringBoot application is all about running an application in ApplicationContext and run tests. Spring Framework does have a dedicated test module for integration testing. It known as spring-test. If we are using spring-boot, then we need to use spring-boot-starter-test, which will internally use spring-test and other dependent libraries.

With the @SpringBootTest annotation, Spring Boot provides a convenient way to start up an application context to be use in a test. In this tutorial, we will discuss when to use @SpringBootTest and how to use it. SpringBoot provides the @SpringBootTest annotation, which we can use to create an application context containing all the objects we need for the Integration Testing It, starts the embedded server, creates a web environment and then enables methods to do Integration testing.

2.1 WebEnvironment

By default, @SpringBootTest does not start the webEnvironment to refine further  how your tests run. It has several options:

1. MOCK(Default): Loads a web ApplicationContext and provides a mock web environment
2. RANDOM_PORT: Loads a WebServerApplicationContext and provides a real web environment. The embedded server is start and listen on a random port. This is the one should be used for the integration test
3. DEFINED_PORT: Loads a WebServerApplicationContext and provides a real web environment.
4. NONE: Loads an ApplicationContext by using SpringApplication but does not provide any web environment

2.2 Write integration tests with @SpringBootTest

Let’s add the Maven dependencies needed to test SpringBoot application

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
    <type>pom</type>
</dependency>
<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.springframework.security</groupId>
    <artifactId>spring-security-test</artifactId>
    <scope>test</scope>
</dependency>

2.3 What is RestController?

SpringBoot RestController annotation is use to create RESTful web services using Spring MVC. Spring RestController takes care of mapping request data to the request defined handles method. This is the Spring boot rest controller used for the testing purpose

 A convenience annotation that is itself annotated with @Controller and @ResponseBody

Get() method  returns Hello world if request sends “hello” word otherwise, response returns “Try saying ‘hello'”

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("helloworld")
public class TestController {

     @GetMapping("/{greeting}")
      public String get(@PathVariable String greeting) {

            String response;
            if(greeting.equals("hello")) {
                 response = "Hello World";
            }else{
                 response = "Try saying 'hello'";
            }
         return response;
     }
}
 2.4 Integration Test

Let’s create a Feature file with a scenario where we send request to SpringBoot Application  and get valid response.

Feature: Test SpringBoot Request

   @ReceiveCorrectResponse
   Scenario: Send a valid SpringBoot Request to get correct response
    Given I send a springboot request to the URL "/helloworld/hello"
    Then the springboot response will return "Hello World"

The test class mentioned below contains integration tests for the spring boot rest controller mentioned above. This test class:

  • uses @SpringBootTest annotation which loads the actual application context.
  • uses WebEnvironment.RANDOM_PORT to create run the application at some random server port.
  • @LocalServerPort gets the reference of port where the server has started. It helps in building the actual request URIs to mimic real client interactions.
  • io.restassured.RestAssured is a Java DSL for simplifying testing of REST based services built on top of HTTP Builder
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SpringIntegrationTest {

       private final static String BASE_URI = "http://localhost";

       @LocalServerPort
       private int port;

       String endpoint = "/helloworld/hello";
       private ValidatableResponse validatableResponse;

       private void configureRestAssured() {
              RestAssured.baseURI = BASE_URI;
              RestAssured.port = port;
              RestAssured.basePath = "/demo";         
       }
       protected RequestSpecification getAnonymousRequest() throws NoSuchAlgorithmException
     {
              configureRestAssured();
              return given();
       }

       @Given("^I send a springboot request to the URL \"([^\"]*)\"$")
       public void iSendARequest(String endpoint) throws Throwable 
      {
              validatableResponse = getAnonymousRequest().contentType(ContentType.JSON).when().get(endpoint).then();
       }

      @Then("^the springboot response will return \"([^\"]*)\"$")
      public void extractResponse(String message) 
    {        validatableResponse.assertThat().statusCode(HttpStatus.OK.value()).body(containsString(message));
       }     
}
2.5 Demo

Run the above tests within Eclipse. The test class start the whole application in embedded server and the execute the test

The next tutorial is about the Integration Testing of SpringBoot Application using Serenity BDD and Cucumber

How to send GET Request in JMeter

HOME

What is Apache JMeter?

The Apache JMeter™ application is open source software, a 100% pure Java application designed to load test functional behavior and measure performance. It was design for testing Web Applications but has since expanded to other test functions.
It can used to simulate a heavy load on a server, group of servers, network or object to test its strength or to analyze overall performance under different load types.

How to send GET HTTP Request in JMeter?

We can perform GET as well as POST operation in JMeter. In this tutorial, we will only explain how we can perform GET operation.

Create a Test Plan in JMeter

Step 1 – Add Thread Group

  • Select Test Plan on the tree
  • Add Thread Group                                                                                           
    • To add Thread Group: Right click on the “Test Plan” and add a new thread group: Add -> Threads (Users) -> Thread Group

In the Thread Group control panel, enter Thread Properties as follows: We will take an example of row no 5.

  • Number of Threads: 5 – Number of users connects to the target website
  • Loop Count: 5  – Number of time to execute testing
  • Ramp-Up Period: 5 – It tells JMeter how long to delay before starting the next user. For example, if we have 5 users and a 5 -second Ramp-Up period, then the delay between starting users would be 1 second (5 seconds /5 users).

Step 2 –  Adding JMeter elements

The JMeter element used here is HTTP Request Sampler. In HTTP Request Control Panel, the Path field indicates which URL request you want to send.

2.1 Add HTTP Request Sampler

To add: Right-click on Thread Group and select: Add -> Sampler -> HTTP Request.

Below mentioned are the values use in HTTP Request to perform the test

  • Name – HTTP Request 
  • Server Name or IP – localhost
  • Port – 8010
  • Method – GET
  • Path – /demo/helloworld/demo

OR

URL – https://reqres.in/api/users?page=2

  • Name – HTTP GET Request 
  • Protocol – https
  • Server Name or IP – reqres.in
  • Port –
  • Method – GET
  • Path – /api/users?page=2

Step 3 – Adding Listeners to Test Plan

Listeners – They shows the results of the test execution. They can show results in a different format such as a tree, table, graph or log file

We are adding  View Result Tree listener

View Result Tree – View Result Tree show results of the user request in basic HTML format

To add: Right click Test Plan, Add -> Listener -> View Result Tree

Complete Test Plan will look like as shown below

Step 4 – Save the Test Plan

To Save: Click File Select -> Save Test Plan as ->Give name of the Test Plan. It will be save as .jmx format.

Sample .jmx File

Step 5  – Run the Test Plan

Click on Green Triangle as shown below to run the test.

Step 6 – View the Execution Status

Click on View Result Tree to see the status of Run. Successful request will be of Green color in the Text Section.

Sample of Failed Request. Failed request will be of Red color in View Result Tree under Text option. This screen sows the reason for the failure of the request like Connection refused here.

That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

runAsync and supplyAsync in ComputableFuture in Java8

This tutorial is to explain the functionality of ComputableFuture class introduced as Java 8 Concurrency API improvement.

ComputableFuture class implements the Future interface; means can be use for future implementation but with additional logic. 
Static methods runAsync and supplyAsync allow us to create a ComputableFuture instance out of Runnable and Supplier functional types accordingly.

runAsync  – Returns a new CompletableFuture that is asynchronously completed by a task running in the ForkJoinPool.commonPool() after it runs the given action. It returns the new CompletableFuture.

CompletableFuture<Void> java.util.concurrent.CompletableFuture.runAsync(Runnable runnable)

ComputableFuture.runAsync accepts Runnable functional interface and return a ComputableFuture which doesn’t have value

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.junit.Test; 
 
 public class runAsyncDemo {
     @Test
      public void runAsync() throws InterruptedException, ExecutionException {
           CompletableFuture future = CompletableFuture.runAsync(() -> System.out.println("runAsync method doesn not return any value"));
           System.out.println(future.get());
   }
}

Output
runAsync method does not return any value
null