DataProvider in TestNG using Excel

HOME

In the previous tutorial, I have explained the DataProvider in TestNG without using Excel. In this tutorial, I will explain the use of Excel in DataProvider for TestNG.

I have created an excel – SearchInBing.xlsx and placed on Desktop. You can create a TestData folder in your project and place the excel file within it. So, my datasheet looks like below-

Next, we will create a DataProvider method that will use another method to read the excel file & create a 2D object from the row & column values of the excel and return the same value, so that our test script can use it. The code for it would look like below-

@DataProvider(name = "excelData")
	public Object[][] excelDataProvider() throws IOException {
		// We are creating an object from the excel sheet data by calling a method that
		// reads data from the excel stored locally in our system
		Object[][] arrObj = getExcelData(
				"C:\\Users\\Vibha\\Desktop\\SearchInBing.xlsx",
				"Details");
		return arrObj;
	}

	// This method handles the excel - opens it and reads the data from the
	// respective cells using a for-loop & returns it in the form of a string array
	public String[][] getExcelData(String fileName, String sheetName) throws IOException {
		String[][] data = null;
		try {
			
			FileInputStream fis = new FileInputStream(fileName);
			XSSFWorkbook workbook = new XSSFWorkbook(fis);
			XSSFSheet sheet = workbook.getSheet(sheetName);
			XSSFRow row = sheet.getRow(0);
			int noOfRows = sheet.getPhysicalNumberOfRows();
			int noOfCols = row.getLastCellNum();
			Cell cell;
			data = new String[noOfRows - 1][noOfCols];

			for (int i = 1; i < noOfRows; i++) {
				for (int j = 0; j < noOfCols; j++) {
					row = sheet.getRow(i);
					cell = row.getCell(j);
					data[i - 1][j] = cell.getStringCellValue();
				}
			}
		} catch (Exception e) {
			System.out.println("The exception is: " + e.getMessage());
		}
		return data;
	}

Now, create a class which contains the test code. By default, the data provider will be looked for in the current test class or one of its base classes. If you want to put your data provider in a different class, it needs to be a static method or a class with a non-arg constructor, and you specify the class where it can be found in the dataProviderClass attribute.

public class DataProviderWithExcelDemo {

	WebDriver driver;

	@BeforeMethod
	public void setUp() {
		System.out.println("Start test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver_win32_93.0.4577.15\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com");
		driver.manage().window().maximize();

	}

	@Test(dataProvider = "excelData", dataProviderClass = ExcelDataProvider.class)
	public void search(String keyWord1, String keyWord2) {

		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord1, " ", keyWord2);
		System.out.println("Keyword entered is : " + keyWord1 + " " + keyWord2);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search results are displayed.");
	}

	@AfterMethod
	public void burnDown() {
		driver.quit();
	}

}

To run the code, right click and Select – TestNG Test.

The Execution status will look like as shown below

This test execution generate reports under test-output folder.

We are concerned about two reports – index.html and emailable-report.html.

Below is the image of emailable-report.html.

Below is the image of index.html.

See how easy it is to read data from excel and use in the Test Code using DataProvider.

I hope you have enjoyed this tutorial. Happy Learning!!

DataProviders in TestNG

HOME

In the last tutorial, I have explain the Parameters in TestNG which passes different test data to the test case as arguments. Similar to TestNG Parameters, DataProviders are a means to pass data to test scripts in TestNG. In this tutorial, I will explain about the DataProviders in TestNG.

What is DataProvider in TestNG?

The DataProvider in TestNG is another way to pass the parameters in the test function, the other one being TestNG parameters. Using DataProvider in TestNG, we can easily inject multiple values into the same test case. It comes inbuilt in TestNG and is popularly used in data-driven frameworks.

Syntax of DataProvider

@DataProvider (name = "name_of_dataprovider")
public Object[][] dpMethod() {
    return new Object [][] { values}
}
  •  A Data Provider is a method on the class that returns an array of array of objects.  This method is annotated with @DataProvider
  • A @Test method specifies its Data Provider with the dataProvider attribute. This name must correspond to a method on the same class annotated with @DataProvider(name=”…”) with a matching name.
  • TestNG dataprovider returns a 2d list of objects..An array of array of objects (Object[][]) where the first dimension’s size is the number of times the test method will be invoked and the second dimension size contains an array of objects that must be compatible with the parameter types of the test method.
  • DataProviders are not declared on top of the functions like TestNG parameters but have a method of their own, which in regular speaking terms called a dataprovider method. For example, dpMethod here.
  • The dataprovider name calls the dataprovider method, and if there is no name specified by the tester, then the dataprovider method is the default name used in the receiving @Test case.
  • Data providers can run in parallel with the attribute parallel.

Below is the basic example of using DataProvider in TestNG.

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class DataProviderDemo {

	WebDriver driver;

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { { "Selenium" }, { "TestNG" } };
	}

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData")
	public void search(String keyWord) {
		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord);
		System.out.println("Keyword entered is : " + keyWord);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

	@AfterMethod
	public void burnDown() {
		driver.quit();

		System.out.println("End the test");
	}

}

In the above example, I am passing two search keywords, viz “Selenium” and “TestNG” to the test method using the DataProvider method. You can run the code and check the output. It will be as shown below-

Here, Test is executed with two values, but we have run the test only once.

Inheriting DataProvider in TestNG

It is messy to have supporting methods like DataProvider and test code in one class. It is always preferred to declare the test case in one class and define TestNG parameters like DataProviders in another class. By default, the data provider will be looked for in the current test class or one of its base classes. If you want to put your data provider in a different class, it needs to be a static method or a class with a non-arg constructor, and you specify the class where it can be found in the dataProviderClass attribute.

Let us create separate classes for the DataProvider method and the test method, as shown below:

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { 
          { "Selenium" }, { "TestNG" }, { "Automation" } };
	}
}

We can see that all we did was create a DataProvider method in a Class and create a new class for Test Code.

public class DataProviderInheritanceDemo {

	WebDriver driver;

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
	public void search(String keyWord) {
		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord);
		System.out.println("Keyword entered is : " + keyWord);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

	@AfterMethod
	public void burnDown() {
		driver.quit();

		System.out.println("End the test");
	}

}

As you can see, to handle the inheritance, all we did was add an attribute to the test method (highlighted above), which specifies the class that has the DataProvider method. 

Passing Multiple Parameter Values in TestNG DataProviders

Passing multiple values is pretty similar to passing numerous parameters. The only difference is that we will pass various values to a single parameter so that a string of input(s) is sent in one go.

Let us quickly understand this concept with the help of the code as shown below.

DataProvider Class

public class DPDemo {

	@DataProvider(name = "testData")
	public Object[][] dataProvFunc() {
		return new Object[][] { { "Automation Tester", "2-5 years" }, { "Performance Tester", "3+ years" },
				{ "DevOps", "5+ years" } };
	}
}

Test Code – DataProviderInheritanceDemo

public class DataProviderInheritanceDemo {

	WebDriver driver;

	@BeforeMethod
	public void setUp() {

		System.out.println("Start the test");
		System.setProperty("webdriver.chrome.driver",
				"C:\\Users\\Vibha\\Software\\chromedriver\\chromedriver.exe");
		driver = new ChromeDriver();
		driver.get("https://www.bing.com/");
		driver.manage().window().maximize();

	}

