Saturday 23 July 2016

Page Object Model in Selenium


Simple Page Object Model with example


In this example we will see a very simple Page Object Model example. To explain we have taken Google application and created Base Page, Sign In page and Create Account page.

Page Object Model Introduction

Page Object Model Framework has now a days become very popular test automation framework in the industry and many companies are using it because of its easy test maintenance and reduces the duplication of code.
The main advantage of Page Object Model is that if the UI changes for any page, it don’t require us to change any tests, we just need to change only the code within the page objects (Only at one place). Many other tools which are using selenium, are following the page object model.

In the above screen shot, we have first identified the locators and defined it on the top after the class. In this way we can achieve readability of test scripts and we can easily identify locators and change them if needed at only one place.
Page Object model is writing all the functionalities / reusable components of a page that we want to automate in a separate class. Say now if we consider four pages as Home page, Login page, Create Account and Forgot password page etc.

As per Google Wiki Page Object
"Within your web app’s UI there are areas that your tests interact with. A Page Object simply models these as objects within the test code. This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place."

For the above pages we will create classes as HomePage.class, LoginPage.class, CreateAccountPage.class and ForgotPasswordPage.class. In each class we will identify and write reusable methods which are specific to a page.

Here in The first page 'google home page' which will have many options like Search, Sign In, +You, Images, privacy etc links. based on the user action it navigates to respective page. Now all functionalities that we want to automate should have reusable methods/components for each page.

Now as our main page is google page we can navigate to other pages by clicking on any link from the google page. When ever we are navigating to other page, we need to return that page object. Else Return the current page object as this action doesn't navigate to a other page represented by another Page Object

The Page Object model provides the following advantages.

1. There is clean separation between test code and page specific code such as locators (or their use if you’re using a UI map) and layout.
2. There is single repository for the services or operations offered by the page rather than having these services scattered through out the tests.

In both cases this allows any modifications required due to UI changes to all be made in one place. Useful information on this technique can be found on numerous blogs as this ‘test design pattern’ is becoming widely used. We encourage the reader who wishes to know more to search the internet for blogs on this subject. Many have written on this design pattern and can provide useful tips beyond the scope of this user guide. To get you started, though, we’ll illustrate page objects with a simple example.

Example: Lets us take a simple login example: /***
* Tests login functionality
*/
public void loginTestCase() {
driver.navigate().to(URL);
driver.findElement(By.name("signIn")).click();
driver.findElement(By.id("username")).sendKeys("testuser");
driver.findElement(By.id("password")).sendKeys("testpassword");
driver.findElement(By.name("loginbtn")).click();

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("profile")));
String Expected=driver.findElement(By.id("message")).getText();
Assert.assertEquals(Expected, "Welcome");


}

If you observe the above test, there is no separation of test and test locators. If this is the case, in future if the UI changes, it must be changed in multiple places. It will also become difficult to identify where these locators are used as the chances of locators are being used in multiple tests are more.

We will try to rewrite the above example by implementing the page object model:/***
* Tests login functionality
*/
public void loginTestCase() {
// To go to home page
homePage.gotoHomePage();
//To click on SignIn link
accountLoginPage = homePage.clickOnSignIn()
//To verify if user is navigated to sign-in page
Assert.assertTrue(accountLoginPage.verifyPage());
//Login to the account
accountLoginPage.userLogin(username,password);
//To verify if user is navigated to user home page after successfull login
Assert.assertTrue(userHomePage.verifyPage());
}

In the above test, we have not used any locators. It is completely separated by driver.findElement 's, waits, exceptions and no static values in the code etc.We will be working only with the methods which are defined in multiple pages. Based on test, we will navigate to the required page and access those page methods.

Simple Page Object Model Framework example

Steps to Create a Simple Page Object Model. The structure of the sample project should look like in the screen shot below



Step 1: Create the Test Setup class

This the main class for page object model, where we will create Webdriver object based on the browser type passed as a parameter in textng.xml file. We will also need to pass the base page application URL in testng.xml as parameter.

