Gradle is an open-source build automation tool that is designed to be flexible enough to build almost any type of software. Gradle runs on the JVM and you must have a Java Development Kit (JDK) installed to use it. Several major IDEs allow you to import Gradle builds and interact with them: Android Studio, IntelliJ IDEA, Eclipse, and NetBeans.
Step 4 – Create a Test Code for the testing of REST API under src/test/java
Rest Assured and Allure Report are two popular tools for testing. Rest Assured is used for API testing and Allure Report is used for creating detailed reports about tests. To see our request and response in more detail using these tools, we need to add a line to our Rest Assured tests. This will provide the request and response details in the report.
For testing purpose, first test – Get Request one fails.
.filter(new AllureRestAssured())
Below is an example of the tests.
package org.example;
import io.qameta.allure.*;
import io.qameta.allure.restassured.AllureRestAssured;
import io.restassured.http.ContentType;
import org.json.JSONObject;
import org.junit.Test;
import static io.restassured.RestAssured.given;
import static org.hamcrest.core.IsEqual.equalTo;
@Epic("REST API Regression Testing using JUnit4")
@Feature("Verify CRUID Operations on Employee module")
public class APITests {
String BaseURL = "https://dummy.restapiexample.com/api";
@Test
@Story("GET Request")
@Severity(SeverityLevel.NORMAL)
@Description("Test Description : Verify the details of employee of id-2")
public void getUser() {
// 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
@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 – Run the Test and Generate Allure Report
To run the tests, use the below command
mvn clean test
The output of the above program is
This will create allure-results folder with all the test reports. These files will be used 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
Categories in Allure Report
The categories tab gives you a way to create custom defects classifications 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, a new result JSON file will get added to 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 times and watch how the number of files 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 click Retries in the right pane. You should see the history of test runs for that test:
Graphs in Allure Report
Graphs allow you to see different statistics collected from the test data: status 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.
The below image shows the request body sent and the status code of the response, its body, and header provided by API.
Packages in Allure Report
The 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!!
Rest Assured enables you to test REST APIs using java libraries and integrates well with Maven/Gradle. REST Assured is a Java library that provides a domain-specific language (DSL) for writing powerful, maintainable tests for RESTful APIs.
What is JUnit?
JUnit is a simple framework to write repeatable tests. It is an instance of the xUnit architecture for unit testing frameworks. JUnit 4 is one of the most popular unit testing frameworks which has a significant role in the test-driven development process.
Dependency List:-
REST Assured – 5.4.0
Java 17
JUnit – 4.13.2
Maven – 3.9.6
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 the system
The Eclipse IDE (integrated development environment) provides strong support for Java developers, 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 a 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 that 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.
The tests should be written in src/test/java directory. To know how to create a JSON Request body using JSONObject, please refer to this tutorial.
import io.restassured.http.ContentType;
import org.json.JSONObject;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static io.restassured.RestAssured.given;
public class APITests {
String BaseURL = "https://dummy.restapiexample.com/api";
@Test
public void createUser() {
JSONObject data = new JSONObject();
data.put("employee_name", "NewUser1");
data.put("employee_salary", "1000");
data.put("employee_age", "35");
// GIVEN
given()
.contentType(ContentType.JSON)
.body(data.toString())
// WHEN
.when()
.post(BaseURL + "/v1/create")
// THEN
.then()
.statusCode(200)
.body("data.employee_name", equalTo("NewUser1"))
.body("message", equalTo("Successfully! Record has been added."));
}
}
Step 7 – Test Execution through JUnit Test
Go to the Runner class and right-click Run As JUnit Test. The tests will run as JUnit tests. (Eclipse)
Below is the image to run the tests in IntelliJ.
This is how the execution console will look like.
Step 8 – Run the tests from the command line
Maven Site Plugin creates a folder – site under the target directory, and the Maven Surefire Report plugin generates the JUnit Reports in the site folder. We need to run the tests through the command line to generate the JUnit Report.
mvn clean test site
The output of the above program is
Step 9 – Report Generation
After the test execution, refresh the project, and a new folder with the name site in the target folder will be generated. This folder contains the reports generated by JUnit. The structure of the folder site looks as shown below.
Step 10 – View the Report
Right-click on the summary.html report and select Open In -> Browser ->Chrome.
Summary Report
Below is the summary Report.
Surefire Report
Below is an example of a Surefire Report. This report contains a summary of the test execution.
We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!
One of the major testing workflows involves switching between multiple windows. Selenium WebDriver has specific switch commands to serve this purpose. Selenium WebDriver assigns an alphanumeric id to each window as soon as the WebDriver object is instantiated. This unique alphanumeric id is called a window handle. Selenium uses this unique id to switch control among several windows. In simple terms, each unique window has a unique ID, so that Selenium can differentiate when it is switching controls from one window to the other.
1) GetWindowHandle
To get the window handle of the current window. It returns a string of alphanumeric window handles.
String parentHandle= driver.getWindowHandle();
2) GetWindowHandles
To get the window handle of all the windows. It returns a set of window handle.
Set handle= driver.getWindowHandles();
3) SwitchTo Window
WebDriver supports moving between named windows using the “switchTo” method.
driver.switchTo().window("windowName");
Let us explain window switch with an example:-
1) Launch new Browser and open https://demoqa.com/browser-windows 2) Check the count of windows which is 1 3) Locate “New Window” button using Id – “windowButton” and click to open a new window 4) Get the count of both windows which is now 2. 5) Get the parent window handle and print it to console 6) Get the window handles of both the open windows and print them 7) Switch to the new window (child window) 8) Get the text of Child Window and print it 9) Close the new window (child window)
The program for the above scenario is shown below:
package com.example.definitions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class WindowSwitchDemo {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
WebDriver driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
// Pass application url
driver.get("https://demoqa.com/browser-windows");
//Count of window - 1
Set<String> allWindowHandles = driver.getWindowHandles();
System.out.println("Count of Window :" + allWindowHandles.size());
//Open a child window
driver.findElement(By.id("windowButton")).click();
//Count of windows , changed from 1 to 2
Set<String> newAllWindowHandles = driver.getWindowHandles();
System.out.println("New Count of Window :" + newAllWindowHandles.size());
// Get the detail of the parent window
String ParentHandle = driver.getWindowHandle();
System.out.println("Parent Window :" + ParentHandle);
//Get details of parent and child windows
Iterator<String> iterator = newAllWindowHandles.iterator();
String mainWindow = iterator.next();
String childWindow = iterator.next();
System.out.println("Parent Window :" + mainWindow);
System.out.println("Child Window :" + childWindow);
//Switch control to child window
driver.switchTo().window(childWindow);
//Verify the text present on child window
WebElement text = driver.findElement(By.id("sampleHeading"));
System.out.println("Child_Title :" + text.getText());
// Close Child window
driver.close();
// Switch back to parent window
driver.switchTo().window(ParentHandle);
System.out.println("Parent Title :" + driver.getTitle());
// Close Parent window
driver.quit();
}
}
The output of the above program is
What is the difference between driver.close() and driver.quit()?
When we are working on multiple windows and a selective window needs to be closed, then transfer the control to that window and use driver.close() to close the selective window. This will not stop the execution of the rest of the program. But, in case it is needed to close all the open windows, then use driver.quit() which will close all the windows opened in a particular session. It basically stops the driver instance, and any further actions to WebDriver may result in an exception. It is generally the last statement of any code.
Congratulations. We have learnt about window switching in Selenium. I hope you find this tutorial helpful. Happy Learning!!
Cucumber Data Tables can be used to add multiple parameters in Step Definition in a tabular form rather than putting all the parameters in the Gherkin statement. This is much easier to read and multiple rows of data can be passed in the same step. Data tables from Gherkin can be accessed by using the DataTable object as the last parameter in a Step Definition. This conversion can be done either by Cucumber or manually.
Let’s write a simple data table and see how we use it.
1. Table into List of a List of Strings
| firstName | lastName | age |
| Thomas | Brown | 30 |
| Perry | Wilson | 26 |
| Ashley | William | 27 |
java type: List<List<String>>
The natural representation of list of a list of strings is shown below.
[
[ "firstName", "lastName", "age" ],
[ "Thomas", "Brown", "30" ],
[ "Perry", "Wilson", "26" ],
[ "Ashley", "William", "27" ]
]
2. Table into List of Maps
java type: List<Map<String, String>>
The natural representation of list of maps is shown below.
[
{ "firstName": "Thomas", "lastName": "Brown", "age": "30" },
{ "firstName": "Perry", "lastName": "Wilson", "age": "26" },
{ "firstName": "Ashley", "lastName": "William", "age": "27" }
]
3. Table into Single Map
Table where first colum is key as shown below
| IN | India |
| IRE | Ireland |
java type: Map<String, String>
TO convert the table into a single map
{
"IN": "India",
"IRE": "Ireland"
}
4. Table into map that uses a list as its value
A table with multiple column values per key.
| IN | India | 29 |
| IRE | Ireland | 8 |
java type: Map<String, List<String>>
{
"IN": ["India","29"],
"IRE": ["Ireland","8"]
}
Now, let us see how we can use DataTable in Cucumber
Cucumber Data Tables Example in Java
Data Table without Header Example
Below is an example of how to implement Data Tables without a Header. For example, we want to test the Login Page of an application. We can either mention all the arguments inside the Gherkin statement or use a table to list all the arguments, as we used below:
Feature: Login to HRM Application
@ValidCredentials
Scenario: Login with valid credentials - Data Table without Header
Given User is on HRMLogin page
When User enters valid credentials
| Admin | admin123 |
Then User should be able to login successfully and new page open
Below is the Step Definition of the above scenario.
import io.cucumber.datatable.DataTable;
import io.cucumber.java.After;
import io.cucumber.java.Before;
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;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
public class DataTableDefinitions {
WebDriver driver;
@Before
public void setup() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
@Given("User is on HRMLogin page")
public void userOnHomePage() {
driver.get("https://opensource-demo.orangehrmlive.com/");
}
@When("User enters valid credentials")
public void entersValidCredential(DataTable dataTable) throws InterruptedException{
System.out.println("Credentials Entered");
List<List<String>> signUpForm = dataTable.asLists(String.class);
String userName = signUpForm.get(0).get(0);
String passWord = signUpForm.get(0).get(1);
driver.findElement(By.name("username")).sendKeys(userName);
driver.findElement(By.name("password")).sendKeys(passWord);
driver.findElement(By.xpath("//*[@class='oxd-form']/div[3]/button")).submit();
}
@Then("User should be able to login successfully and new page open")
public void successfulLogin() throws InterruptedException {
String newPageText = driver.findElement(By.xpath("//*[@class='oxd-topbar-header-breadcrumb']/h6")).getText();
System.out.println("newPageText :" + newPageText);
assertThat(newPageText, containsString("Dashboard"));
}
@After
public void teardown(){
driver.quit();
}
}
To run the Feature file, we need a Cucumber TestRunner.
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/DataTable.feature",
glue = "definitions", tags="@ValidCredentials")
public class CucumberRunnerTest {
}
The output of the above program is
In the above example, we don’t have a header. We have just got the List object. We get the values of DataTable starting from 0 index.
Cucumber converts the above table into a list of lists. It treats each row as a list of the column values. We use the asLists method — supplying a String.class argument — to convert the DataTable argument to a List<List<String>>. This Class argument informs the asLists method of what data type we expect each element to be.
Data Table with Header and Single Row Example
Below is a cucumber data tables example with the header.
Adding a header to your table makes it easier to read and maintain.
@InValidCredential
Scenario: Login with invalid credential - Header with Single Row
Given User is on HRMLogin page
Then User enters invalid credentials and Login will be unsuccessful with error message
| Username | Password | ErrorMessage |
| Admin1 | admin123!$ | Invalid credentials |
Below is the Step Definition of the above scenario.
package org.example.definitions;
import io.cucumber.datatable.DataTable;
import io.cucumber.java.After;
import io.cucumber.java.Before;
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;
import org.openqa.selenium.chrome.ChromeOptions;
import java.time.Duration;
import java.util.List;
import java.util.Map;
public class DataTableDefinitions {
WebDriver driver;
@Before
public void setup() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
@Given("User is on HRMLogin page")
public void userOnHomePage() {
driver.get("https://opensource-demo.orangehrmlive.com/");
}
@Then("User enters invalid credentials and Login will be unsuccessful with error message")
public void entersInvalidCredential(DataTable userTable) throws InterruptedException {
System.out.println("Enter Credentials");
List<Map<String, String>> user = userTable.asMaps(String.class, String.class);
String userName = user.get(0).get("Username");
System.out.println("Username :" + userName);
driver.findElement(By.name("username")).sendKeys(userName);
String passWord = user.get(0).get("Password");
System.out.println("Password :" + passWord);
driver.findElement(By.name("password")).sendKeys(passWord);
driver.findElement(By.xpath("//*[@class='oxd-form']/div[3]/button")).submit();
String errorMessage = user.get(0).get("ErrorMessage");
String actualErrorMessage = driver.findElement(By.xpath("//*[@class='orangehrm-login-error']/div[1]/div[1]/p")).getText();
System.out.println("Actual Error Message :" + actualErrorMessage);
Assert.assertTrue(actualErrorMessage.equalsIgnoreCase(errorMessage));
}
@After
public void teardown(){
driver.quit();
}
}
The output of the above program is
In the above example, we have only 1 row with the header, so have used get(0) to retrieve the first row of DataTable. After that, I used get(“HeaderName”) to get the value of the row of DataTable.
Data Table with Header and Multiple Rows Example
Below is a cucumber data table example with multiple rows of data with the header. This is helpful when we want to test multiple combinations of data in a step.
@Multiple_InValidCredentials
Scenario: Login with invalid credentials - Data Table with Header and Multiple Rows
Given User is on HRMLogin page
Then User enters invalid credentials and Login will be unsuccessful with custom error messages
| Username | Password | ErrorMessage |
| Admin1 | admin123! | Invalid credentials |
| Admina | admin123a | Invalid credentials |
Below is the Step Definition of the above scenario
import io.cucumber.datatable.DataTable;
import io.cucumber.java.After;
import io.cucumber.java.Before;
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;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
public class DataTableDefinitions {
WebDriver driver;
@Before
public void setup() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
}
@Given("User is on HRMLogin page")
public void userOnHomePage() {
driver.get("https://opensource-demo.orangehrmlive.com/");
}
@Then("User enters invalid credentials and Login will be unsuccessful with custom error messages")
public void entersInvalidCredentials(DataTable userTable) throws InterruptedException {
System.out.println("Enter Credentials");
List<Map<String, String>> user = userTable.asMaps(String.class, String.class);
for (Map<String, String> form : user) {
String userName = form.get("Username");
System.out.println("Username :" + userName);
driver.findElement(By.name("username")).sendKeys(userName);
String passWord = form.get("Password");
System.out.println("Password :" + passWord);
driver.findElement(By.name("password")).sendKeys(passWord);
driver.findElement(By.xpath("//*[@class='oxd-form']/div[3]/button")).submit();
String errorMessage = form.get("ErrorMessage");
String actualErrorMessage = driver.findElement(By.xpath("//*[@class='orangehrm-login-error']/div[1]/div[1]/p")).getText();
System.out.println("Actual Error Message :" + actualErrorMessage);
Assert.assertTrue(actualErrorMessage.equalsIgnoreCase(errorMessage));
}
}
@After
public void teardown(){
driver.quit();
}
}
The output of the above program is
Cucumber creates a list containing each row, but instead maps the column heading to each column value. Cucumber repeats this process for each subsequent row. We use the asMaps method — supplying two String.class arguments — to convert the DataTable argument to a List<Map<String, String>>.
The first argument denotes the data type of the key (header). The second indicates the data type of each column value. Thus, we supply two String.class arguments because our headers (key) and title and author (values) are all Strings.
Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!
ArrayList is a part of collection framework and is present in java.util package. It provides us dynamic arrays in Java. ArrayList is a resizable-array implementation of the List interface. In this tutorial, we will cover the below topics:-
1) What is the difference between Array and ArrayList?
Array has fixed length, so if it is full we cannot add more elements, similarly if we delete few elements from the array, there will not be any change in the memory consumption. Whereas ArrayList can grow dynamically. We can add elements as well can delete the elements and this will make changes in the memory consumption. The size of an array cannot modified (if you want to add or remove elements to/from an array, we have to create a new one). While elements can added and removed from an ArrayList.
2) How to create an ArrayList?
This statement creates an ArrayList with the name Companies with type “String”.
import java.util.ArrayList; // import the ArrayList class
ArrayListCompanies = new ArrayList(); // Create an ArrayList object
3) How to add elements to an ArrayList?
We can add element to an ArrayList by using add() method. There are many ways to add elements.
1) To add the element at the end of the List.
Companies.add("Samsung");
2) To add the element at the specified location in ArrayList, we can specify the index in the add method like this.
Companies.add(2,"Microsoft");
4) How to remove elements from ArrayList?
1) To remove the element with name.
Companies.remove("MI");
2) To remove the element at the specified location in ArrayList, we can specify the index in the remove method.
Companies.remove(1);
5) ArrayList SizeMethod
To find out how many elements an ArrayList have, use the size() method.
Companies.size();
Let me show how to add and remove elements from an ArrayList with the help of an example.
package com.example.definitions;
import java.util.ArrayList;
import java.util.function.Predicate;
public class ArrayList_IteratorExample {
public static void main(String[] args) {
//Create ArrayList of String
ArrayList<String> Companies = new ArrayList();
// Check if an ArrayList is empty
System.out.println("Is Company List empty :"+Companies.isEmpty());
// Adding new elements to the ArrayList
Companies.add("Samsung");
Companies.add("Apple");
Companies.add("Motorola");
Companies.add("Google");
Companies.add("Sony");
Companies.add("Blackberry");
System.out.println("Company List is :"+Companies);
// Adding an element at a particular index in an ArrayList
Companies.add(2,"Microsoft");
System.out.println("Updated Company List is:"+Companies);
// Find the size of an ArrayList
System.out.println("Size of Company List: "+Companies.size());
// Retrieve the element at a given index
System.out.println("First Company in list: "+Companies.get(0));
// Retrieve the last element from ArrayList
String LastCompany = Companies.get(Companies.size()-1);
System.out.println("Last Company in list: "+LastCompany);
// Remove the element
Companies.remove("MI");
// Remove the element at index '1'
Companies.remove(1);
System.out.println("Updated Company List after removal is:"+Companies);
// Remove first occurrence of the given element from the ArrayList
// (The remove() method returns false if the element does not exist in the ArrayList)
boolean isRemoved = Companies.remove("Lenovo");
System.out.println("Lenovo exists in Company List :"+isRemoved);
// Remove all the elements that satisfy the given predicate
Predicate<String> newCompanies = company -> company.startsWith("B");
Companies.removeIf(newCompanies);
System.out.println("After Removing all elements that start with \"B\": " + Companies);
}
}
The output of the above program is
6) Method to iterate through ArrayList
There are various methods to iterate through ArrayList. We will discuss few of the methods. 1) Iterator interface 2) For -each loop 3) For loop 4) While loop
package com.example.definitions;
import java.util.ArrayList;
public class ArrayList_IteratorExample {
public static void main(String[] args) {
//Creating arraylist
ArrayList<String> Companies = new ArrayList();
// Adding new elements to the ArrayList
Companies.add("Samsung");
Companies.add("Apple");
Companies.add("Motorola");
Companies.add("Google");
Companies.add("Sony");
Companies.add("Blackberry");
//Traversing list through Iterator
for(String a:Companies)
System.out.println(a);
System.out.println("------------------------------------------");
//Traversing list through for loop
for(int i=0;i<Companies.size();i++)
{
System.out.println(Companies.get(i));
}
System.out.println("------------------------------------------");
// Traversing list through For-Each loop
for(String a:Companies)
System.out.println(a);
}
}
The output of the above program is
Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!! Cheers!!
Java is a general-purpose programming language that is a concurrent, class-based, and object-oriented language. Java follows the concept of “write once and run anywhere (WORA).” This means that compiled Java code can be run on all different platforms that support Java. There’s no need for recompilation.
The below example covers the implementation of Allure Reports with Cucumber, Selenium, TestNG, Java, and Maven. Before starting, make sure to install Allure on your machine. Refer to this tutorial to install allure – What is Allure Report?.
Create a folder – features within src/test/resources to create test scenarios in the 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 scenarios are written in Gherkinslanguage.
Feature: Login to HRM Application
Background:
Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"
@ValidCredentials
Scenario: Login with valid credentials
When User enters username as "Admin" and password as "admin123"
Then User should be able to login successfully and new page open
@InvalidCredentials
Scenario Outline: Login with invalid credentials
When User enters username as "<username>" and password as "<password>"
Then User should be able to see error message "<errorMessage>"
Examples:
| username | password | errorMessage |
| Admin | admin12$$ | Invalid credentials |
| admin$$ | admin123 | Invalid credentials |
| abc123 | xyz$$ | Invalid credentials |
| 234 | xyz$$ | Invalid credentials! |
Step 5 – Create the Step Definition class or Glue Code
The stepdefinition class is created in src/test/java directory.
Below is the code for the Hooks.
package com.example.definitions;
import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.Scenario;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.time.Duration;
public class Hooks {
protected static WebDriver driver;
public final static int TIMEOUT = 5;
@Before
public void setUp() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(TIMEOUT));
}
@After
public void tearDown(Scenario scenario) {
try {
String screenshotName = scenario.getName();
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
package com.example.definitions;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import org.openqa.selenium.By;
import org.testng.Assert;
public class LoginPageDefinitions {
Hooks hooks;
@Given("User is on HRMLogin page {string}")
public void loginTest(String url) {
hooks.driver.get(url);
}
@When("User enters username as {string} and password as {string}")
public void goToHomePage(String userName, String passWord) {
// login to application
hooks.driver.findElement(By.name("username")).sendKeys(userName);
hooks.driver.findElement(By.name("password")).sendKeys(passWord);
hooks.driver.findElement(By.xpath("//*[@class='oxd-form']/div[3]/button")).submit();
// go the next page
}
@Then("User should be able to login successfully and new page open")
public void verifyLogin() {
String homePageHeading = hooks.driver.findElement(By.xpath("//*[@class='oxd-topbar-header-breadcrumb']/h6")).getText();
//Verify new page - HomePage
Assert.assertEquals(homePageHeading,"Dashboard");
}
@Then("User should be able to see error message {string}")
public void verifyErrorMessage(String expectedErrorMessage) {
String actualErrorMessage = hooks.driver.findElement(By.xpath("//*[@class='orangehrm-login-error']/div[1]/div[1]/p")).getText();
// Verify Error Message
Assert.assertEquals(actualErrorMessage, expectedErrorMessage);
}
}
Step 6 – Create a TestNG Cucumber Runner class
We need to create a class called Runner class to run the tests. This class will use the TestNG annotation @Test, which tells TestNG what is the test runner class.
package com.example.runner;
import org.testng.annotations.Test;
import io.cucumber.testng.AbstractTestNGCucumberTests;
import io.cucumber.testng.CucumberOptions;
@Test
@CucumberOptions(tags = "", features = {"src/test/resources/features"}, glue = {"com.example.definitions"},
plugin = {"pretty","io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm"})
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 executesCucumberRunnerTests as a separate 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.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 one test failed and four passed out of five tests.
This will create the allure-results folder with all the test reports within target folder. These files will be used to generate Allure Report.
Use the below command 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
The categories tab gives you a way to create custom defect classifications 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 tests are executed from CucumberRunnerTests.
Graphs in Allure Report
Graphs allow you to see different statistics collected from the test data: status breakdown or severity and duration diagrams.
Timeline in Allure Report
The timeline tab visualizes retrospective test execution, allure adaptors collect precise timings of tests, and here on this tab, they are arranged accordingly to their sequential or parallel timing structure.
Behaviours of Allure Report
This tab groups test results according to Epic, Feature, and Story tags.
Screenshot attached to the failed test case
Packages in Allure Report
The 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.
Congratulations!! We have integrated an allure report with Cucumber, Selenium, and TestNG. I hope this tutorial is useful to you.
Static method is a method that belongs to the class, not to the instance of the class.
It can be access without creating the object of the class.
Static method can only access static variables, static methods of same class or another class.
Method Overriding – Static methods cannot be overridden because of early binding
Memory Allocation – In static method, memory allocation happens only once, because the static keyword fixed a particular memory for that method in ram. So when the method calls every time in a program, each time that particular memory is used.
Below is an example that shows how the static methods can be use without creating an object of the class.
package com.example.definitions;
public class staticMyClass {
static void MyStatic_Method() { // Static Method
System.out.println("Static method can be accessed without creating object");
}
public void MyPublic_Method() { // Public Method
System.out.println("Public method can be accessed only by creating object");
}
public static void main(String[] args) {
MyStatic_Method(); // Calling Static Method
}
}
The output of the above program is
Non Static Method
Non Static can be public, private, protected or default. They do not have static or non-static keyword before their method name.
It can be access by creating the object of the class.
Non Static method can access static variables, static methods of same class or another class as well as non-static variables and methods.
Method Overriding – Non Static methods can be overridden because of runtime binding
Memory Allocation – In non-static method, memory allocation happens when the method invokes and the memory is allocated every time when the method is called. So more memory is used here as compared to static method.
public class nonStaticClass {
static void MyStatic_Method() { // Static Method
System.out.println("Static method can be accessed without creating object");
}
public void MyPublic_Method() { // Public Method
System.out.println("Public method can be accessed only by creating object");
}
public static void main(String[] args) {
nonStaticClass stat = new nonStaticClass();
stat.MyPublic_Method(); // Calling Non Static Method
}
}
The traditional way to use any browser in Selenium tests is to download browser binaries, and we need to set the path of these files in our script like below or its location should be added to the classpath.
The process of manually downloading and managing these drivers for each of the operating systems is very painful. We also have to check when new versions of the binaries are released / new browser versions are released. We should check the compatibility for all the executables and add them.
Note: – Selenium 4.6 and above has inbuilt tool to handle drivers. If you are using Selenium version less than 4.6, then you can use WebDriverManager.
How to download all the driver executables automatically?
The automatic download of the drivers can be done by WebDriverManager. WebDriverManager is a library that allows controlling web browsers programmatically. It provides a cross-browser API that can be used to drive web browsers (e.g., Chrome, Edge, or Firefox, among others) using different programming languages (e.g., Java, JavaScript, Python, C#, or Ruby). The primary use of Selenium WebDriver is implementing automated tests for web applications.
The communication between the WebDriver API and the driver binary is done using a standard protocol called W3C WebDriver (formerly the so-called JSON Wire Protocol). Then, the communication between the driver and the browser is done using the native capabilities of each browser.
How To add WebDriverManager to a Selenium project manually?
Download the latest version of WebDriverManager from here.
It will download a zip file. Now extract the jar/zip file. It will show various .jar under the folder, as shown below:
Once we extract the zip file, we have to reference these jar files in our project. For this, navigate to project properties and click Build Path-> Configure Build Path in Eclipse
Click “Add External Jars” as per the steps highlighted below to include all the WebDriverManager jars extracted.
After clicking on the “Add External JARs“, all the selected extracted JARs are added to the project.
When this finishes, the project references show these referenced jars in the project explorer as highlighted below, and they are ready to be consumed in the Selenium test scripts.
Chrome
The below code snippet shows a quick usage of WebDriverManager with Chrome:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Demo {
public static void main(String[] args) {
WebDriverManager.chromedriver().setup();
// Create an object of Chrome Options class
ChromeOptions chromeOptions = new ChromeOptions();
// Create an object of WebDriver class and pass the Chrome Options object as
// an argument
WebDriver driver = new ChromeDriver(chromeOptions);
System.out.println("Executing Chrome Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
The output of the above program is
FireFox Driver
The below code snippet shows a quick usage of WebDriverManager with FireFox:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class FireFoxDemo {
public static void main(String[] args) {
WebDriverManager.firefoxdriver().setup();
// Create an object of Firefox Options class
FirefoxOptions firefoxOptions = new FirefoxOptions();
// Create an object of WebDriver class and pass the Firefox Options object
// as an argument
WebDriver driver = new FirefoxDriver(firefoxOptions);
System.out.println("Executing Firefox Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
The output of the above program is
Microsoft Edge
The below code snippet shows a quick usage of WebDriverManager with Microsoft Edge:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class EdgeDemo {
public static void main(String[] args) {
WebDriverManager.edgedriver().setup();
// Create an object of Edge Options class
EdgeOptions edgeOptions = new EdgeOptions();
// Create an object of WebDriver class and pass the Edge Options object
// as an argument
WebDriver driver = new EdgeDriver(edgeOptions);
System.out.println("Executing Microsoft Edge Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
How to instantiate a specific browser version using WebDriverManager?
WebDriverManagerprovides the ability to download a specific version of the browser. For example, the latest chromedriver version is 100.0.4896.20 (released on 2022-03-04). But if we want an earlier version, say, Chromedriver version 98.0.4758.102, we have to add the following code.
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import io.github.bonigarcia.wdm.WebDriverManager;
public class Demo {
public static void main(String[] args) {
WebDriverManager.chromedriver().driverVersion("98.0.4758.102").setup();
// Create an object of Chrome Options class
ChromeOptions chromeOptions = new ChromeOptions();
// Create an object of WebDriver class and pass the Chrome Options object as
// an argument
WebDriver driver = new ChromeDriver(chromeOptions);
System.out.println("Executing Chrome Driver");
driver.get("https://www.bing.com/");
System.out.println("Title of Page :" + driver.getTitle());
System.out.println("Page URL : " + driver.getCurrentUrl());
// Close the driver
driver.close();
}
}
The output of the above program is
As we can see from the above screenshot, as a result of executing the above program, the Chromedriver started successfully. We can see the details of starting the chrome driver instance in the first line of output. Here we have set the Chrome version to “98.0.4758.102″.
Congratulations!! We have learned to download drivers automatically.