	// Passing the dataProvider to the test method through @Test annotation
	@Test(dataProvider = "testData", dataProviderClass = DPDemo.class)
	public void search(String keyWord1, String keyWord2) {

		WebElement txtBox = driver.findElement(By.id("sb_form_q"));
		txtBox.sendKeys(keyWord1, keyWord2);
		System.out.println("Keyword entered is : " + keyWord1 + " " + keyWord2);
		txtBox.sendKeys(Keys.ENTER);
		System.out.println("Search result is displayed.");
	}

	@AfterMethod
	public void burnDown() {
		driver.quit();

		System.out.println("End the test");
	}
}

Run the test script, and you will see both the values for the TestNG parameters being passed in one go, the output for it would be as follows-

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Integration of Allure Report with Rest Assured and TestNG

HOME

In the previous tutorial, I have explained the Integration of the Allure Report with Rest Assured with JUnit4 . In this tutorial, I will explain how to Integrate Allure Report with Rest Assured and TestNG.

Below example covers the implementation of Allure Report for Rest API using Rest Assured ,TestNG, Java and Maven.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Java 11
  2. Maven – 3.8.1
  3. Allure Report – 2.14.0
  4. Rest Assured – 4.4.0
  5. Allure Rest Assured – 2.14.0
  6. Allure TestNG – 2.14.0
  7. Aspectj – 1.9.6

Implementation Steps

  1. Update Properties section in Maven pom.xml
  2. Add Rest Assured, Allure-Rest Assured and Allure-TetNG dependencies in POM.xml
  3. Update Build Section of pom.xml in Allure Report Project.
  4. Create the Test Code for the testing of REST API under src/test/java
  5. Create TestNG.xml for the project
  6. Run the Tests and Generate Allure Report

Step 1 – Update Properties section in Maven pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <rest-assured.version>4.4.0</rest-assured.version>
    <allure.testng.version>2.14.0</allure.testng.version>
    <allure.rest-assured.version>2.14.0</allure.rest-assured.version>
    <jackson.version>2.12.3</jackson.version>
    <json.version>20210307</json.version>
    <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <aspectj.version>1.9.6</aspectj.version>
    <maven-surefire-plugin-version>3.0.0-M5</maven-surefire-plugin-version>
  </properties>

Step 2 – Add the Allure-Rest Assured dependency

 <!--Allure Reporting Dependency-->   
   <dependency>
      <groupId>io.qameta.allure</groupId>
      <artifactId>allure-rest-assured</artifactId>
      <version>${allure.rest-assured.version}</version>
   </dependency>

Add other dependencies like Rest Assured and Allure-TetNG dependencies in POM.xml

<dependencies>

     <!-- Allure TestNG Dependency -->
     <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-testng</artifactId>
        <version>${allure.testng.version}</version>
        <scope>test</scope>
    </dependency>
    
   <!-- Rest Assured Dependency -->
    <dependency>
       <groupId>io.rest-assured</groupId>
       <artifactId>rest-assured</artifactId>
       <version>${rest-assured.version}</version>
       <scope>test</scope>
    </dependency>

    <!-- Jackson Dependency -->
    <dependency>
       <groupId>com.fasterxml.jackson.core</groupId>
       <artifactId>jackson-databind</artifactId>
       <version>${jackson.version}</version>
    </dependency>

    <!-- JSON Dependency -->
    <dependency>
       <groupId>org.json</groupId>
       <artifactId>json</artifactId>
       <version>${json.version}</version>
    </dependency>  
    
  </dependencies>

Step 3 – Update Build Section of pom.xml in Allure Report Project

 <build>
   <plugins>
         <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
               <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source> <!--For JAVA 8 use 1.8-->
                    <target>${maven.compiler.target}</target> <!--For JAVA 8 use 1.8-->
                </configuration>
            </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven-surefire-plugin-version}</version>
           <configuration>
                    <suiteXmlFiles>
                        <suiteXmlFile>TestNG.xml</suiteXmlFile>
                    </suiteXmlFiles>
                 <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                 </argLine>
             </configuration>          
             <dependencies>
             
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
      </plugins>
  </build>

Step 4 – Create the Test Code for the testing of REST API under src/test/java

To see our request and response more detailed using Rest Assured we need to add a line to our Rest Assured tests.This will provide the request and response details in the report.

 .filter(new AllureRestAssured())
@Epic("REST API Regression Testing using TestNG")
@Feature("Verify CRUID Operations on Employee module")
public class EmployeeDetailsTest {

	String BaseURL = "http://dummy.restapiexample.com/api";

	@Test(description = "GET Request Operation")
	@Story("GET Request with Valid User")
	@Severity(SeverityLevel.NORMAL)
	@Description("Test Description : Verify the details of employee of id-2")
	public void verifyUser() {

		// GIVEN
		given()
               .filter(new AllureRestAssured())

		// WHEN
		.when()
               .get(BaseURL + "/v1/employee/2")
				
        // THEN
		  .then()
                .statusCode(200)
                .statusLine("HTTP/1.1 200 OK")
				
                 // To verify booking id at index 2
				.body("data.employee_name", equalTo("Garrett Winters"))
				.body("message", equalTo("Successfully! Record has been fetched."));
	}

	@Test(description = "GET Request Operation")
	@Story("GET Request with Invalid User")
	@Severity(SeverityLevel.NORMAL)
	@Description("Test Description : Verify the details of employee of id-99999")
	public void verifyInvalidUser() {

		// Given
		given()
              .filter(new AllureRestAssured())

		// WHEN
		.when()
              .get(BaseURL + "/v1/employee/99999")
				
        // THEN
		.then()
               .statusCode(200)
               .statusLine("HTTP/1.1 200 OK")
			   .body("message", equalTo("Successfully! Record has not been fetched."));
	}

	@Test(description = "POST Request Operation")
	@Story("POST Request")
	@Severity(SeverityLevel.NORMAL)
	@Description("Test Description : Verify the creation of a new employee")
	public void createUser() {

		JSONObject data = new JSONObject();

		data.put("employee_name", "APITest");
		data.put("employee_salary", "99999");
		data.put("employee_age", "30");

        //GIVEN 
		given()
              .filter(new AllureRestAssured())
              .contentType(ContentType.JSON)
              .body(data.toString())

	    // WHEN
		.when()
               .post(BaseURL + "/v1/create")

		// THEN
		.then()
               .statusCode(200)
               .body("data.employee_name", equalTo("APITest"))
			   .body("message", equalTo("Successfully! Record has been added."));

	}

}

Step 5 – Create testng.xml for the project

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="5" name="Test">
    <classes>
      <class name="com.example.RestAssuredTestNGAllureReport.EmployeeDetailsTest"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Step 6 – Run the Test and Generate Allure Report

To run the tests, use the below command

mvn clean test

In the below image, we can see that two tesst are failed and one passed out of three tests.

This will create allure-results folder with all the test report. These files will be use to generate Allure Report.

To create Allure Report, use the below command

allure serve

This will generate the beautiful Allure Test Report as shown below.

Allure Report Dashboard

Overview page hosts several default widgets representing basic characteristics of your project and test environment.

Categories in Allure Report

Categories tab gives you the way to create custom defects classification to apply for test results. There are two categories of defects – Product Defects (failed tests) and Test Defects (broken tests).

Suites in Allure Report

On the Suites tab a standard structural representation of executed tests, grouped by suites and classes can be found.

View test history

Each time you run the report from the command line with the mvn clean test command, new result json file will get added in the allure-results folder. Allure can use those files to include a historical view of your tests. Let’s give that a try.

To get started run mvn clean test a few time and watch how the number of file in the allure-reports folder grows.

Now go back to view your report. Select Suites from the left nav, select one of your tests, and cick Retries in the right pane. You should see history of test runs for that test:

Graphs in Allure Report

Graphs allow you to see different statistics collected from the test data: statuses breakdown or severity and duration diagrams.

Timeline in Allure Report

Timeline tab visualizes retrospective of tests execution, allure adaptors collect precise timings of tests, and here on this tab they are arranged accordingly to their sequential or parallel timing structure.

Behaviors of Allure Report

This tab groups test results according to Epic, Feature and Story tags.

Packages in Allure Report

Packages tab represents a tree-like layout of test results, grouped by different packages.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Allure Report with Cucumber5 and TestNG

HOME

In the previous tutorial, I have explained the Integration of the Allure Report with Selenium and TestNG. In this tutorial, I will explain how to Integrate Allure Report with Cucumber5 and TestNG.

Below example covers the implementation of Allure Reports with Cucumber5, Selenium, TestNG, Java and Maven.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Selenium – 3.141.59
  2. Java 11
  3. Cucumber 5 – 5.7.0
  4. Maven – 3.8.1
  5. Allure Report – 2.14.0
  6. Allure Cucumber5 – 2.14.0
  7. Aspectj – 1.9.6

Implementation Steps

  1. Update Properties section in Maven pom.xml
  2. Add Cucumber5, Selenium, TestNG and Allure Cucumber5 dependencies in POM.xml
  3. Update Build Section of pom.xml in Allure Report Project.
  4. Create source folder – src/test/resources and features folder within src/test/resources to create test scenarios in Feature file
  5. Create the Step Definition class or Glue Code
  6. Create a Cucumber Runner class
  7. Run the Test and Generate Allure Report

Step 1 – Update Properties section in Maven pom.xml

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <selenium.version>3.141.59</selenium.version>
    <cucumber.version>5.7.0</cucumber.version>
    <testng.version>7.4.0</testng.version>
    <allure.cucumber5.version>2.14.0</allure.cucumber5.version>
    <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
    <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <aspectj.version>1.9.6</aspectj.version>
    <allure.maven.version>2.10.0</allure.maven.version>
  </properties>

Step 2 – Add Cucumber5, Selenium, TestNG, Allure-Cucumber5 and Allure-TestNG dependencies in POM.xml

<dependencies>
  <!--Cucumber Dependencies-->  
    <dependency>
       <groupId>io.cucumber</groupId>
       <artifactId>cucumber-java</artifactId>
       <version>${cucumber.version}</version>
    </dependency>
 
  <!--Selenium Dependency-->
    <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-java</artifactId>
       <version>${selenium.version}</version>
    </dependency>
  <!--Cucumber TestNG Dependency-->
    <dependency>
       <groupId>io.cucumber</groupId>
       <artifactId>cucumber-testng</artifactId>
       <version>${cucumber.version}</version>
        <scope>test</scope>
    </dependency>
  <!--Hamcrest Dependency-->
    <dependency>
       <groupId>org.hamcrest</groupId>
       <artifactId>hamcrest</artifactId>
       <version>2.2</version>
       <scope>test</scope>
    </dependency>
    
  <!--Allure Cucumber Dependency-->   
      <dependency>
         <groupId>io.qameta.allure</groupId>
         <artifactId>allure-cucumber5-jvm</artifactId>
         <version>${allure.cucumber5.version}</version>
    </dependency>  
</dependencies>

Step 3 – Update Build Section of pom.xml in Allure Report Project

<build>
    <plugins>   
      <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source> 
                    <target>${maven.compiler.target}</target> 
                </configuration>
            </plugin>
     
     <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
             <version>${maven.surefire.plugin.version}</version>
            <configuration>
                 <suiteXmlFiles>
                        <suiteXmlFile>TestNG.xml</suiteXmlFile>
                    </suiteXmlFiles>
                <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                    -Dcucumber.options="--plugin io.qameta.allure.cucumber5jvm.AllureCucumber5Jvm"
                </argLine>
                        
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
        
         <plugin>
                <groupId>io.qameta.allure</groupId>
                <artifactId>allure-maven</artifactId>
                <version>${allure.maven.version}</version>
                <configuration>
                    <reportVersion>${allure.version}</reportVersion>
                </configuration>
            </plugin>
      </plugins>      
   </build>

Step 4 – Create source folder – src/test/resources and features folder within src/test/resources to create test scenarios in Feature file

Feature file should be saved as an extension of .feature. Add the test scenarios in this feature file. I have added sample test scenarios. In this feature file. The test scnerios are written in Gherkins language.

@LoginPage @TestNG
@severity=blocker
Feature: Feature - Login to HRM Application 
 
   @ValidCredentials
   Scenario: Scenario - Login with valid credentials 
     
    Given User is on Home page
    When User enters username as "Admin"
    And User enters password as "admin123"
    Then User should be able to login sucessfully
    
   @InvalidCredentials
   Scenario Outline: Scenario -Login with invalid credentials
   
    Given User is on Home page
    When User enters username as "<username>"
    And User enters password as "<password>"
    Then Error message "<message>" should be displayed
    
    Examples:
    |username  |password  |message                         |
    |admin     |admin     |Invalid credentials             |
    |          |admin123  |Username can be empty           | 
    |Admin     |          |Password can be empty           |
    |          |          |Username cannot be empty        |

Step 5 – Create the Step Definition class or Glue Code

CommonDefinitions.java

package com.example.CucumberAllureReportDemo.definitions;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
public class CommonDefinitions {
	protected static WebDriver driver;
	@Before
	public void setup() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	}
	@After
	public void tearDown(Scenario scenario) {
		try {
			String screenshotName = scenario.getName().replaceAll("", "_");
			if (scenario.isFailed()) {
				TakesScreenshot ts = (TakesScreenshot) driver;
				byte[] screenshot = ts.getScreenshotAs(OutputType.BYTES);
				scenario.attach(screenshot, "img/png", screenshotName);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		driver.quit();
	}
}

LoginPageDefinition.java

public class LoginDefinition {
	@Given("User is on Home page")
	public void userOnHomePage() {
		CommonDefinitions.driver.get("https://opensource-demo.orangehrmlive.com/");
	}
	@When("User enters username as {string}")
	public void entersUsername(String userName) throws InterruptedException {
		System.out.println("Username Entered");
		CommonDefinitions.driver.findElement(By.name("txtUsername")).sendKeys(userName);
	}
	@When("User enters password as {string}")
	public void entersPassword(String passWord) throws InterruptedException {
		System.out.println("Password Entered");
		CommonDefinitions.driver.findElement(By.name("txtPassword")).sendKeys(passWord);
		CommonDefinitions.driver.findElement(By.id("btnLogin")).submit();
	}
	@Then("User should be able to login sucessfully")
	public void sucessfulLogin() throws InterruptedException {
		String newPageText = CommonDefinitions.driver.findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		assertThat(newPageText, containsString("Welcome"));
	}
	@Then("Error message {string} should be displayed")
	public void unsucessfulLogin(String message) throws InterruptedException {
		String errorMessage = CommonDefinitions.driver.findElement(By.id("spanMessage")).getText();
		System.out.println("Error Message :" + errorMessage);
		Assert.assertEquals(errorMessage, message);
	}
}

Step 6 – Create a Cucumber Runner class

We need to create a class called Runner class to run the tests. This class will use the JUnit annotation @RunWith(), which tells JUnit what is the test runner class.

import org.testng.annotations.Test;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
@Test
@CucumberOptions(plugin = { "pretty }, tags = "", features = "src/test/resources/features/Login.feature", glue = "com.example.CucumberAllureReportDemo.definitions")
public class CucumberRunnerTests extends AbstractTestNGCucumberTests {
}

Note:- @Test annotation marks this class as part of the test. So, if we will remove this annotation, the Allure Report execute CucumberRunnerTests as a seperate test suite, so there will be duplicate results.

Step 7 – Create testng.xml for the project

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "Suite1">
  <test name = "Test Demo">
    <classes>
          <class name = "com.example.CucumberAllureReportDemo.runner.CucumberRunnerTests"/>
     </classes>  
   </test>
</suite>

Step 8 – Run the Test and Generate Allure Report

To run the tests, use the below command

mvn clean test

In the below image, we can see that two tests are failed and three passed out of five tests.

This will create allure-results folder with all the test report. These files will be use to generate Allure Report.

Use the below comand to generate the Allure Report

allure serve

This will generate the beautiful Allure Test Report as shown below.

Allure Report Dashboard

Categories in Allure Report

Categories tab gives you the way to create custom defects classification to apply for test results. There are two categories of defects – Product Defects (failed tests) and Test Defects (broken tests).

Suites in Allure Report

On the Suites tab a standard structural representation of executed tests, grouped by suites and classes can be found. Here, we have 2 suits – Feature and Surefire test. Surefire test are executed from CucumberRunnerTests.

Graphs in Allure Report

Graphs allow you to see different statistics collected from the test data: statuses breakdown or severity and duration diagrams.

Timeline in Allure Report

Timeline tab visualizes retrospective of tests execution, allure adaptors collect precise timings of tests, and here on this tab they are arranged accordingly to their sequential or parallel timing structure.

Behaviors of Allure Report

This tab groups test results according to Epic, Feature and Story tags.

Packages in Allure Report

Packages tab represents a tree-like layout of test results, grouped by different packages.

When we don’t use @Test in CucumberRunnerTests.java, then as mentioned above the Allure report will have duplicate details as shown below:-

Integration of Allure Report with Selenium and TestNG

HOME

In this tutorial, I will explain how to integrate Allure Report (one of the very famous Report) with Selenium and TestNG.

What is Allure Framework?

Allure is an open-source framework designed to create interactive and comprehensive test report by Yandex QA Team.

Below example covers the implementation of Allure Reports in Selenium using TestNG, Java and Maven.

Pre-Requisite

  1. Java 11 installed
  2. Maven installed
  3. Eclipse or IntelliJ installed

This framework consists of:

  1. Selenium – 3.141.59
  2. Java 11
  3. TestNG – 7.4.0
  4. Maven – 3.8.1
  5. Allure Report – 2.14.0
  6. Allure TestNG – 2.14.0

Implementation Steps

  1. Update Properties section in Maven pom.xml
  2. Add Selenium, TestNG and Allure TestNG dependencies in POM.xml
  3. Update Build Section of pom.xml in Allure Report Project.
  4. Create Pages and Test Code for the pages
  5. Create testng.xml for the project
  6. Run the Test and Generate Allure Report

Step 1 – Update Properties section

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <selenium.version>3.141.59</selenium.version>
    <testng.version>7.4.0</testng.version>
    <allure.testng.version>2.14.0</allure.testng.version>
    <maven.compiler.plugin.version>3.5.1</maven.compiler.plugin.version>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <aspectj.version>1.9.6</aspectj.version>
    <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
  </properties>

Step 2 – Add Selenium, TestNG and Allure TestNG dependencies in POM.xml

<dependencies>
    
     <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
    <dependency>
        <groupId>io.qameta.allure</groupId>
        <artifactId>allure-testng</artifactId>
        <version>${allure.testng.version}</version>
        <scope>test</scope>
    </dependency>
  </dependencies>

Step 3 – Update Build Section of pom.xml in Allure Report Project

<build>
       
       <plugins>
   <!-- Compiler plug-in -->
  
           <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source> <!--For JAVA 8 use 1.8-->
                    <target>${maven.compiler.target}</target> <!--For JAVA 8 use 1.8-->
                </configuration>
            </plugin>
            
     <!-- Added Surefire Plugin configuration to execute tests -->       
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-surefire-plugin</artifactId>
              <version>${maven.surefire.plugin.version}</version>
              <configuration>
                    <suiteXmlFiles>
                        <suiteXmlFile>TestNG.xml</suiteXmlFile>
                    </suiteXmlFiles>
                 <argLine>
                    -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
                 </argLine>
             </configuration>          
             <dependencies>
            
            <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjweaver</artifactId>
                    <version>${aspectj.version}</version>
                </dependency>
            </dependencies>
        </plugin>
      </plugins>
  </build>

Step 4 – Create Pages and Test Code for the pages

Below is the sample project which uses Selenium and TestNG which is used to generate an Allure Report.

We have 2 pages. Below is the code for Login Page which contains all the web elements and methods related to that web elements.

LoginPage.java

public class LoginPage {

	WebDriver driver;

	By userName = By.name("txtUsername");

	By password = By.name("txtPassword");

	By titleText = By.id("logInPanelHeading");

	By login = By.id("btnLogin");

	By errorMessage = By.id("spanMessage");

	public LoginPage(WebDriver driver) {
		this.driver = driver;
	}

	// Set user name in textbox
	public void setUserName(String strUserName) {
		driver.findElement(userName).sendKeys(strUserName);
	}

	// Set password in password textbox
	public void setPassword(String strPassword) {
		driver.findElement(password).sendKeys(strPassword);
	}

	// Click on login button
	public void clickLogin() {
		driver.findElement(login).click();
	}

	@Step("Verify title of Login Page")
	public void verifyPageTitle() {
		String loginPageTitle = driver.findElement(titleText).getText();
		Assert.assertTrue(loginPageTitle.contains("LOGIN Panel"));
	}

    /* Failed Test */
	@Step("Verify error message when invalid credentail is provided")
	public void verifyErrorMessage() {
		String invalidCredentialErrorMessage = driver.findElement(errorMessage).getText();
		Assert.assertTrue(invalidCredentialErrorMessage.contains("Incorrect Credentials"));
	}

	@Step("Enter username and password")
	public void login(String strUserName, String strPasword) {

		// Fill user name
		this.setUserName(strUserName);

		// Fill password
		this.setPassword(strPasword);

		// Click Login button
		this.clickLogin();

	}
}

Dashboard.java

public class DashboardPage {

	WebDriver driver;

	By dashboardPageTitle = By.id("welcome");

	By options = By.cssSelector(
			"#dashboard-quick-launch-panel-menu_holder > table > tbody > tr > td:nth-child(1) > div > a > span");

	public DashboardPage(WebDriver driver) {
		this.driver = driver;

	}

	@Step("Verify title of Dashboard page")
	public void verifyDashboardPageTitle() {
		String DashboardPageTitle = driver.findElement(dashboardPageTitle).getText();
		Assert.assertTrue(DashboardPageTitle.contains("Welcome"));
	}

	@Step("Verify Quick Launch Options on Dashboard page")
	public void verifyQuickLaunchOptions() {
		String QuickLaunchOptions = driver.findElement(options).getText();
		Assert.assertTrue(QuickLaunchOptions.contains("Assign Leave"));
	}

}

Below are the Test clases for Login Page and Dasboard Page. Here, we have BaseTest Class also which contains the common methods needed by other test pages.

BaseTest.java

public class BaseTest {

	public static WebDriver driver;
	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Step("Start the application")
	@BeforeMethod
	public void setup() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@Step("Stop the application")
	@AfterMethod
	public void close() {
		driver.close();
	}
}

LoginTests.java

@Epic("Web Application Regression Testing")
@Feature("Login Page Tests")
@Listeners(TestExecutionListener.class)
public class LoginTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Severity(SeverityLevel.NORMAL)
	@Test(priority = 0, description = "Verify Login Page")
	@Description("Test Description : Verify the title of Login Page")
	@Story("Title of Login Page")
	public void verifyLoginPage() {

		// Create Login Page object
		objLogin = new LoginPage(driver);

		// Verify login page text
		objLogin.verifyPageTitle();
	}

   /* Failed Test */
	@Severity(SeverityLevel.BLOCKER)
	@Test(priority = 1, description = "Login with invalid username and password")
	@Description("Test Description : Login Test with invalid credentials")
	@Story("Unsuccessful Login to Application")
	public void invalidCredentialTest() {

		// Create Login Page object
		objLogin = new LoginPage(driver);
		objLogin.login("test", "test123");

		// Verify login page text
		objLogin.verifyErrorMessage();

	}

}

We can order tests by severity by using @Severity annotation. Click here to know more about other Allure annotations.

DashboardTests.java

@Epic("Web Application Regression Testing")
@Feature("Dashboard Page Tests")
@Listeners(TestExecutionListener.class)
public class DashboardTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Severity(SeverityLevel.BLOCKER)
	@Test(priority = 0, description = "Verify Dashboard Page")
	@Description("Test Description : After successful login to application opens Dashboard page")
	@Story("Successful login of application opens Dashboard Page")

	public void DasboardTest() {

		objLogin = new LoginPage(driver);

		// login to application
		objLogin.login("Admin", "admin123");

		// go the dashboard page
		objDashboardPage = new DashboardPage(driver);

		// Verify dashboard page
		objDashboardPage.verifyQuickLaunchOptions();

	}

}

We can group tests with @Epic@Feature, and @Stories annotations. Click here to know more about other Allure annotations.

TestExecutionListener.class

We can add attachments to our reports by using @Attachment annotation. It can return String, byte [], etc.  I need to add @Listeners({ TestExecutionListener.class }) declaration at the top of the test classes. Click here to know more about other Allure annotations.

public class TestExecutionListener implements ITestListener {

	@Attachment(value = "Screenshot of {0}", type = "image/png")
	public byte[] saveScreenshot(String name, WebDriver driver) {
		return (byte[]) ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
	}

	@Override
	public void onTestFailure(ITestResult result) {
		saveScreenshot(result.getName(), BaseTest.driver);
	}

}

Step 5 – Create testng.xml for the project

TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name = "Allure Reports">
  <test name = "Login Page Tests">
    <classes>
          <class name = "com.example.TestNGAllureReportDemo.tests.LoginTests"/>
         
          </classes>
          </test> 
    <test name =" Dashboard Tests">   
    <classes> 
          <class name = "com.example.TestNGAllureReportDemo.tests.DashboardTests"/>
          </classes>
    </test>

</suite>

Step 6 – Run the Test and Generate Allure Report

To run the tests, use the below command

mvn clean test

In the below image, we can see that one test is failed and two passed out of three tests.

To create Allure Report, use the below command

allure serve

This will generate the beautiful Allure Test Report as shown below.

Allure Report Dashboard

Overview page hosts several default widgets representing basic characteristics of your project and test environment.

  1. Statistics – overall report statistics.
  2. Launches – if this report represents several test launches, statistics per launch will be shown here.
  3. Behaviors – information on results aggregated according to stories and features.
  4. Executors – information on test executors that were used to run the tests.
  5. History Trend – if tests accumulated some historical data, it’s trend will be calculated and shown on the graph.
  6. Environment – information on test environment.

Categories in Allure Report

Categories tab gives you the way to create custom defects classification to apply for test results. There are two categories of defects – Product Defects (failed tests) and Test Defects (broken tests).

Suites in Allure Report

On the Suites tab a standard structural representation of executed tests, grouped by suites and classes can be found.

Graphs in Allure Report

Graphs allow you to see different statistics collected from the test data: statuses breakdown or severity and duration diagrams.

Timeline in Allure Report

Timeline tab visualizes retrospective of tests execution, allure adaptors collect precise timings of tests, and here on this tab they are arranged accordingly to their sequential or parallel timing structure.

Behaviors of Allure Report

This tab groups test results according to Epic, Feature and Story tags.

Packages in Allure Report

Packages tab represents a tree-like layout of test results, grouped by different packages.

If you click on the i (hihlighted tab), it will show the test exection report in the below format.

How to create and run TestNG.xml of a TestNG class

HOME

There are 2 ways to run TestNG tests – using Run As TestNG tests and from testng.xml.

In this tutorial, I’m explaining how to create and run tests using TestNG.xml.

Step 1 – In the below project, there is no testng.xml present.

Step 2 – Right click on class name “API_Test.java” and navigate “TestNG–>Convert to TestNG“.

Step 3 – Now a new window for testng.xml will be generated as shown below. Click the Finish Button.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="5" name="Test">
    <classes>
      <class name="com.example.RestAssured_TestNG_Demo.API_Test"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Step 4 – A xml file named “testng.xml” will be generated in project hierarchy.

Step 5 – Right click on this testng.xml and select Run As–> Testng Suite

Step 6 – You will view the result in two different tabs: Console and “Results of running suite”. Below is the image of Rest of running suite tab.

Multiple Classes

Let us imagine a sceanrio where there are 3 classes and we want to run them all together, you can done that by creating a testng.xm and mention all 3 classes in that testng.xml.

Select all 3 classes and right click and navigate “TestNG–>Convert to TestNG

This is how the testng.xml will look like for multiple classes.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test thread-count="5" name="Test">
    <classes>
      <class name="com.example.RestAssured_TestNG_Demo.API_Test1"/>
      <class name="com.example.RestAssured_TestNG_Demo.Test3"/>
      <class name="com.example.RestAssured_TestNG_Demo.Test2"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Right click on this testng.xml and select Run As–> Testng Suite.  You will get the result in two tabs: Console and “Results of running suite”. Rhis shows that all the tests present withing the three classes are executed.

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

Page Object Model without Page Factory in Selenium Webdriver

HOME

What is Page Object Model?

Page Object Model(POM) is an object design pattern in Selenium webdriver which tells how to organize the object repository. In this case, we refer to web elements as Objects. Page Object Model(POM) is not a Test Framework.

In the Page Object Model (POM), each web page is represented as a separate class. For example, consider HRM website. It has many web pages like Login , Dashboard , Assign Leave, Leave List, Timesheets, etc. Under this model, for each web page in the application, there should be a corresponding Page Class. This Page class will identify the WebElements of that web page and also contains Page methods that perform operations on those WebElements.

If a new web element is added or an existing web element is updated, then you can add or update that web element in object repository by navigating to class which has same name as webpage.

The object repository is independent of test cases, so we can use the same object repository for a different purpose with different tools. For example, we can integrate Page Object Model in Selenium with TestNG/JUnit for functional Testing and at the same time with JBehave/Cucumber for acceptance testing.

POM enhances test maintenance, readability and reducing code duplication.

In this tutorial, I’m creating a project using Page Object Model as Design Pattern and TestNG as the Test Automation Framework.

Steps to create a Page Object Model Project

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Add dependencies to pom.xml
  6. Create Page Class for each page – LoginPage.Java and DashboardPage.java
  7. Create tests for each Page – BaseTests, LoginTests and DashboardTests
  8. Create a TestNG.XML
  9. Run the tests from TestNG.xml
  10. TestNG Report Generation

Step 1- Download and Install Java

Click here to know How to install Java. To check if Java is already installed on your machine, use the below command in the command line. This command will show the version of Java installed on your machine.

java -version

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer. The Eclipse IDE for Java Developers distribution is designed to support standard Java development. It includes support for the Maven and Gradle build system and support for the Git version control system. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

To know if Maven is already installed or not on your machine, type this command in the command line. This command will show the version of Maven installed on your machine.

mvn -version

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – pageobjectmodel_demo
Version – 0.0.1-SNAPSHOT
Package – com. example.pageobjectmodel_demo

Step 5 – Add dependencies to the pom.xml

I have added Selenium and TestNG dependencies.

<dependencies>
  
   <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>   
    
</dependencies>

Step 6 – Create Page Class for each page – LoginPage.Java and DashboardPage.java

I want to test 2 pages – Login and Dashboard. So, I’m creating 2 seperate class. Each class will contain its web elements and methods of that page.

LoginPage.Java

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {

	WebDriver driver;

	By userName = By.name("txtUsername");

	By password = By.name("txtPassword");

	By titleText = By.id("logInPanelHeading");

	By login = By.id("btnLogin");

	public LoginPage(WebDriver driver) {
		this.driver = driver;
	}

	// Set user name in textbox
	public void setUserName(String strUserName) {
		driver.findElement(userName).sendKeys(strUserName);
	}

	// Set password in password textbox
	public void setPassword(String strPassword) {
		driver.findElement(password).sendKeys(strPassword);
	}

	// Click on login button
	public void clickLogin() {
		driver.findElement(login).click();
	}

	// Get the title of Login Page
	public String getLoginTitle() {
		return driver.findElement(titleText).getText();
	}

	public void login(String strUserName, String strPasword) {

		// Fill user name
		this.setUserName(strUserName);

		// Fill password
		this.setPassword(strPasword);

		// Click Login button
		this.clickLogin();
	}
}

DashboardPage.java

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class DashboardPage {

	WebDriver driver;

	By homePageUserName = By.id("welcome");

	public DashboardPage(WebDriver driver) {
		this.driver = driver;

	}

	// Get the User name from Home Page
	public String getHomePageText() {
		return driver.findElement(homePageUserName).getText();
	}

}

Step 7 – Create tests for each Page – BaseTests, LoginTests and DashboardTests

Here, I have created 3 classes. BaseTest class to contain startUp and tearDown methods. These methods will run once before the after of every class. LoginTests and DashboardTests classes contain the tests related to LoginPage and DashboardPage respectively.

BaseTest

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class BaseTest {

	public static WebDriver driver;
	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@BeforeClass
	public void setup() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");
		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@AfterClass
	public void close() {
		driver.close();
	}
}

LoginTests

import org.testng.Assert;
import org.testng.annotations.Test;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class LoginTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Test(priority = 0)
	public void loginTest() {

		// Create Login Page object
		objLogin = new LoginPage(driver);

		// Verify login page text
		String loginPageTitle = objLogin.getLoginTitle();
		Assert.assertTrue(loginPageTitle.contains("LOGIN Panel"));
	}

}