In this example we have taken only two browsers the default Firefox and chrome browser. To initiate Chrome browser, we need to set the System Property by providing the chromedriver exe path.
We need to create a method to return Webdriver 'driver' where this is used for test execution.
Below is the example TestBaseSetup.class file

package com.pack.base;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;

public class TestBaseSetup {

private WebDriver driver;
static String driverPath = "D:\\chromedriver\";
public WebDriver getDriver()
{
        return driver;

}

private void setDriver(String browserType, String appURL)
{
   switch (browserType) {
case "chrome":
driver = initChromeDriver(appURL);
break;
case "firefox":
driver = initFirefoxDriver(appURL);
break;
default:
System.out.println("browser : " + browserType
+ " is invalid, Launching Firefox as browser of choice..");

driver = initFirefoxDriver(appURL);

}

}

private static WebDriver initChromeDriver(String appURL) {
System.out.println("Launching google chrome with new profile..");
System.setProperty("webdriver.chrome.driver", driverPath
+ "chromedriver.exe");

WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.navigate().to(appURL);

return driver;

}

private static WebDriver initFirefoxDriver(String appURL) {
System.out.println("Launching Firefox browser..");
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.navigate().to(appURL);
return driver;

}

@Parameters({ "browserType", "appURL" })
@BeforeClass

public void initializeTestBaseSetup(String browserType, String appURL) {
try {

setDriver(browserType, appURL);

} catch (Exception e) {
System.out.println("Error....." + e.getStackTrace());

}

}



@AfterClass
public void tearDown() {
driver.quit();
}

}

Step 2: Now We will create Page Object classes. For each page we will create a separate class with constructor. We identify the locators and keep all together on just below the class. This will help us to re-use the locators for multiple methods and the main important is, we can easily find the locator and change if required.

We need to identify and list of all the possible functionalities on this page and we should write methods in such a way they are re-used. When ever there is a method to click on a button or link, we should return driver object of that page.

We will look into the below example. For method SignInBtn, we are returning after clicking on Sign In button as it is redirecting to sign in page.

BasePage.class

package come.pack.common.pageobjects;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class BasePage {

protected WebDriver driver;
private By signInButton = By.linkText("Sign in");

public BasePage(WebDriver driver) {
this.driver = driver;

}

public SignInPage clickSignInBtn() {
System.out.println("clicking on sign in button");
WebElement signInBtnElement=driver.findElement(signInButton);
if(signInBtnElement.isDisplayed()||signInBtnElement.isEnabled())
signInBtnElement.click();
else System.out.println("Element not found");
return new SignInPage(driver);

}

public void clickImagesLink() {
//It should have a logic to click on images link
//And it should navigate to google images page

}
public String getPageTitle(){

String title = driver.getTitle();

return title;

}

public boolean verifyBasePageTitle() {

String expectedPageTitle="Google";

return getPageTitle().contains(expectedPageTitle);

}


}

In the below SignInpage.class, we have methods to click on create account and sign in button. We are just verifying an error in sign in page for now in this example.

SignInPage.class

package come.pack.common.pageobjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement

public class SignInPage {
private WebDriver driver;
private By headerPageText = By.cssSelector(".hidden-small");
private By createAccountLink = By.id("link-signup");
private By emailTextBox = By.id("Email");
private By passwordTextBox = By.id("Passwd");
private By loginBtn = By.id("signIn");
private By errorMsgTxt = By.id("errormsg_0_Passwd");

public SignInPage(WebDriver driver) {
this.driver=driver;

}

public String getSignInPageTitle() {
String pageTitle = driver.getTitle();
return pageTitle;
}

public boolean verifySignInPageTitle() {
String expectedTitle = "Sign in - Google Accounts";
return getSignInPageTitle().contains(expectedTitle);

}

public boolean verifySignInPageText() {
WebElement element = driver.findElement(headerPageText);
String pageText = element.getText();
String expectedPageText = "Sign in with your Google Account";
return pageText.contains(expectedPageText);

}

public CreateAccountPage clickonCreateAnAccount() {
WebElement element=driver.findElement(createAccountLink);
if(element.isDisplayed()||element.isEnabled())
element.click();
return new CreateAccountPage(driver);

}
public boolean verifySignIn() {
enterUserName("test");
enterPassword("pass");
clickOnSignIn();

return getErrorMessage().contains("incorrect");

}

public void enterUserName(String userName) {

WebElement emailTxtBox = driver.findElement(emailTextBox);

if(emailTxtBox.isDisplayed())

emailTxtBox.sendKeys(userName);

}



public void enterPassword(String password) {

WebElement passwordTxtBox = driver.findElement(passwordTextBox);

if(passwordTxtBox.isDisplayed())

passwordTxtBox.sendKeys(password);

}

public void clickOnSignIn() {

WebElement signInBtn = driver.findElement(loginBtn);

if(signInBtn.isDisplayed())

signInBtn.click();

}


public String getErrorMessage() {

String strErrorMsg = null;

WebElement errorMsg = driver.findElement(errorMsgTxt);

if(errorMsg.isDisplayed()&&errorMsg.isEnabled())

strErrorMsg = errorMsg.getText();

return strErrorMsg;

}

}


CreateAccountPage.class

package come.pack.common.pageobjects;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;


public class CreateAccountPage {

private WebDriver driver;

private By headerPageTxt = By.cssSelector(".signuponepage.main.content.clearfix>h1");

public CreateAccountPage(WebDriver driver) {

this.driver=driver;

}

public String getPageTitle() {

String title = driver.getTitle();

return title;

}

public boolean verifyPageTitle() {

String pageTitle = "Create your Google Account";

return getPageTitle().contains(pageTitle);

}

public boolean verifyCreateAccountPageText() {

WebElement element = driver.findElement(headerPageTxt);

String pageText ="Create your Google Account";

return element.getText().contains(pageText);

}

public void createAccount() {

//need to write steps for creating an account

}



}

Step 3: Now we will see how to write Tests for the above pages. For all the page Objects, we will now create Tests for each page. Which will help us in easy maintainability. if there is any change in the UI, we can simply change in one Page one place. We will see first example test for "BasePageTest.class".

In the below example we verifying home page by taking the title. We have written a method in BasePage and we are just calling it here.

'package com.pack.common.tests;

import org.openqa.selenium.WebDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.pack.base.TestBaseSetup;
import come.pack.common.pageobjects.BasePage;

public class BasePageTest extends TestBaseSetup{

private WebDriver driver;

@BeforeClass
public void setUp() {
driver=getDriver();

}


@Test

public void verifyHomePage() {

System.out.println("Home page test...");

BasePage basePage = new BasePage(driver);

Assert.assertTrue(basePage.verifyBasePageTitle(), "Home page title doesn't match");

}


}


We will look into the next test 'SignInPageTest'. In the below test, we are verifying page title, page text, and Sign in functionality. For all these verifications we have defined methods in SignInPage class which we are calling from tests.

package com.pack.common.tests;
import org.openqa.selenium.WebDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.pack.base.TestBaseSetup;
import come.pack.common.pageobjects.BasePage;
import come.pack.common.pageobjects.SignInPage;
public class SignInPageTest extends TestBaseSetup{
private WebDriver driver;
private SignInPage signInPage;
private BasePage basePage;

@BeforeClass
public void setUp() {

driver=getDriver();

}

@Test

public void verifySignInFunction() {

System.out.println("Sign In functionality details...");

basePage = new BasePage(driver);

signInPage = basePage.clickSignInBtn();

Assert.assertTrue(signInPage.verifySignInPageTitle(), "Sign In page title doesn't match");

Assert.assertTrue(signInPage.verifySignInPageText(), "Page text not matching");

Assert.assertTrue(signInPage.verifySignIn(), "Unable to sign in");

}


}

Now the create test 'CreateAnAccountTest'. Now we should be able to understand the verification that we are doing in the below test.

package com.pack.common.tests;

import org.openqa.selenium.WebDriver;

import org.testng.Assert;

import org.testng.annotations.BeforeClass;

import org.testng.annotations.Test;
import com.pack.base.TestBaseSetup;
import come.pack.common.pageobjects.BasePage;

import come.pack.common.pageobjects.CreateAccountPage;

import come.pack.common.pageobjects.SignInPage;

public class CreateAnAccounTest extends TestBaseSetup {

private WebDriver driver;

private SignInPage signInPage;

private BasePage basePage;

private CreateAccountPage createAccountPage;



@BeforeClass

public void setUp() {

driver=getDriver();

}



@Test

public void verifyCreateAnAccounPage() {

System.out.println("Create An Account page test...");

basePage = new BasePage(driver);

signInPage = basePage.clickSignInBtn();

createAccountPage = signInPage.clickonCreateAnAccount();

Assert.assertTrue(createAccountPage.verifyPageTitle(), "Page title not matching");

Assert.assertTrue(createAccountPage.verifyCreateAccountPageText(), "Page text not matching");

}
public void verifySignInFunction() {

}

}


Step 4: We are done with Base Setup, Page Objects creation, Tests creation. Now we will execute them using 'testng.xml' file. We will add the classes which we want to test.


Remember we need to pass the parameters 'browserType' and 'appURL' for the base Setup class.


<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="Page Object test example">

<parameter name="appURL" value="https://www.google.co.in/"/>

<parameter name="browserType" value="firefox"/>

<test name="sample test">

<classes>

<class name="com.pack.common.tests.HomePageTest"/>

<class name="com.pack.common.tests.SignInPageTest"/>

<class name="com.pack.common.tests.CreateAnAccounTest"/>

</classes>

</test>

</suite>


The above Page Object Model framework is the simple one without using any Build tools, Loggers, Listeners and Utilities. In the next coming post we will add all these things and design a Robust Page Object Model Framework which are used in the Industry.


The below are the list of things which are commonly used in the Real time Page Object Model Framework.

1. Selenium Webdriver with Java

2. Maven Build Tool

3. TestNG (We will user TestNG Listeners also)

4. Log4j

5. Eclipse IDE






Saturday 11 June 2016

Latest Tools used in Automation Testing



Many websites/web applications suffer from bugs due to its improper functionality, behaviour, usability, security, etc. For those websites/web applications, web testing tools do magic (these Testing tools take out all bugs from websites/web applications in limited time period and limited cost). Determining and fixing a bug, drafting a bug sheet, and determining priority and severity is hard during development phase of websites. Most of the bugs come due to functional issue of the website/web application. So, to come out of functional issues, we have tried to provide some web functional/regression testing tools.

1) Calabash: 
Automated Acceptance Testing for iOS and Android Apps (Both Android and iOS)

2) Frank:

3) MonkeyTalk:
Mobile App Testing Tool (Both Android and iOS)

4) Robotium:
The world's leading Android™ test automation framework - Google Project Hosting (Android)

5) Selendroid:
Selenium for Android (Android)

6) BDD: SoapUI:
SoapUI is a free and open source cross-platform Functional Testing solution. With an easy-to-use graphical interface, and enterprise-class features, SoapUI allows you to easily and rapidly create and execute automated functional, regression, compliance, and load tests. In a single test environment, SoapUI provides complete test coverage and supports all the standard protocols and technologies. There are simply no limits to what you can do with your tests. Meet SoapUI, the world's most complete testing tool!

SoapUI NG Pro:
  • Comprehensive reporting
  • Award-winning support
  • Data-driven testing
  • Contract coverage
  • Fast & Fun testing
  • Automation at its finest
  • Seamless transition
7) Appium:
Advantages:
1) Open source
2) You can write in one of many languages (java, c#, ruby etc.)
3) Appium does not require any modification to the source code of your application before running tests. I guess most of other tools require an extra agent needs to be compiled with your application code so that the tool can interact with the mobile app.
4) Supports both ios and android platforms. You can have single codebase to test your android and ios apps.
5) Good community support. You can ask questions here:
6) support for running multiple tests is currently available on android.
7) Appium can be used to automate native apps, hybrid apps ans mobile web apps.

8) TestingWhiz:

TestingWhiz is a Codeless Automated Software Testing Tool for Web, Mobile, Database, Cloud, Web Services and API testing.
It is pillared on a strong architecture combined with intuitive Automation Engine and short learning curve that promises to take your test automation to the next level.

Automated Regression Testing:
Helps you perform regression test automation by simply recording the test steps and reusing the same with modifications in the code less test editor.
  • Web Test Automation:
    Allows you to automate Web UI testing to verify the critical functioning of your web applications and deliver efficient and effective web interfaces that meet user expectations.
  • Automated Cross-Browser Testing:
    Helps you perform automated cross-browser testing of your applications with support for multiple browsers such as Internet Explorer, Mozilla Firefox, Google Chrome, Safari, and Opera.
  • Automated Database Testing:
    Allows you to test application’s database in a number of ways with the support of database test automation, enabling you to test the core of the application and not just the front-end.
  • Web Services Automated Testing:
    Helps you perform automated web services testing to verify whether the web services communicate and access information from web as defined with support for SOAP and RESTful web services.
  • Automated Mobile Testing:
    Allows you to execute testing of your native, hybrid and mobile web apps on real mobile devices and simulators with automated mobile testing solution.
9) Sikuli:
Sikuli is a tool to automate graphical user interfaces (GUI) using “Visual Image Match” method. In Sikuli, all the web elements should be taken as an image and stored inside the project. Sikuli will trigger GUI interactions based on the image visual match, the image which we have passed as the parameter along with all methods.
Sikuli can be very much useful to automate flash objects (which do not have ID or name). It can be useful in the situation, where we have a stable GUI (i.e. GUI components not changing).
Even Window based applications can also be automated using Sikuli. Sikuli provides very friendly Sikuli-script.jar, which can be easily used together with Selenium WebDriver. We can even automate Adobe Video/Audio player, Flash Games on website using Sikuli. With simple API, it makes coding easier.

Practical Uses:
1. Sikuli can be used to automate Flash Objects / Flash Websites.
2. It can be useful to automate Window based application. We can automate, what we are seeing on the screen.
3. It provides, simple API. i.e. all methods can be accessed using screen class object.
4. It can be easily integrated with Selenium and all other tools.
5. Using Sikuli we can automate desktop applications.
6. Most of the automation testing tools will not support flash object automation (E.g. Selenium). Sikuli provides extensive support to automate flash objects.
7. It uses powerful “Visual Match” mechanism to automate desktop & flash objects.

Benefits:
Open source Tool.
One of the biggest advantage of Sikuli is that, it can easily automate Flash objects.
It makes easy to automate windows application.
When you’re testing an application under development and you don’t know the ID/name of the elements, then you can go with Sikuli. It will check the appearance of the image and if match found, it will interact with the image accordingly.

10) AutoIt:
 AutoIt is a freeware tool which is used for automating anything in Windows environment. AutoIt script is written in BASIC language. It can simulate any combination of keystrokes, mouse movement and window/control manipulation.
Through AutoIt we can prepare scripts for our routine actions like file input/output operations, application handling, resources monitoring, and administrative tasks and so on.
While doing automation through Selenium or through any other tool for that matter, we all encounter a common problem, windows pop-ups. As Selenium is confined to automating browsers, desktop window is out of scope. Web applications sometimes need to interact with the desktops to perform things like file downloads and uploads. There are tools available for automating these sorts of workflow such as AutoIt, Robot Framework and Silk Test etc.

We can upload or download the files or images by transferring our control from Selenium WebDriver to AutoIt. We need to explicitly call the AutoIt script from our program.

Monday 30 May 2016

jMeter-Performance Testing Tool

Introduction:

