How To Create Gradle Project With Selenium

By Sruthy

By Sruthy

Sruthy, with her 10+ years of experience, is a dynamic professional who seamlessly blends her creative soul with technical prowess. With a Technical Degree in Graphics Design and Communications and a Bachelor’s Degree in Electronics and Communication, she brings a unique combination of artistic flair…

Learn about our editorial policies.
Updated March 7, 2024

This Tutorial Explains how to Create the Gradle Project with Selenium, Writing Test Scenarios in Gherkin Syntax and Running Tests using Cucumber JVM:

In this article, we will explain about Selenium and how we can set up a Gradle project with Selenium. Contrary to the general belief, Selenium is one of the popular browser automation tools. Selenium WebDriver is an advanced version of Selenium RC, and it helps in automating tests for web applications.

Most of the DevOps teams use Gradle and define various customized tasks to run Selenium automation tests, as part of their Continuous Delivery pipeline. Therefore, in this article, we will cover the concepts of writing test scenarios (specifications) in Gherkin syntax, implementing those scenarios in Selenium Java, and running the tests using Cucumber JVM.

Finally, we will see examples of Gradle tasks to run tests. Then we can invoke these tasks from the command line or a terminal.

Create The Gradle Project With Selenium

Create The Gradle Project

Prerequisites

We have already outlined the steps to install JDK and to configure it with IntelliJIDEA in our How To Use Gradle post where we learned about Gradle and how we use it to build, test, and publish a Java project. Therefore, we do not cover those concepts here.

Now let us download the corresponding repository from Github for a better understanding of this article.

Step #1: Open IntelliJIDEA

If IntelliJIDEA opens a default project, then close the Project and click on the launch icon again.

IntelliJIDEA_Welcome_Screen

Step #2: Give the Github repository path in the URL text box and Download the repository.

Github repository path in the URL text box

Click on Yes on the popup, when we get a prompt on checking out the build.gradle.

Checkout_Prompt

We need to wait for few seconds for the IntelliJ IDEA to clone the repository on the local machine. Alternatively, we can download the zip file.

As we are testing a web application, we need to install a browser and the corresponding WebDriver binary.

Install Chrome as per the Operating System that you are using and check the version of the Chrome browser.

Chrome_version

Download the Chromdriver binary corresponding to the version of the Chrome browser on the local machine. In this article, we are using Windows. Therefore, we have downloaded chromedriver.exe. Keep chromedriver.exe under src/test/resources folder and note down the path.

chome_driver_path

Now, we need to check that our sample web application is working. Let us check if the forgot password link is working by opening it in the Browser.

sample_Application_Web

Setup Gradle Project With Cucumber JVM And Selenium

Now, we need Java bindings of Selenium and Cucumber JVM to run our tests.

So, let us configure them as outlined in the below steps:

Step #1: Open Gradle build file called build.gradle.

Step #2: Mention the dependencies outlined below.

dependencies {
    //testCompile group: 'junit', name: 'junit', version: '4.12'
    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java',
            version: '3.141.59'
    // https://mvnrepository.com/artifact/io.cucumber/cucumber-java
    compile group: 'io.cucumber', name: 'cucumber-java', version: '5.6.0'
    // https://mvnrepository.com/artifact/io.cucumber/cucumber-junit
    testCompile group: 'io.cucumber', name: 'cucumber-junit', version: '5.6.0'
    // https://mvnrepository.com/artifact/org.hamcrest/hamcrest
    testCompile group: 'org.hamcrest', name: 'hamcrest', version: '2.2'
}	

Import the changes in build.gradle, when prompted by IntelliJ IDEA. Ensure that the specified dependencies have been downloaded and added to the references.

We need to check external libraries in project explorer.

dependencies_project_explorer

We are done with all the pre-requisites and set up for us to move ahead and write a BDD test scenario, following Gherkin syntax.

Write BDD Test Scenarios

Let us go ahead and create a feature file with two example scenarios. Create a folder called features and a file called forgotpassword.feature” and write the Scenarios as given below:

@forgotpassword
Feature: Forgot password 

 Scenario: A valid email id is allowed
    Given Navigate to Page ForgotPassword
    When A User enters a valid email id
    And A User clicks on Retrieve password button
    Then Application shows that the email has been sent.  

Scenario: An invalid email is not allowed
    Given Navigate to Page ForgotPassword
    When A User enters a invalid email id
    And A User clicks on Retrieve password button
    Then Application does not show that email has been sent.
  
  # TODO - the below step is not be implemented because feature is still not available
    # And Application shows an error message "Invalid Email"

We need not write it as this file is already given in the sample project.

Implement BDD Specifications In Java

Let us implement these scenarios in Selenium.

Recommended Reading=> Selenium Tutorial