DashboardTests

import org.testng.Assert;
import org.testng.annotations.Test;

import com.example.pageobjectmodel_demo.pages.DashboardPage;
import com.example.pageobjectmodel_demo.pages.LoginPage;

public class DashboardTests extends BaseTest {

	LoginPage objLogin;
	DashboardPage objDashboardPage;

	@Test(priority = 0)
	public void DasboardTest() {

		objLogin = new LoginPage(driver);

		// login to application
		objLogin.login("Admin", "admin123");

		// go the dashboard page
		objDashboardPage = new DashboardPage(driver);

		// Verify dashboard page
		Assert.assertTrue(objDashboardPage.getHomePageText().contains("Welcome"));
	}

}

Step 8 – Create a TestNG.XML

Here, I have mentioned 2 test classes. So, when I will run the tests from TestNG.xml, it will run the tests of both the classes. If will mention any one class, then the test of that particular class will be executed.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "PageObjectModel">
  <test name = "PageObjectModel Tests">
    <classes>
          <class name = "com.example.pageobjectmodel_demo.tests.LoginTests"/>
          <class name = "com.example.pageobjectmodel_demo.tests.DashboardTests"/>
     </classes>  
   </test>
</suite>

Step 9 – Run the tests from TestNG.xml

Right click on TestNG.xml and select Run As TestNG Suite.

The execution status looks like as shown below.

Step 10 – TestNG Report Generation

Once the execution is finished, refresh the project. It will create a test-output folder containing various reports generated by TestNG. Below is the screenshot of the report folder.

Image of Index.html report

Image of emailable-report.html

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

Parallel Testing in Cucumber with TestNG

HOME

In this tutorial, I will explain Parallel Testing using Cucumber with TestNG.

Cucumber-JVM allows parallel execution across multiple threads since version 4.0.0. There are several options to incorporate this built-in feature in a Cucumber project. You can do so by using JUnit, TestNG or CLI.

Cucumber can be executed in parallel using TestNG and Maven test execution plugins by setting the dataprovider parallel option to true.

In TestNG the scenarios and rows in a scenario outline are executed in multiple threads. One can use either Maven Surefire or Failsafe plugin for executing the runners. In this tutorial, I’m using the Maven Surefire plugin.

Pre-Requisite

  1. Java is installed
  2. Maven is installed
  3. TestNG is installed

This framework consists of:

  1. Selenium – 3.141.59
  2. Java 11
  3. Cucumber Java – 6.8.1
  4. Cucumber TestNG- 6.8.1
  5. Maven – 3.8.1
  6. TestNG – 7.4.0
  7. Maven Surefire Plugin – 3.0.0-M5

Steps to create a project for parallel Testing in Cucumber

  1. Create a Maven project.
  2. Update Properties section in Maven pom.xml
  3. Add Cucumber and TestNG dependencies to the project.
  4. Add Surefire plugin configuration to the build section to the POM.
  5. Create 2 feature files under src/test/resources – Login.feature and HomePage.feature.
  6. Create the Step Definition classes for both feature files or Glue Code.
  7. Create a Cucumber TestNG Runner class.
  8. Report Generation
  9. Execute the test from Command Line.
  10. Execute the test from TestNG Runner.
  11. Difference between parallel and non parallel tests

Detailed Step Description

Step 1 – Create a Maven project

Create a Maven project in your favorite IDE using the cucumber-archetype. To know more about this, click here.

Step 2 – Update Properties section in Maven pom.xml

<properties>
   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   <selenium.version>3.141.59</selenium.version> 
   <cucumber.version>6.8.1</cucumber.version>
   <testng.version>7.4.0</testng.version>
   <maven.surefire.plugin.version>3.0.0-M5</maven.surefire.plugin.version>
 </properties>

Step 3 – Add Cucumber, Selenium and TestNG dependencies to the project

Add below mentioned Cucumber-Java and Cucumber-TestNG and Selenium-java dependencies to the project.

<dependencies>

    <!--Cucumber Dependencies -->
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-java</artifactId>
      <version>${cucumber.version}</version>
    </dependency>
  
    <dependency>
      <groupId>io.cucumber</groupId>
      <artifactId>cucumber-testng</artifactId>
      <version>${cucumber.version}</version>
      <scope>test</scope>
     </dependency>
  
    <!-- Selenium Dependency -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>${selenium.version}</version>
    </dependency>

    <!-- TestNG Dependency -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>${testng.version}</version>
      <scope>test</scope>
    </dependency>  

</dependencies>
  

Step 4 – Add Surefire plugin configuration to the build section to the POM

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${maven.surefire.plugin.version}</version>
</plugin>

Step 5 – Create 2 feature files under src/test/resources – Login.feature and HomePage.feature

Below are the sample feature files.

Login.feature

Feature: Login to HRM Application 
 
   @ValidCredentials
   Scenario: Login with valid credentials - Feature 1, Scenario -1
     
    Given User is on Home page
    When User enters username as "Admin"
    And User enters password as "admin123"
    Then User should be able to login sucessfully

HomePage.feature

Feature: Home page validation
 
Background:
   Given User Navigates to HRM login page
   And User login with valid credentials

   @ValidQuickLaunch
   Scenario Outline: Login with valid credentials to check QuickLanuch options  - Feature 2, Scenario -1
    
   When User is in Dashboard page
	 Then there are valid QuickLaunch options '<options>'
	  	
	Examples: 
		|options                  |
		|Assign Leave             |
		|Leave List               |

	
	@ValidLegendOptions		
	Scenario Outline: Login with valid credentials to check Manu Options - Feature 2, Scenario -2
    
   When User is in Dashboard page
	 Then there are valid Legend options '<legendOptions>'
	  	
	Examples: 
		|legendOptions               |
		|Administration              |

Step 6 – Create the Step Definition classes for both feature files or Glue Code.

Below is the Step Definition for Login.feature.

public class LoginDefinition {

	WebDriver driver;

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

		System.out.println("Thread ID - " + Thread.currentThread().getId());
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		driver = new FirefoxDriver();

		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@When("User enters username as {string}")
	public void entersUsername(String userName) throws InterruptedException {

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

	}

