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!!
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.
Featurefile should be saved as an extension of .feature. Add the test scenarios in this feature file. I have added sample test scenarios. The test scenarios are written inGherkins language. A feature file is created under src/test/resources.
Feature: Login to HRM
@ValidCredentials
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 successfully
@InValidCredentials
Scenario Outline: Login with invalid credentials
Given User is on Home page
When User enters username as '<username>'
And User enters password as '<password>'
Then User should be able to see error message '<errorMessage>'
Examples:
|username |password |errorMessage |
|admin |admin |Invalid credentials |
| |admin123 |Username cannot be empty |
|Admin | |Password cannot be empty |
| | |Username cannot be empty |
@ForgetPassword
Scenario: Verify Forget Password Functionality
Given User is on Home page
When User clicks on Forgot your password link
Then User should be able to see new page which contains Reset Password button
Step 5 – Create the Step Definition class or Glue Code
Create a StepDefinition class for LoginPage.feature.
package com.example.definitions;
import com.example.steps.StepDashboardPage;
import com.example.steps.StepForgetPasswordPage;
import com.example.steps.StepLoginPage;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import net.serenitybdd.annotations.Steps;
import org.junit.Assert;
import static org.junit.Assert.assertTrue;
public class LoginPageDefinitions {
@Steps
StepLoginPage loginPage;
@Steps
StepDashboardPage dashPage;
@Steps
StepForgetPasswordPage forgetpasswordPage;
@Given("User is on Home page")
public void openApplication() {
loginPage.open();
System.out.println("Page is opened");
}
@When("User enters username as {string}")
public void enterUsername(String userName) {
System.out.println("Enter Username");
loginPage.inputUserName(userName);
}
@When("User enters password as {string}")
public void enterPassword(String passWord) {
loginPage.inputPassword(passWord);
loginPage.clickLogin();
}
@Then("User should be able to login successfully")
public void clickOnLoginButton() {
dashPage.loginVerify();
}
@Then("User should be able to see error message {string}")
public void unsuccessfulLogin(String expectedErrorMessage) {
String actualErrorMessage = loginPage.errorMessage();
Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
}
@When("User clicks on Forgot your password link")
public void clickForgetPasswordLink() {
loginPage.clickForgetPasswordLink();
}
@Then("User should be able to see new page which contains Reset Password button")
public void verifyForgetPasswordPage() {
assertTrue(forgetpasswordPage.ForgetPasswordPage());
}
}
Serenity Step Libraries integrate smoothly into Cucumber Step Definition files; all you need to do is to annotate a step library variable with the @Steps annotation. Methods that represent a business task or action (inputUserName()), and that will appear in the reports as a separate step, is annotated with the @Step annotation. Other methods, such as loginVerify(), query the state of the application and are used in assert statements.
Here, I have created 3 StepClasses – StepLoginPage, StepDashboardPage, and StepForgetPasswordPage
We cannot run a Feature file on its own in a cucumber-based framework. We need to create a Java class, which will run the Feature File. It is the starting point for JUnit to start executing the tests. TestRunner class creates under src/ test/java. When you run the tests with serenity, you use the CucumberWithSerenity test runner. If the feature files are not in the same package as the test runner class, you also need to use the @CucumberOptions class to provide the root directory where the feature files are found.
import org.junit.runner.RunWith;
import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;
@RunWith(CucumberWithSerenity.class)
@CucumberOptions(plugin = {}, features = "src/test/resources/features/LoginPage.feature", glue = "com.example.definitions")
public class SerenityRunnerTests {
}
Step 7 – Create serenity.conf file under src/test/resources
Serenity.conf file is used to specify various features like the type of webdriver used, various test environments, run tests in headless mode, and many more options.
webdriver.driver. – This tells Serenity which browser to use for the test execution. You can configure this in several locations – serenity.properties or serenity.conf. Here, I have provided this information in serenity.conf
We can also configure the webdriver.base.url property for different environments in the serenity.conf configuration file, in the src/test/resources directory. Below is an example of the same.
Once the environment section is present in your serenity.conf file, you can use the environment system property to use the properties for a given environment. For example, the following would cause the staging URLs to be used:
mvn clean verify -Denvironment=staging
The default environment will be used if no other value is provided. In our example, I will not provide any environment, so it will pick the default environment.
Step 8 – Create serenity.properties file at the root of the project
serenity.project.name = Serenity and Cucumber Report Demo
Step 9 – Run the tests through the command line which generates Serenity Report
Open the command line and go to the location where pom.xml of the project is present and type the below command.
mvn clean verify -Denvironment=firefox
I have provided the location of the Firefox driver through the command line. I believe this is the best way to run the test. We can hard-code the path in the test code or in serenity.conf file. If you don’t want to pass the location of webdriver through the command line, then mention the details of webdriver in serenity.conf and just use the below command for execution.
mvn clean verify
Below is the image of the execution status.
This also provides the location of the serenity report as highlighted in the above image.
Serenity Report
Requirement View
In Serenity, requirements are organized in a hierarchy. We can get an idea of the full directory structure (in src/test/features directory) for the project.
The Test Resultstab (shown below) tells you about the acceptance tests that were executed for this set of requirements.
Test Results
At the bottom of the Test Results tab, you will find the actual test results – the list of all the tests, automated and manual, that were executed for this requirement.
Feature
This provides the detail of all the Test Scenarios present in a Feature File.
Below is an example of a Scenario Outline in the Report. It shows all the examples mentioned in the feature file.
This screen shows the test steps and screenshots of each step.
We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!
Serenity BDD is an open-source library that aims to make the idea of living documentation a reality.
Serenity BDD helps you write cleaner and more maintainable automated acceptance and regression tests faster. Serenity also uses the test results to produce illustrated, narrative reports that document and describe what your application does and how it works. Serenity tells you not only what tests have been executed, but more importantly, what requirements have been tested.
One key advantage of using Serenity BDD is that you do not have to invest time in building and maintaining your own automation framework.
Serenity BDD provides strong support for different types of automated acceptance testing, including:
Rich built-in support for web testing with Selenium.
REST API testing with Rest Assured.
Highly readable, maintainable, and scalable automated testing with the Screenplay pattern.
Getting started Cucumber 6 with Serenity BDD
Cucumber is a popular tool for automating BDD-style acceptance criteria.
Serenity seamlessly supports Cucumber 2.x, Cucumber 5, and Cucumber 6. However, this flexibility requires a little tweaking in the build dependencies.
If you are using Maven, you need to do the following:
exclude the default cucumber-core dependency from your serenity-core dependency
Add dependencies on the Cucumber 6.x version of cucumber-java and cucumber-junit into your project.
Prerequisite:
Serenity – 4.0.30
JUnit4 – 4.13.2
Serenity Cucumber – 4.0.30
Maven Compiler – 3.12.1
Maven Surefire Plugin – 3.2.3
Java – 17
Project Structure
Relationship between Web Application, Serenity BDD, Cucumber, and Selenium
Implementation Steps
Step 1: Add Serenity, Cucumber, and JUnit4 dependencies to the Maven project
The pom.xml will look like something as shown below.
Step 2: Create a Feature File under src/test/resources
A Feature File is an entry point to the Cucumber tests. This is a file where you will describe your tests in Descriptive language (Like English). A feature file can contain a scenario or can contain many scenarios in a single feature file. Below is an example of a Feature file.
Feature: Login Page
@ValidCredentials
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 successfully
@InValidCredentials
Scenario Outline: Login with invalid credentials
Given User is on Home page
When User enters username as '<username>'
And User enters password as '<password>'
Then User should be able to see error message '<errorMessage>'
Examples:
| username | password | errorMessage |
| $$$$$ | ££££££££ | Invalid credentials |
| admin | Admin123 | Invalid credentials |
| Admin123 | admin | Invalid credentials |
Step 3: Create the Step Definition class
The glue code shown below uses Serenity step libraries as action classes to make the tests easier to read and to improve maintainability.
These classes declare using the Serenity @Steps annotation. The @Steps annotation tells Serenity to create a new instance of the class, and inject any other steps or page objects that this instance might need.
Each action class models a particular facet of user behavior: navigating to a particular page, performing a search, or retrieving the results of a search. These classes design to be small and self-contained, which makes them more stable and easier to maintain.
LoginPageDefinitioncontains the steps to open the web browser, enter the username, enter the password and click on the Login Button
package com.example.definitions;
import com.example.steps.StepDashboardPage;
import com.example.steps.StepLoginPage;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import net.serenitybdd.annotations.Steps;
import org.junit.Assert;
public class LoginPageDefinitions {
@Steps
StepLoginPage loginPage;
@Steps
StepDashboardPage dashPage;
@Given("User is on Home page")
public void openApplication() {
loginPage.open();
System.out.println("Page is opened");
}
@When("User enters username as {string}")
public void enterUsername(String userName) {
System.out.println("Enter Username");
loginPage.inputUserName(userName);
}
@When("User enters password as {string}")
public void enterPassword(String passWord) {
loginPage.inputPassword(passWord);
loginPage.clickLogin();
}
@Then("User should be able to login successfully")
public void clickOnLoginButton() {
dashPage.loginVerify();
}
@Then("User should be able to see error message {string}")
public void unsucessfulLogin(String expectedErrorMessage) throws InterruptedException {
String actualErrorMessage = loginPage.errorMessage();
Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
}
}
This annotation lets you define a URL or a set of URLs that work with a particular page.
StepLoginPage is created by extending it from PageObject class. In this class, $() method used below, which locates a web element using a By locator or an XPath or CSS expression. This class is responsible for uniquely locating elements on the page, and it does this by defining locators or occasionally by resolving web elements dynamically.
Step 4: Create Serenity Test Runner under src/test/java
We cannot run a Feature file on its own in a cucumber-based framework. We need to create a Java class, which will run the Feature File. It is the starting point for JUnit to start executing the tests. TestRunner class creates under src/test/java. When you run the tests with serenity, you use the CucumberWithSerenity test runner. If the feature files are not in the same package as the test runner class, you also need to use the @CucumberOptions class to provide the root directory where the feature files found.
Below is the code for SerenityRunnerTests.
import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;
import org.junit.runner.RunWith;
@RunWith(CucumberWithSerenity.class)
@CucumberOptions(plugin = { "pretty" }, features = "src/test/resources/features/LoginPage.feature",
glue="com.example.definitions")
public class SerenityRunnerTests {}
Step 5: Create serenity.conf (Configuration File)
Serenity uses serenity.conf file in thesrc/test/resources directory to configure test execution options. serenity.config can also contain the environment URL and other options like headless mode and soon.
To have a successful and effective implementation of a test framework, it is always advisable that the test framework supports test execution in multiple ways. The most commonly used ways to execute tests in Cucumber Framework are by running the tests using JUnit and TestNG.
To execute tests using JUnit, we need to create a JUnit Test Runner. Whereas, we need a Maven project to execute Cucumber tests from Command-Line.
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
@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 |
HomePage.feature
Feature: Login to Home
Background:
Given User is on HRMLogin page "https://opensource-demo.orangehrmlive.com/"
@ValidCredentialsHome
Scenario: Login with valid credentials to got to home page
When User enters username as "Admin" and password as "admin123"
Then User should be able to login successfully and new Home page opens
Run Test from Command Line
1. Running all the tests
1. Open the command prompt and change the directory to the project location where pom.xml is present.
2. All feature files should be in src/test/resources and create the Cucumber Runner class as CucumberRunnerTest. Note:- The Runner class name should end with Test to execute the tests from Command Line Run the following command in the command prompt:
mvn clean test
mvn clean test runs Cucumber Features using Cucumber’s JUnit Runner. The @RunWith (Cucumber.class)annotation on the TestRunner class tells JUnit to start Cucumber. Cucumber runs time parses the command-line options to know what feature to run, where the Glue Code lives, what plugins to use, and so on.
3. The below screenshot shows that CucumberRunnerTest class is triggered.
4. The below screenshot shows the build success output.
Cucumber provides several options that can be passed to on the command line.
2. Running Scenarios using Tags
If you are using Maven and want to run a subset of scenarios tagged with @ValidCredentials.
mvn clean test -Dcucumber.filter.tags="@ValidCredentials"
The output of the above program is
3. Running a Feature file
Suppose you want to run a single Feature File from the command line, then use the below syntax
mvn clean test -Dcucumber.features="src/test/resources/features/HomePage.feature"
The output of the above program is
4. Creating Cucumber Report from Command Line
If we want to generate a different report, then we can use the following command and see the HTML report generate at the location mentioned:
mvn clean test -Dcucumber.plugin="html:target/cucumber-reports/cucumberReport.html"
The output of the above program is
5. Passing multiple Parameters
If we want to pass more than one parameter, then we can use the following command
mvn clean test -Dcucumber.features="src/test/resources/features/LoginPage.feature" -Dcucumber.filter.tags="@ValidCredentials"
The output of the above program is
6. Running a Scenario without a tag
If we want to run a single Scenario from the command line and no tag is assigned to that scenario, this is how we specify
mvn clean test -Dcucumber.features="src/test/resources/features/LoginPage.feature:7"
The output of the above program is
That’s it! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!
GitHub serves as a collaborative platform that supports version control, code collaboration, automated testing, and issue tracking, all of which are crucial elements in the software testing process. It promotes transparency, collaboration, and efficiency in the development and testing workflows.
CI/CD pipelines have contributed to the success of the DevOps cycle in all software development projects. This is a holistic process that bridges development and operations. Continuous integration helps development teams deploy code efficiently, and continuous delivery automates code deployment.
Implementation Steps
Step 1 – Create GitHub Actions and Workflows
I have a repository available in GitHub – RestAssured_TestNG_Demo as shown in the below image. Go to the “Actions” tab. Click on the “Actions” tab.
Step 2 – Select the type of Actions
You will see that GitHub recommends Actions depending on the project. In our case, it is recommending actions suitable for a Java project. I have selected the “Java with Maven” option as my project is built in Maven.
Step 3 – Generation of Sample pipeline
If you choose an existing option, it will automatically generate a .yaml for the project as shown below.
We will replace the current workflow with the following yml file as shown below:
name: Rest API Tests using Rest Assured with TestNG
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
cache: maven
- name: Test Execution
run: mvn clean test
- name: Test Report Generation
uses: actions/upload-artifact@v4
if: success() || failure()
with:
name: TestNG Report # Name of the folder
path: target/surefire-reports/ # Path to test results
Step 4 – Commit the changes
After the changes, hit the “Start Commit” button.
This will give the option to add a description for the commit. It will also enable the user to commit either to the main branch or commit to any other branch that exists in the project. Click on the “Commit new file” button to set up the workflow file.
It will create a maven.yml file as shown below in the project.
Step 5 – Verify that the workflow is running
Next, head over to the “Actions” tab, and you will see your YAML workflow file present under the tab. The yellow sign represents that the job is in the queue.
In Progress – When the job starts building and running, you will see the status change from “Queued” to “in progress”.
Passed – If the build is successful, you will see a green tick mark.
Below is the execution log.
Click on the workflow and the below screen is displayed. It shows the status of the run of the workflow, the total time taken to run the workflow, and the name of the .yml file.
Below shows all the steps of the workflow.
Step 6 – Published TestNG Report on GitHub
From the logs of the Workflow, you can see that the Test Report step was executed successfully.
Once the pipeline run, a TestNG Report folder will be generated as shown in the below image:
When we click on the folder TestNG Report, a zipped file will be downloaded, and we can extract it to see all the files contained within it.
Maven is a powerful and widely used build automation and project management tool primarily used for Java projects. It simplifies the process of managing a software project by providing a standard way to build, manage dependencies, and generate documentation.
In the previous tutorial, we have discussed about How to install Maven on Windows. In this tutorial, we will see How To Create Selenium Maven Project in Eclipse IDE.
Prerequisite:
Maven Installed on machine
Java installed on machine
Integrated Development Environment (IDE) like IntelliJ IDEA or Eclipse is installed
Steps to follow:
Step 1 – To create a new project – Click on the New and then select – Project option.
Step 2 – Select the Maven Projectand click on the “Next” button.
Step 3 – You can select the default workplace or mention the location where you want to save the project.
Click the “Next“ button.
Step 4 – Select maven-archetype-quickstart option as shown below and click on the “Next” button.
Step 5 – Provide the Group Id, Artifact Id details and click the “Finish” button.
Group Id : com.example
Artifact Id : SeleniumMaven_Demo
Step 6 – The structure of the project looks as shown in the below image.
Step 7 – POM file will look like below image
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>SeleniumMaven_Demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SeleniumMaven_Demo</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
In the previous tutorial, I explained theSerenity BDD with Cucumber for Web Application using Junit4. In this tutorial, I will explain the same Test Framework using Serenity, Cucumber, and JUnit5. This tutorial gives a clear picture of the initial setup of a BDD Framework.
The JUnit Platform serves as a foundation for launching testing frameworks on the JVM. It also defines the TestEngine API for developing a testing framework that runs on the platform.
JUnit Jupiter is the combination of the new programming model and extension model for writing tests and extensions in JUnit 5. The Jupiter sub-project provides a TestEngine for running Jupiter based tests on the platform.
JUnit Vintage provides a TestEngine for running JUnit 3 and JUnit 4 based tests on the platform. It requires JUnit 4.12 or later to be present on the class/module path.
JUnit5 is not completely integrated with Serenity with Cucumber. So, it is advisable to usejupiter-vintage-engine for the Cucumber TestRunner classes.
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 and create a new Maven Project
Step 8 – Create a feature file under src/test/resources
The purpose of the Feature keyword is to provide a high-level description of a software feature, and to group related scenarios. To know more about the Feature file, please refer this tutorial.
Feature: Login to HRM
@ValidCredentials
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 successfully
@InValidCredentials
Scenario Outline: Login with invalid credentials
Given User is on Home page
When User enters username as '<username>'
And User enters password as '<password>'
Then User should be able to see error message '<errorMessage>'
Examples:
|username |password |errorMessage |
|admin |admin |Invalid credentials |
|abc |admin123 |Invalid credentials |
|abc |abc123 |Invalid credentials |
|1$£" | 45£"% |Invalid credentials |
@ForgetPassword
Scenario: Verify Forget Password Functionality
Given User is on Home page
When User clicks on Forgot your password link
Then User should be able to see new page which contains Reset Password button
Step 9 – Create junit-platform.properties file under src/test/resources (optional)
This is an optional step. Cucumber of version 6.7 and above provides the functionality to generate a beautiful cucumber report. For this, it is needed to add a file junit-platform.properties under src/test/resources.
cucumber.publish.enabled = true
Step 10 – Create the Step Definition class or Glue Code
A Step Definition is a Java method with an expression that links it to one or more Gherkin steps. When Cucumber executes a Gherkin step in a scenario, it will look for a matching step definition to execute. You can have all of your step definitions in one file, or in multiple files.
LoginPageDefinitions
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.example.SerenityCucumberJunit5Demo.steps.StepDashboardPage;
import com.example.SerenityCucumberJunit5Demo.steps.StepForgetPasswordPage;
import com.example.SerenityCucumberJunit5Demo.steps.StepLoginPage;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import net.serenitybdd.annotations.Steps;
public class LoginPageDefinitions {
@Steps
StepLoginPage loginPage;
@Steps
StepDashboardPage dashPage;
@Steps
StepForgetPasswordPage forgetpasswordPage;
@Given("User is on Home page")
public void openApplication() {
loginPage.open();
}
@When("User enters username as {string}")
public void enterUsername(String userName) {
loginPage.inputUserName(userName);
}
@When("User enters password as {string}")
public void enterPassword(String passWord) {
loginPage.inputPassword(passWord);
loginPage.clickLogin();
}
@Then("User should be able to login successfully")
public void clickOnLoginButton() {
dashPage.loginVerify();
}
@Then("User should be able to see error message {string}")
public void unsucessfulLogin(String expectedErrorMessage) {
String actualErrorMessage = loginPage.errorMessage();
System.out.println("Actual Error Message :" + actualErrorMessage);
assertEquals(expectedErrorMessage, actualErrorMessage);
}
@When("User clicks on Forgot your password link")
public void clickForgetPasswordLink() {
loginPage.clickForgetPasswordLink();
}
@Then("User should be able to see new page which contains Reset Password button")
public void verifyForgetPasswordPage() {
assertTrue(forgetpasswordPage.ForgetPasswordPage());
}
}
Assertions in JUnit-Vintage Engine are imported from the below package:-
import static org.junit.jupiter.api.Assertions.*;
DashboardPageDefinitions
import com.example.SerenityCucumberJunit5Demo.steps.StepDashboardPage;
import net.serenitybdd.annotations.Step;
import net.serenitybdd.annotations.Steps;
public class DashboardPageDefinitions {
@Steps
StepDashboardPage dashPage;
@Step
public void verifyAdminLogin() {
dashPage.loginVerify();
}
}
The corresponding Test Step classes are – StepLoginPage and StepDashboardPage.
There are multiple ways to identify a web element on the web page – one of the ways is to use @FindBy or $(By.).
I prefer to use @FindBy as I need not find the same element multiple times. Using @FindBy, I have identified a web element and defined a WebElementFacacde for the same which is reusable.
Cucumber runs the feature files via JUnit and needs a dedicated test runner class to actually run the feature files. When you run the tests with Serenity, you use theCucumberWithSerenity test runner. You also need to use the @CucumberOptionsclass to provide the root directory where the feature files can be found.
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
import org.junit.platform.suite.api.ConfigurationParameter;
import org.junit.platform.suite.api.IncludeEngines;
import org.junit.platform.suite.api.SelectClasspathResource;
import org.junit.platform.suite.api.Suite;
@Suite
@IncludeEngines("cucumber")
@SelectClasspathResource("/features")
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example.SerenityCucumberJunit5Demo.definitions")
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "io.cucumber.core.plugin.SerenityReporterParallel,pretty,timeline:build/test-results/timeline")
public class SerenityRunnerTest {
}
Step 12 – Create serenity.conf file under src/test/resources
The serenity configuration file is used to configure the drivers so the test cases can run successfully. This file contains an operating system-specific binary. The binary file sits between your test and the browser. It acts as an intermediary, an interface between your tests and the browser you are using.
You can also configure the webdriver.base.url property for different environments in the serenity.conf configuration file.
Step 13 – Create serenity.properties file at the root of the project
serenity.project.name = Serenity and Cucumber and JUnit5 Demo
Step 14 – Run the tests from Command Line
Open the command line and go to the location where pom.xml of the project is present and type the below command.
mvn clean verify
Step 15 – Test Execution Status
The image displayed above shows the execution status.
The feature file contains 3 test cases. Test Case 2 is a Test Scenario that has 4 examples. So, in total we have 6 tests. This information is clearly mentioned in the new version of Serenity.
Step 16 – Serenity Report Generation
The best part about Serenity is the report generation by it. The Reports contain all possible types of information, you can think of with minimal extra effort. There are multiple types of reports are generated. We are interested in index.html and serenity-summary.html. To know more about Serenity Reports, please refer to tutorials for Index.html and Serenity-Summary.html. Below is the new Serenity Report.
index.html
2. serenity-summary.html
Step 17 – Cucumber Report Generation (Optional)
Every Test Execution generates a Cucumber Report (Version 6.7.0) and above as shown in the image.
Copy the URL and paste it to a browser and it shows the report as shown below:
To know more about Cucumber Reports, refertothis tutorial.
We are done! Congratulations on making it through this tutorial and hope you found it useful! Happy Learning!!
In the previous tutorial, we got an introduction to Log4j 2. In this tutorial, we will create a Selenium project and implement logging using the Log4j2 YML configuration.
We’ve defined the level of the root logger as DEBUG. This means that we’ll get all the log events with level DEBUG and above. We’ve also defined a name for the appender as LogToConsoleand File.
We want to direct the logs to the console as well as File, we assigned the Appender typeas Console and File.
We specify the pattern in which we want to print the log messages.
Step 4 – Import log4j in the Selenium script
We need to import the log4j library in the Selenium script, so that we can use it in your code. Here is an example of how to import log4j in the Selenium script:
We need to create a Logger instance in the Selenium script so that we can use it to log information. Here is an example of how to create a Logger instance: