Monday, July 14, 2014

Constant Variables



Test data can be of two types, fixed or variable. If it is fixed, we can easily hard code the test data in to our test scripts. But sometimes the fixed test data is also used in so many scripts and if it gets changed then it is a huge task to update the entire effected test scripts for example the URL of your test application. It remains same but once you shifted to other environment, you need to change it in all of your test scripts. We can easily place the URL in Text file or Excel file outside our test scripts but Java gives us special feature of creating Constants variables which works exactly the same as Environment and Global variable in QTP.
1. Create a ‘New Package‘ file and name it as “utility“, by right click on the Project and select New > Package. 
    2. Create a ‘New Class‘file, by right click on the above created Package and select New > Class and name it as Constant. 
    3. Assign keywords in this class to your fixed data for e.g. Url, Username and Password.
package utility;
public class Constant {
    public static final String URL = "url of the application";
    public static final String Username = "testuser@gmail.com";
    public static final String Password = "Test@123";
}

Constants Variables are declared as public static, so that they can be called in any other methods without instantiate the class.
Constant Variables are declared as final, so that they cannot be changed during the execution.

4. SignIn_Action class will remain same

package appModule;
import org.openqa.selenium.WebDriver;
import pageObject.Login_Page;

public class SignIn_Action{
       // Pass Arguments (Username and Password) as string
    public static void Execute(WebDriver driver,String sUserName, String sPassword){
    Login_Page.txtbx_UserName(driver).sendKeys(sUserName);
    Login_Page.txtbx_Password(driver).sendKeys(sPassword);
    Login_Page.btn_Login(driver).click();
}
}
5. Create a New Class and name it as Global_Var_TC by right click on the automationFramework‘ Package and select New > Class. We will be creating all our test cases under this package. Now pass your Constant Variables (URL, Username and Password) as arguments to your Execute method of SignIn_Action class in your Global_Var_TC test case.
package automationFramework;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import pageObject.Home_Page;
import utility.Constant;
import appModule.SignIn_Action;

public class Global_var_TC {
       private static WebDriver driver = null;
       public static void main(String[] args) {
       driver = new FirefoxDriver();
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
       driver.get(Constant.URL);
       driver.manage().window().maximize();
       // Use your Module SignIn now
       SignIn_Action.Execute(driver,Constant.Username,Constant.Password);
       System.out.println(" Login Successfully.");
       Home_Page.lnk_LogOut(driver).click();
       driver.quit();
       }
}
You will notice that once you type ‘Constant’ and the moment you press dot, all the variables in the Constant class will be displayed. We can expose variables in order to reduce duplicated code. We are able to call these Constant variables multiple times. This will ensure a better maintainable test code, because we only have to make adjustments in one particular place.
When the test data is not fixed or if the same test script can be executed with the large amount of test data, we use external files for test data.

Thursday, July 3, 2014

Function Parameters

It is always a good practice to pass parameters when calling the method, rather than providing parameters inside the method. We can pass parameters through methods, just as in normal programming code. The code below will show us how we can login with parameterized username and password.
Steps to follow:
1. First let’s have a look over our previous example of SignIn_Action class.
package appModule;
import org.openqa.selenium.WebDriver;
import pageObject.Login_Page;

public class SignIn_Action{
    public static void Execute(WebDriver driver){
Login_Page.txtbx_UserName(driver).sendKeys("testuser@gmail.com");
Login_Page.txtbx_Password(driver).sendKeys("test@1234");
Login_Page.btn_Login(driver).click();
}
}
2. Modify the above Execute method of class SignIn_Action to accept string Arguments (Username & Password).
package appModule;
import org.openqa.selenium.WebDriver;
import pageObject.Login_Page;

public class SignIn_Action{
    public static void Execute(WebDriver driver, String sUserName, String sPassword){
Login_Page.txtbx_UserName(driver).sendKeys(sUserName);
Login_Page.txtbx_Password(driver).sendKeys(sPassword);
Login_Page.btn_Login(driver).click();
}
}
3. Create a New Class and name it as Param_TC by right click on the automationFramework Package and select New > Class. We will be creating all our test cases under this package. Now convert your old Module_TC in to the new passing parameters based test case.
package automationFramework;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import appModule.SignIn_Action;
import pageObject.Home_Page;
public class Param_TC {
       private static WebDriver driver = null;
       public static void main(String[] args) {
       driver = new FirefoxDriver();
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
       driver.get("Application URL");
       driver.manage().window().maximize();
       // Use your Module SignIn now
       SignIn_Action.Execute(driver,"testuser@gmail.com","test@123");
       System.out.println(" Login Successfully.");
       Home_Page.lnk_LogOut(driver).click();
       driver.quit();
       }
}
You see how easy it is to pass parameters to your methods. It increases your code readability.
Note: It is still not the best idea to hard-code your input anywhere in your test script, as it will still impact the bulk of your test scripts if there is any change in user data. I used this example just to give you an idea to how we use parameters in a method.

Wednesday, July 2, 2014

Modular Driven Framework

In most of the web application we have few set of actions which are always executed in the series of actions. Rather than writing those actions again and again in our test, we can club those actions in to a method and then calling that method in our test script. Modularity avoids duplication of code. In future if there is any change in the series of action, all you have to do is to make changes in your main modular method script. No test case will be impacted with the change.

Steps to follow:
Look for repeated functionality in your application for example the ‘login’ functionality. We can simple wrap this functionality in a method and we can give it a sensible name.

1. Create a ‘New Package‘ file and name it as appModule’, by right click on the Project and select New > Package. We will be creating different packages for Page Objects, Utilities, Test Data, Test Cases and Modular actions. It is always recommended to use this structure, as it is easy to understand, easy to use and easy to maintain.
2. Create ‘New Class‘ and name it as SignIn_Action by right click on package ‘appModule‘ and select New > Class. It will add new class ‘SignIn_Action’ under package ‘appModule’.
3. Now create a Public Static Void Method and name it as Execute and club the following steps in to it:
         Enter Username
         Enter Password
 Click on the Sign In button
This method will not have any Argument (driver) and Return value as it is a void method.

package appModule;
import org.openqa.selenium.WebDriver;
import pageObject.Login_Page;

public class SignIn_Action{
       public static void Execute(WebDriver driver){
Login_Page.txtbx_UserName(driver).sendKeys("testuser_1@gmail.com");
Login_Page.txtbx_Password(driver).sendKeys("Test@123");
Login_Page.btn_Login(driver).click();
}
}     
4.  Create a New Class and name it as Module_TC by right click on the ‘automationFramework‘package and select New > Class. We will be creating all our test cases under this package.
Now convert old PageObjectModel test case in to the new Module based test case.
package automationFramework;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import appModule.SignIn_Action;
import pageObject.Home_Page;
public class Module_TC {
       private static WebDriver driver = null;
       public static void main(String[] args) {
       driver = new FirefoxDriver();
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
       driver.get("ApplicationURL");

       // Use your module SignIn now
       SignIn_Action.Execute(driver);
       System.out.println(" Login Successfully.");
       Home_Page.lnk_LogOut(driver).click();
       driver.quit();
       }
}
We will notice that call to SignIn_Action will automatically execute all the steps mentioned under it.