Apache JMeter is a 100% pure Java desktop application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions. Apache JMeter may be used to test performance both on static and dynamic resources (files, Servlets, Perl scripts, Java Objects, Data Bases and Queries, FTP Servers and more). It can be used to simulate a heavy load on a server, network or object to test its strength or to analyze overall performance under different load types. You can use it to make a graphical analysis of performance or to test your server/script/object behavior under heavy concurrent load.

Features:

Apache JMeter features include:
  • Ability to load and performance test many different server/protocol types:
    • Web - HTTP, HTTPS
    • SOAP / REST
    • FTP
    • Database via JDBC
    • LDAP
    • Message-oriented middleware (MOM) via JMS
    • Mail - SMTP(S), POP3(S) and IMAP(S)
    • Native commands or shell scripts
    • TCP
  • Complete portability and 100% Java purity.
  • Full multithreading framework allows concurrent sampling by many threads and simultaneous sampling of different functions by separate thread groups.
  • Careful GUI design allows faster Test Plan building and debugging.
  • Caching and offline analysis/replaying of test results.
  • Highly Extensible core:
    • Pluggable Samplers allow unlimited testing capabilities.
    • Several load statistics may be chosen with pluggable timers.
    • Many advanced plugins are available to generate final report of jmeter.
Advantages & Disadvantages:

  1.  It’s easy to use and GUI are very user friendly, which helps in executing and recording application sessions.
  2.  It is open source. So, you can modify or change or add new features.
  3.  Apart from above two reasons, the excellent benefit is that it is free. So, no license cost.
  4.  It’s pure Java tool, which allows to execute this tool in any platform (i.e. platform independent)
  5. It’s have many configuration mechanism like Http Request, FTP Request, java request, SOAP Request etc.
  6. This tool mainly used for performance testing (load, stress)
  7. It’s used only for web based application not windows base application.
  8. If you are using it for a big project, then no guarantee of support or further enhancements.
Conclusion:
Need to test your web services, database, FTP- or web server? Both performance and functional testing? We can easily use JMeter. It is free, very intuitive and has all the possibilities you need to automate your work. Another big advantage of JMeter: open source tool.You can download the source and make modifications to it if you like. Also direct contact with the developers through a mailing list is very handy.

Jmeter Test:



Report:



 Graphical Report:

Tuesday 3 May 2016

About Author

In just the past two years, the software testing industry has changed drastically. I started this blog as a way for me to keep up. I found myself taking copious amounts of notes when I started interviewing for automated development positions, and I wanted a place to store them. A place to motivate me to keep on putting in the hours needed in order to research and study these new technologies.

About Me:

I'm Bharat Mane, born & brought up from a small village (Daribadchi) in Sangli District, Maharashtra-India. Currently, I'm working as a QA Lead and from past 4 years. I've been attempting to make the leap from manual to automated testing -- just like most software testers nowadays. I have completed my Bachelor of Engineering (BE) in E&TC from Nagpur University in 2013. As I had from E&TC background, so coding hasn't been a focal point of my career -- until now.
 I finally entered the field of Software Testing mainly in Automation development, writing automated tests for Web-based applications. As this is my first blog and in this, I'm trying to share with all of you that what I have been learning, what skills I have been picking up, how they do things with automation.

In last 3 years, I have learned & having working experience on number of tools in Automation Testing-
  • Selenium IDE
  • Selenium WebDriver
  • Selenium Grid
  • Apache Maven
  • BDD framework with Cucumber
  • Mobile Testing(Android & iOS)-Appium
  • AutoIT
  • TestNG
  • Sikuli
  • Log4j
  • Extent Reports in Selenium
  • SoapUI-API testing tool 
  • JMeter

I'm always trying to update with latest technologies & I still need to learn lots of technologies in Automation testing mostly in Selenium.

If you like my blog Feel free to like dropping me a line on-

FB: https://www.facebook.com/bharat.mane2 
LinkedIn: https://www.linkedin.com/in/bharat-mane-15396510b
GitHub: https://github.com/Bharat-Mane
Instagram: https://www.instagram.com/bharatmane2 
StackExchange: http://sqa.stackexchange.com/users/17411/bharat-mane

===========================================