Create a Java class, TestSteps.java, in a package theinternet under src/test/java.

TestSteps_Class

Please look at the code in the example project. We need to specify the path to the chromedriver.exe correctly.

package theinternet;

import io.cucumber.java.After;
import io.cucumber.java.Before;
import io.cucumber.java.en.And;
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.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.nio.file.Paths;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class ForgotPassword{
    private WebDriver driver;    

    @Before
    public void setUp() {       
              System.setProperty("webdriver.chrome.driver",
Paths.get("src/test/resources/chromedriver_win32/chromedriver.exe").toString());        
             if (driver == null) {
                   driver = new ChromeDriver();
             }
       }    
    @After
    public void tearDown() {
        if (driver!=null) {
            driver.close();
            driver.quit();
        }
    }    

    @Given("Navigate to Page ForgotPassword")
    public void navigateToPageForgotPassword() {
        driver.navigate().to("https://the-internet.herokuapp.com/forgot_password");
    }   

   @When("A User enters a valid email id")
    public void aUserEntersAValidEmailId() {
        driver.findElement(By.name("email")).sendKeys("valid@example.com");
    }   

    @And("A User clicks on Retrieve password button")
    public void aUserClicksOnRetrievePasswordButton() {
        driver.findElement(By.id("form_submit")).click();
    }    

    @When("A User enters a invalid email id")
    public void aUserEntersAInvalidEmailId() {
        driver.findElement(By.name("email")).sendKeys("invalid@");
    }    

    @Then("Application shows that the email has been sent.")
    public void applicationShowsThatTheEmailHasBeenSent() {
        String actualMessage = driver.findElement(By.id("content")).getText();
        assertThat(actualMessage.trim(), is("Your e-mail's been sent!"));
    }   

    @Then("Application does not show that email has been sent.")
    public void applicationDoesNotShowThatEmailHasBeenSent() {
        String actualMessage = driver.findElement(By.id("content")).getText();
        assertThat(actualMessage.trim(), not("Your e-mail's been sent!"));
    }

}

Run Cucumber Tests Using Gradle

Now let us create a Java Class called RunTests.java under src/test/java.

We need to mention CucumberOptions, as outlined below:

Runtests_Class

Let us look at the Java code of the RunTests Java Class.

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

import io.cucumber.junit.CucumberOptions;

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/resources/features",
        glue = {"theinternet"},
        tags = {"@forgotpassword"},
        plugin = {
                "pretty",
                "json:build/cucumber-report/cucumber.json",
                "html:build/cucumber-report/cucumber.html",
                "junit:build/cucumber-report/cucumber.xml"}
)
public class RunTests {
}

Ensure that we have saved all the created files.

Please check that all the files are present as per the list and path as given below:

all_files_project_explorer

We can run the created Selenium tests using Gradle’s build as well as test tasks. We can run the tests from the IDE as well as from the command line.

In the IDE, open RunTests Class and click on the Green play icon.

Green_Play_Icon

We can also open the Command line at the project’s root path and use the command as given below.

D:\softwaretestinghelp\gradle_selenium>.\gradlew.bat test --tests RunTests

Please check the test that is failing. After running the tests, we can extract the Gradle reports using its export icon in the run panel of the IntelliJ IDEA.

export_results

Html reports from the Gradle export feature are displayed below:

Html reports

How To Run Cucumber Tests In Parallel?

In real-time projects, we run the tests in parallel to save time in the test execution phase of the STLC ( Software Test Life Cycle). Therefore, let us update the project to make it suitable for running tests in parallel.

Let us create a new features file, with name statuscodes.feaure, and create a Scenario Outline with three examples for the features of the application at Status Codes.

@statuscodes
Feature: HTTP status codes
  Scenario Outline: Check the status HTTP status codes
   Given A User Navigates to StatusCodes Page
   When A User Clicks on status Code <strong><</strong>input<strong>></strong>
   Then Application displays the message <strong><</strong>outputCode<strong>></strong>
   Examples:
<strong>     | </strong><em>input </em><strong>| </strong><em>outputCode </em><strong>|</strong>
<strong>     |</strong> 200  | 200       |
     | 301   | 301        |
     | 404  | 404   <strong>    |
</strong>

Now, let us update the TestSteps Class under theinternet package with the below-given step implementations in Java.

@Given("A User Navigates to StatusCodes Page")
public void aUserNavigatesToStatusCodesPage() {
   driver.navigate().to("https://the-internet.herokuapp.com/status_codes");
}

@When("A User Clicks on status Code {int}")
public void aUserClicksOnStatusCodeInput(Integer inputCode) {
   driver.findElement(By.partialLinkText(inputCode.toString())).click();
}

@Then("Application displays the message {int}")
public void applicationDisplaysTheMessageOutputCode(Integer outputCode) {
   String expectedMessage = "This page returned a "+outputCode.toString()+" status code.";
   String actualMessage = driver.findElement(By.cssSelector("h3 + p")).getText();  


 assertThat(actualMessage, containsString(expectedMessage));
}

Please look at the full file contents in the sample project, downloaded from Github.

Open build.gradle file and add Courgette-JVM under dependencies. Courgette-JVM makes it possible to run cucumber tests in parallel. Mention it under dependencies and import the changes in build.gradle file.

// https://mvnrepository.com/artifact/io.github.prashant-ramcharan/courgette-jvm
compile group: 'io.github.prashant-ramcharan', name: 'courgette-jvm', version: '4.6.2'

The dependencies block in the Gradle build needs to be as shown below.

dependencies {	
    //testCompile group: 'junit', name: 'junit', version: '4.12'
    // https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java',
            version: '3.141.59'
    // https://mvnrepository.com/artifact/io.cucumber/cucumber-java
    compile group: 'io.cucumber', name: 'cucumber-java', version: '5.6.0'
    // https://mvnrepository.com/artifact/io.cucumber/cucumber-junit
    testCompile group: 'io.cucumber', name: 'cucumber-junit', version: '5.6.0'   
 
    // https://mvnrepository.com/artifact/org.hamcrest/hamcrest
    testCompile group: 'org.hamcrest', name: 'hamcrest', version: '2.2'   
    // https://mvnrepository.com/artifact/io.github.prashant-ramcharan/courgette-jvm
    compile group: 'io.github.prashant-ramcharan', name: 'courgette-jvm', version: '4.6.2'
}

Check whether Courgette-JVM has been downloaded and accessible under the external libraries section. We can check that in the project explorer of the IDE, as shown in the below image.

Check whether Courgette-JVM has been downloaded

Create a Java Class similar to RunTests.java with the code given below and save it with the name RunParallelTests.java at src/test/java. We need to copy the code as shown below and paste that into the file.

import courgette.api.CourgetteOptions;
import courgette.api.CourgetteRunLevel;
import courgette.api.junit.Courgette;
import courgette.api.CucumberOptions;
import org.junit.runner.RunWith;

@RunWith(Courgette.class)
@CourgetteOptions(
       threads = 10,
       runLevel = CourgetteRunLevel.FEATURE,
       showTestOutput = true,
       reportTargetDir = "build/parallel",
       cucumberOptions = @CucumberOptions(
               features = "src/test/resources/features",
               glue = "theinternet",
               tags = {"@statuscodes or @forgotpassword"},
               plugin = {
                       "pretty",
                       "json:build/cucumber-report/cucumber.json",
                       "html:build/cucumber-report/cucumber.html",
                       "junit:build/cucumber-report/cucumber.xml"}
       )
)
public class RunParallelTests {
}

We use Courgette JVM’s API to define its options, similar to Cucumber JVM. Please notice the CucumberOptions annotation inside CourgetteOptions. We have kept all parameters the same as earlier other than parameter called tags. Now we have included the new feature too.

Important here is to notice that Courgette JVM has a parameter called runLevel. We can use runLevel to run the tests on either a Scenario or a Feature level.

Feature Level

Let us first run our tests in parallel on the Feature level. Once we start running the tests, we should be able to notice that tests of both the Features are running in 02 separate browser instances.

Use the below-given command from the project’s root directory to run tests using Gradle. However, we can use the IDE too to run these tests.

D:\softwaretestinghelp\gradle_selenium>.\gradlew.bat test --tests RunParallelTests

Notice the reports folder, as stated in the configurations of Courgette-JVM. Please check the reports under build/parallel directory.

CourgetteJVM_reports

Scenario Level

Once we run the parallel tests on the Scenario level, Courgette-JVM runs all the scenarios in our feature files in parallel in separate browser instances. Update CourgetteOptions as shown below in RunParallelTests.java

runLevel = CourgetteRunLevel.SCENARIO,

Again use the below-given command from the project’s root directory to run tests using Gradle.

D:\softwaretestinghelp\gradle_selenium>.\gradlew.bat test --tests RunParallelTests

Check the reports under the build/parallel directory and notice the time difference.

CourgetteJVM_reports_scenario_level

Note that the time taken by these tests to run and complete is dependent on the memory configuration present on the target machine.

Conclusion

We have explained the steps to create and run a Gradle project with Selenium. We have taken very simple to understand examples, in this article. We have also provided the source code for the example project under the MIT license. You can download it from here.

We have also covered the concepts on running Selenium tests using Courgette JVM in parallel both at the scenario and feature level.

Was this helpful?

Thanks for your feedback!

Leave a Comment