Data Driven Framework | Creating The Project | Part 2

Data Driven Framework Tutorial

 

In this part of data driven framework tutorial, we will perform the following:

  1. Create a new Maven project and add necessary packages
  2. Adding the dependencies to pom.xml
  3. Create a parent or base class
  4. Using properties file to store application data (browser information, url, locator information, etc.)

To start with, we will be automating following tests in upcoming tutorials:

  • Our first test script will verify the login functionality. Please head over to the demo application and register with some dummy data.
  • The second test will validate the registration functionality.

Before jumping into the test scripts, let us create a maven project first.

 

Creating a Maven project

 

Open eclipse and choose File -> New -> Maven Project. A pop up will appear, choose skip archetype selection checkbox and click on next. On the following screen, enter the Group Id and Artifact Id as mentioned in the below screenshot.

 

Maven Project

 

Click on the Finish button and the maven project DataDrivenPattern should get created. Next, we will add the following packages to the project.

  • src/main/java
    • com.appliedselenium.base – This will contain the TestBase.java class
  • src/test/java
    • com.appliedselenium.listeners – This will contain the implementation of TestNG Listener.
    • com.appliedselenium.testscripts – All the test scripts will reside in this package.
    • com.appliedselenium.utilities – All the utility classes will be placed in this. ReadExcel.java class will also be inside this package.
  • src/test/resources
    • excelData – contains the excel sheet containing the user registration data.
    • executables – driver executables for browsers (chromedriver, geckodriver, etc.). Download and store the compatible version of chromedriver.exe in this path.
  • logs – After implementing the log4j, following 2 log files will be generated in this package:
    • application.log – It captures the user-defined logs from the application under test.
    • selenium.log – It captures the logs generated by selenium while executing the test scripts.
  • properties – This package contains the following 2 .properties files:
    • config.properties – contains the configuration related data. For eg. application url, browser name, etc.
    • or.properties – contains locator values

The basic framework skeleton after creating the above packages will look like:

 

Data Driven Framework Design

 

 

Creating pom.xml

 

The pom.xml contains all the dependencies that we are going to use in our project. Copy and paste below code into pom.xml file:

 

<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.appliedselenium</groupId>
    <artifactId>DataDrivenPattern</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <dependencies>

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

        <!-- https://mvnrepository.com/artifact/com.aventstack/extentreports -->
        <dependency>
            <groupId>com.aventstack</groupId>
            <artifactId>extentreports</artifactId>
            <version>4.0.9</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>


        <!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>javax.mail-api</artifactId>
            <version>1.6.2</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>


        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-scratchpad</artifactId>
            <version>3.17</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>openxml4j</artifactId>
            <version>1.0-beta</version>
        </dependency>

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

        </dependency>


        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>



    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <testFailureIgnore>false</testFailureIgnore>
                    <suiteXmlFiles>
                        <suiteXmlFile>src/test/resources/testNG/testng.xml
                        </suiteXmlFile>
                    </suiteXmlFiles>
                </configuration>

            </plugin>
        </plugins>
    </build>

</project>

 

Apart from the dependencies, we have also added a plugin for surefire. This is used to execute the test scripts using maven(more on it in the upcoming tutorial). Note that surefire plugin has the path to testng.xml, which we have not created yet but will create in the next tutorials.

Click on the Save button and eclipse should download all the required jars. 

 

Creating .properties files

 

As mentioned above, our data driven framework will have 2 .properties files. To create the file, select properties folder -> right click -> New -> File and enter config.properties.

 

 

config.properties

 

Similarly, create another file or.properties inside properties folder.

 

config.properties

 

This properties file contain the following configuration, assuming that the credentials are admin1 for username and password:

 

browser=chrome
url=https://parabank.parasoft.com/parabank/index.htm
implicit_wait=100
user_name=admin1
password=admin1

 

 

or.properties

 

This file contains the locator values of the application under test. We will focus on the first test case for now, which is to test the successful login (Please register first and create your test login account). Hence this file will contain locator values of the following fields (highlighted in red).

 

 

Below are the locator values of these 2 fields in terms of xpath, you may use any technique to extract the locator value. Since I am using xpath, hence I have suffixed _XPATH at the end of each locator variable. If you are using any other method like id, cssSelector, etc. then please suffix the variable accordingly. We will see the benefit of using this suffix in the upcoming tutorial.

 