	@When("User enters password as {string}")
	public void entersPassword(String passWord) throws InterruptedException {

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

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

	@Then("User should be able to login sucessfully")
	public void sucessfullLogin() throws InterruptedException {

		String newPageText = driver.findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		assertThat(newPageText, containsString("Welcome"));

		driver.quit();

	}

Below is the Step Definition for HomePage.feature.

public class HomePageDefinitions {

	WebDriver driver;

	@Given("User Navigates to HRM login page")
	public void userOnHomePage() {

		System.out.println("Thread ID - " + Thread.currentThread().getId());
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		driver = new FirefoxDriver();
		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
		driver.get("https://opensource-demo.orangehrmlive.com/");
	}

	@And("User login with valid credentials")
	public void entersCredentials() throws InterruptedException {
		Thread.sleep(1000);

		driver.findElement(By.name("txtUsername")).sendKeys("Admin");
		driver.findElement(By.name("txtPassword")).sendKeys("admin123");
		driver.findElement(By.id("btnLogin")).submit();

	}

	@When("User is in Dashboard page")
	public void verifyDashboardPage() {

		String dashboardTitle = driver.findElement(By.id("welcome")).getText();
		assertThat(dashboardTitle, containsString("Welcome"));

	}

	@Then("there are valid QuickLaunch options {string}")
	public void verifyQuickLinks(String options) throws InterruptedException {

		switch (options) {
		case "Assign Leave":
			String linkOne = driver
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[1]/div/a/span"))
					.getText();
			Assert.assertEquals(linkOne, options);
			Thread.sleep(1000);
			break;
		case "Leave List ":
			String linkTwo = driver
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[2]/div/a/span"))
					.getText();
			Assert.assertEquals(linkTwo, options);
			Thread.sleep(1000);
			break;
		case "Timesheets":
			String linkThree = driver
					.findElement(By.xpath(
							"//*[@id='dashboard-quick-launch-panel-menu_holder']/table/tbody/tr/td[3]/div/a/span"))
					.getText();
			Assert.assertEquals(linkThree, options);
			Thread.sleep(1000);
			break;
		default:
			break;
		}

		driver.quit();

	}

	@Then("there are valid Legend options {string}")
	public void verifyMenuOptions(String options) throws InterruptedException {

		switch (options) {
		case "Not assigned to Subunits":
			String linkOne = driver
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[1]/td[2]"))
					.getText();
			Assert.assertEquals(linkOne, options);
			Thread.sleep(1000);
			break;
		case "Administration":
			String linkTwo = driver
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[2]/td[2]"))
					.getText();
			Assert.assertEquals(linkTwo, options);
			Thread.sleep(1000);
			break;
		case "Client Services":
			String linkThree = driver
					.findElement(
							By.xpath("//*[@id='div_legend_pim_employee_distribution_legend']/table/tbody/tr[3]/td[2]"))
					.getText();
			Assert.assertEquals(linkThree, options);
			Thread.sleep(1000);
			break;
		default:
			break;

		}
		driver.quit();
	}
}

Step 7 – Create a Cucumber TestNG Runner class

Add a cucumber runner by extending the AbstractTestNGCucumberTests class and overriding the scenarios method. Set the parallel option value to true for the DataProvider annotation.

import org.testng.annotations.DataProvider;

import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;

@CucumberOptions(tags = "", features = "src/test/resources/features", glue = "com.example.Cucumber_TestNGDemo.definitions")

public class CucumberRunnerTests extends AbstractTestNGCucumberTests {

	@Override
	@DataProvider(parallel = true)
	public Object[][] scenarios() {
		return super.scenarios();
	}

}

Step 8 – Report Generation

Add cucumber.properties under src/test/resources and add the below instruction in the file.

cucumber.publish.enabled=true

Step 9 – Execute the test from Command Line

Use the below mentioned command in command prompt to run the tests.

mvn test

Step 10 – Execute the tests from TestNG Runner

Go to Runner class and right click Run As TestNG Test. The tests will run as TestNG tests.

Step 11 – Difference between parallel and non parallel tests

Parallel Tests – All the tests are started at the same time, so they share different threads. The way tests are executed are different in them. With non-paralle tests, all the scenarios of the same feature are executed together and then he scenarios of another feature file. Whereas, in parallel test, all the tests are started at the same time, so there won’t be any specific order.

All the scenarios and rows of the scenario outlines are executed in different threads.

Non Parallel Tests

Parallel Test Report – The execution time to complete the tests are less in parallel test execution as compared to the non parallel one.

Non Parallel Tests Report

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

There is another tutorial which shows Parallel Testing in Cucumber with JUnit.

Integration of REST Assured with TestNG

HOME

As we know, REST Assured is a Java DSL for simplifying testing of REST based services built on top of HTTP Builder. In this tutorial, I’ll create a Test Framework for the testing of REST API using REST Assured and TestNG as test framework. This framework consists of:-

  1. REST Assured – 4.3.3
  2. Java 8 or above
  3. TestNG – 7.4.0
  4. Maven – 3.8.1

Steps to setup Rest API Test Automation Framework with REST Assured and TestNG

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Add REST Assured and TestNG dependencies to the project
  6. Create a TEST file under src/test/java to write the test code.
  7. Run the tests as TestNG Tests
  8. Run the tests from TestNG.xml
  9. TestNG Report Generation

Detailed Step Description

Step 1- Download and Install Java

Java needs to be present on the system to run the tests. Click here to know How to install Java. To know if Java is installed or not on your machine, type this command in the command line. This command will show the version of Java installed on your machine.

java -version

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

To know if Maven is already installed or not on your machine, type this command in the command line. This command will show the version of Maven installed on your machine.

mvn -version

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – RestAssured_TestNG_Demo
Version – 0.0.1-SNAPSHOT
Package – com. example.RestAssured_TestNG_Demo

Step 5 – Add REST Assured and TestNG dependencies to the project

Add below mentioned REST Assured and TestNG dependencies to the project.

<dependencies>
 <!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
   <dependency>
     <groupId>io.rest-assured</groupId>
     <artifactId>rest-assured</artifactId>
     <version>4.3.3</version>
     <scope>test</scope>
    </dependency>
</dependencies>

To create a JSONObject body for the request, we need to add below dependencies to the Test Framework.

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.12.3</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20210307</version>
</dependency> 

Step 6 – Create a TEST file under src/test/java to write the test code.

To know how to create a JSON Request body using JSONObject, please refer this tutorial.

To know more about priority in TestNG, please refer this tutorial.

public class API_Test {

	@Test(description = "To get the details of employee with id 2", priority = 0)
	public void verifyUser() {

		// Given
		given()
		
        // When
		.when()
              .get("http://dummy.restapiexample.com/api/v1/employee/2")
				
         // Then
		 .then()
                .statusCode(200)
                .statusLine("HTTP/1.1 200 OK")
				// To verify booking id at index 3
				.body("data.employee_name", equalTo("Garrett Winters"))
				.body("message", equalTo("Successfully! Record has been fetched."));
	}

	@Test(description = "To create a new employee", priority = 1)
	public void createUser() {

		JSONObject data = new JSONObject();

		data.put("employee_name", "APITest");
		data.put("employee_salary", "99999");
		data.put("employee_age", "30");

		
		// GIVEN
		given()
               .baseUri("http://dummy.restapiexample.com/api")
               .contentType(ContentType.JSON)
               .body(data.toString())

		// WHEN
		.when()
               .post("/v1/create")

		// THEN
		.then()
               .statusCode(200)
               .body("data.employee_name", equalTo("APITest"))
			   .body("message", equalTo("Successfully! Record has been added."));

	}

}

Step 7 – Test Execution through TestNG

Go to Runner class and right click Run As TestNG Test. The tests will run as TestNG tests.

This is how the execution console will look like.

Step 8 – Run the tests from TestNG.xml

Create a TestNG.xml as shown below and run the tests as TestNG. Here, the tests are present in class – com.example.Selenium_TestNGDemo.API_Test.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "Suite1">
  <test name = "Test Demo">
    <classes>
          <class name = "com.example.Selenium_TestNGDemo.API_Test"/>
     </classes>  
   </test>
</suite>

Step 9 – TestNG Report Generation

After test execution, refresh the project, a new folder with name test-output will be generated. This folder contains the reports generated by TestNG. The structure of folder test-output looks like as shown below.

We are interested in ’emailable-report.html’ report. Open ’emailable-report.html’, as this is a html report open it with browser. Below image shows emailable-report.html.

TestNG also produce “index.html” report and it resides under test-output folder. Below image shows index.html report. This report contains the high level summary of the tests.

We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!

Integration of Selenium with TestNG

HOME

In this tutorial, I’ll create a Framework for the testing of web applications using Selenium Webdriver with TestNG . This framework consists of:-

  1. Selenium
  2. Java 8 or above
  3. TestNG
  4. Maven

Steps to setup Cucumber Test Automation Framework with Selenium and TestNG

  1. Download and Install Java on system
  2. Download and setup Eclipse IDE on system
  3. Setup Maven
  4. Create a new Maven Project
  5. Add Selenium and TestNG dependencies to the project
  6. Create a Test file under src/test/java
  7. Run the tests from TestNG.xml
  8. TestNG Report Generation

Detailed Step Description

Step 1- Download and Install Java

Cucumber and Selenium needs Java to be installed on the system to run the tests. Click here to know How to install Java.

Step 2 – Download and setup Eclipse IDE on system

The Eclipse IDE (integrated development environment) provides strong support for Java developer which is needed to write Java code. Click here to know How to install Eclipse.

Step 3 – Setup Maven

To build a test framework, we need to add a number of dependencies to the project. It is very tedious and cumbersome process to add each dependency manually. So, to overcome this problem, we use a build management tool. Maven is a build management tool which is used to define project structure, dependencies, build, and test management. Click here to know How to install Maven.

Step 4 – Create a new Maven Project

Click here to know How to create a Maven project

Below is the Maven project structure. Here,

Group Id – com.example
Artifact Id – Selenium_TestNGDemo
Version – 0.0.1-SNAPSHOT
Package – com. example. Selenium_TestNGDemo

Step 5 – Add Selenium and TestNG dependencies to the project.

As this is a Maven project, we can add the dependencies in POM.xml as shown below.

 <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>3.141.59</version>
    </dependency>
    
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>7.4.0</version>
      <scope>test</scope>
    </dependency>


<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
    <dependency>
      <groupId>org.hamcrest</groupId>
      <artifactId>hamcrest</artifactId>
      <version>2.2</version>
      <scope>test</scope>
    </dependency>

After addition of dependencies in pom.xml, Maven Dependencies folder will be updated automatically with all the JAR file related to the dependencies.

Step 6 – Create a Test file under src/test/java

@BeforeTest – methods under this annotation will be executed prior to the first test case in the TestNG file.

@AfterTest – methods under this annotation will be executed after all test cases in the TestNG file are executed.

@Test – The annotated method is a part of a test case.

Description –  You can describe your test case under the description, stating what it does.

description = "This test validates title of login functionality"

Priority – You can prioritize the order of your test methods by defining a priority. Based on the defined priority, the test shall execute in that order.

priority = 0
public class TestNG_Demo {

	WebDriver driver;

	@BeforeTest
	public void setUp() {
		System.setProperty("webdriver.gecko.driver",
				"C:\\Users\\Vibha\\Software\\geckodriver-v0.26.0-win64\\geckodriver.exe");

		driver = new FirefoxDriver();
		driver.get("https://opensource-demo.orangehrmlive.com/");

		driver.manage().window().maximize();
		driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
	}

	@Test(description = "This test validates title of login functionality", priority = 0)
	public void verifyLoginPage() {

		String expectedTitle = driver.findElement(By.xpath("//*[@id='logInPanelHeading']")).getText();

		System.out.println("Title :" + expectedTitle);
		assertTrue(expectedTitle.equalsIgnoreCase("LOGIN Panel"));
	}

	@Test(description = "This test validates  successful login to Home page", priority = 1)
	public void verifyHomePage() {

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

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

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

		String newPageText = driver.findElement(By.id("welcome")).getText();
		System.out.println("newPageText :" + newPageText);
		assertThat(newPageText, containsString("Welcome"));
	}

	@AfterTest
	public void teardown() {

		driver.quit();
	}

}

Step 7 – Test Execution through TestNG

Go to Runner class and right click Run As TestNG Test. The tests will run as TestNG tests.

Step 8 – Run the tests from TestNG.xml

Create a TestNG.xml as shown below and run the tests as TestNG.

<?xml version = "1.0"encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name = "Suite1">
  <test name = "TestNG Demo">
    <classes>
          <class name = "com.example.Selenium_TestNGDemo.TestNG_Demo"/>
     </classes>  
   </test>
</suite>

Step 9 – TestNG Report Generation

TestNG generates various type of reports under test-output folder like emailable-report.html, index.html, testng-results.xml.

We are interested in ’emailable-report.html’ report. Open ’emailable-report.html’, as this is a html report open it with browser. Below image shows emailable-report.html.

TestNG also produce “index.html” report and it resides under test-output folder. Below image shows index.html report. This is the latest theme of the report.

The links present at the left side are clickable. I have clicked Times link and you can see the details on the right side.