#Login Page
username_XPATH=//input[@class='input'][@name='username']
passwd_XPATH=//input[@class='input'][@name='password']
loginBtn_XPATH=//input[@class='button'][@type='submit']

 

 

Base class in Data Driven Framework

 

The base class is considered as the parent class of all other classes, as it is extended by almost all other classes of the project including test classes. The execution is kicked-off with this class. Our base class will have the following features (we will add more to it as we progress in the tutorial):

  • Initialization of WebDriver (ChromeDriver, GeckoDriver, etc.)
  • Implementation of log4j logger
  • Instantiating the .properties files, ReadExcel utility class, and Extent report class objects
  • TestNG annotations to start and terminate the test suite automation
  • Opening the browser and navigating to the application under test
  • Generic methods, etc.

Following is the code for base class. The name of the base class is TestBase.

 

package com.appliedselenium.base;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;

public class TestBase {

    //initialize the WebDriver interface reference variable
    public static WebDriver driver;

    // Create instance of Properties class to refer the .properties file
    public static Properties or = new Properties();
    public static Properties config = new Properties();

    // Create filestream class object to load the file
    public static FileInputStream fis;

    // First method to be called before automation suite is executed 
    @BeforeSuite
    public void setUp() {
        
        //check if driver reference variable is null, i.e. no browser is opened through selenium yet
        if (driver == null) {

            //get the reference of or.properties file
            try {
            
                fis = new FileInputStream(
                        System.getProperty("user.dir") + "\\src\\test\\resources\\properties\\or.properties");
            } catch (FileNotFoundException e) {
                
                e.printStackTrace();
            }
            
            //load the file into memory
            try {
                or.load(fis);

            } catch (IOException e) {
                
                e.printStackTrace();
            }

            //get the reference of config.properties file
            try {
                fis = new FileInputStream(
                        System.getProperty("user.dir") + "\\src\\test\\resources\\properties\\config.properties");
            } catch (FileNotFoundException e) {
                
                e.printStackTrace();
            }
            
            //load the file into memory
            try {
                config.load(fis);
            } catch (IOException e) {
                
                e.printStackTrace();
            }

            // invoke the browser mentioned in config.prop and assign it to driver reference variable
            if (config.getProperty("browser").equals("chrome")) {
                System.setProperty("webdriver.chrome.driver",
                        System.getProperty("user.dir") + "\\src\\test\\resources\\executables\\chromedriver.exe");
                driver = new ChromeDriver();
            }

            //open the url and assign an implicit wait (as configured in config.properties)
            driver.get(config.getProperty("url"));
            driver.manage().window().maximize();
            driver.manage().timeouts().implicitlyWait(Integer.parseInt(config.getProperty("implicit_wait")),
                    TimeUnit.SECONDS);
        }

    }

    // Mehod called after all the tests are executed
    @AfterSuite
    public void tearDown() {
        System.out.println("Closing the browser");
        driver.quit();

    }

}

 

Following is the explanation of the above code:

  • Initialize the WebDriver interface reference variable. WebDriver is an interface and it is implemented in ChromeDriver, GeckoDriver, etc. We cannot create an object of an interface but we can create a reference variable and point it to the class which implements the interface. In this case, driver reference variable points to the ChromeDriver class.
  • Create instances of config and or .properties files.
  • Create an instance of FileInputStream class which is used to load the 2 .properties files into memory.
  • @BeforeSuite annotation – This is a TestNG annotation that is used to indicate the method defined under this annotation must be executed before the automation suite is executed. This is where the execution of test scripts start.
  • @AfterSuite annotation – This TestNG annotation is executed after everything inside @BeforeSuite annotation gets executed. This is generally used in clean up tasks, for eg. clearing cookies, closing any open file instances, closing the browser, etc.

In the next tutorial, we will learn how to execute the TestBase class using TestNG and create our first test.

 

Author: Dhawal Joshi

A post-graduate in MCA, ISTQB & ITIL certified QA with more than 8 years of experience in QA working with a CMMI Level 5 organization as System Analyst. I started my automation journey with HP UFT(formerly known as QTP) and for the past few years, I am using Selenium for automation. I also have experience in Android Application Development, Java, HTML, and VBScript. When I am not working, I like to spend time with my family, cooking and learning new developments in IT.

Leave a Reply

Your email address will not be published. Required fields are marked *