Selenium 2.0 WebDriver – its easy to learn!!

I wanted to evaluate Selenium 2.0 hence went through the Selenium 2.0 and WebDriver documentation and tried writing some simple tests with JUnit.4  Its really easy to understand.  Lot of changes, its like entirely a new tool.

APIs are pretty straight forward and easy to use.  Let us have a look at the following code.

package com.selftechy.webdriver;

import org.junit.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class SearchGoogle {
protected static WebDriver driver;	

	@BeforeClass
	public static void setUp() throws Exception {
        driver = new FirefoxDriver();
	}

	@Test
	public void testGoogleSearch() throws Exception {
		driver.get("http://www.google.com");
		driver.findElement(By.name("q")).sendKeys("selftechy");
		driver.findElement(By.name("q")).submit();
		driver.findElement(By.name("btnG")).click();
		driver.findElement(By.partialLinkText("Selftechy.com")).click();
	}

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

To write the above code, I have not used Selenium IDE but used Firebug. / Firepath  Using Firebug we can find out ID, name, xpath, etc of an object. If you know little bit of HTML DOM (should know what is ID, name, tag, xpath, etc) then using the APIs such as findElement, it is very easy to automate test cases.

The above code searches for “selftechy” in Google and then opens up the http://www.selftechy.com website by clicking on the search result.  It uses API – findElement and methods – click, get, submit, sendkeys, etc.

Since WebDriver provides an option to find out elements using link text / partial link text, it is easy to click on the link as well as locate them on the application.

One more thing I want to mention here is with WebDriver, there is no need to run Selenium RC for standalone tests.  Just go to Run As and click on JUnit Test., it starts executing the test.

If you ask me to choose between Selenium 1.x & Selenium 2.0 WebDriver, I would suggest the latter.

Selenium WebDriver – Handling Javascript Popups

In the latest release of Selenium 2.0 WebDriver Alert class is implemented.  Get the latest release of Selenium 2.0 from this Download link.  Download selenium-server-2.0rc3.zip and unzip into \Libraries folder.  Add “selenium-server-standalone-2.0rc3” to the classpath (Add the External Jar to buildpath of the project’s properties in Eclipse IDE).

Here, I have taken an example HTML file which produces an alert box after clicking a button on the page.  Below is the code for that HTML file.  Copy and paste this HTML code into notepad and save it as “jscriptpopup.htm”

<html>
<head>

function show_alert()
{
alert("This is an JavaScript alert box!");
}

</head>
<body>

<input type="button" onclick="show_alert()" value="Show alert box" />

</body>
</html>

Selenium 2.0 WebDriver provides class – Alert to handle the popups.  We can cancel the popup or else click on the OK button on the alert box.  We can also get the message on the alert box.

Before using the methods, alert class should be declared as follows:

Alert alert = driver.switchTo().alert();

Alert class provides various methods such as:

  1. accept()
  2. dismiss()
  3. getText()

This makes the Automation Tester’s life easier when there are lot of JavaScript popup’s in the Application under Test.

Create a new Java Class copy and paste the below code and then execute:

package com.selftechy.wdriver;
/*
 * Author - Bharathk
 * 
 */
import org.openqa.selenium.By;
import org.openqa.selenium.Alert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

public class JscriptPopMain {
	public static void main(String[] args) {
		WebDriver driver=new FirefoxDriver();
		driver.get("file:///F:/Helios-Workspace/WebDriver/TestDataWebDriver/jscriptpopup.htm");
		driver.findElement(By.xpath("//input[@value='Show alert box']")).click();
		Alert alert = driver.switchTo().alert();
		System.out.println(alert.getText());
		alert.accept();
		driver.quit();
	}
}

Execution of the above code should produce the result as – “This is an JavaScript alert box!

Selenium 2.0 WebDriver – A Test Automation example

Getting started with web driver requires some idea on “how to use the APIs” provided by the Selenium 2 Web driver.  Some of the useful APIs were discussed in detail in “Useful APIs of WebDriver”.  Example of automating a web page with these APIs explains the Test Automation with WebDriver better.

I have created a sample web page which has different objects such as edit box, labels, links, buttons, radio button, checkbox, javascript popup, etc.

The below example:

package com.selftechy.wdriverbasics;

/*
 * Author - Bharathk
 * Copyrights - All rights reserved. 
 * 
 */

import java.util.List;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class CreateAccount {
	public static WebDriver driver;
	public Alert alert;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		driver=new FirefoxDriver();
		driver.get("file:///C:/Sample%20Website/CreateAccount.htm");
	}

	@Test
	public void testCreateAccount() throws InterruptedException{
		navigatetoWebpage(driver,"file:///C:/Sample%20Website/CreateAccount.htm");
		typeinEditbox(driver,"name","FirstName","Karthik");
		typeinEditbox(driver,"name","Lname","Shetty");
		typeinEditbox(driver,"xpath","//textarea[@name='street']","No. 425, 3rd Main, 7th Cross, 1st Sector, HSR Layout");
		selectValue(driver,"Chennai");
		selectValue(driver,"Tamilnadu");
		selectValue(driver,"Germany");
		selectRadiobutton(driver,"name","male");
		selectCheckbox(driver,"name","kannada","ON");
		selectCheckbox(driver,"name","english","ON");
		selectCheckbox(driver,"name","hindi","ON");
		clickButton(driver,"name","Save");
		closeJscriptPopup(driver,alert);
		Thread.sleep(50);
		clickLink(driver,"xpath","//a[@href='CustomerInfo.htm']");
		Thread.sleep(50);
		clickLink(driver,"xpath","//a[@href='CreateAccount.htm']");
	}
	
	public static void closeJscriptPopup(WebDriver driver, Alert alert){
		alert = driver.switchTo().alert();
		alert.accept();
	}

	public static void navigatetoWebpage(WebDriver driver, String url){
		driver.get(url);
	}
	public static void clickButton(WebDriver driver, String identifyBy, String locator){
		if (identifyBy.equalsIgnoreCase("xpath")){
			driver.findElement(By.xpath(locator)).click();
		}else if (identifyBy.equalsIgnoreCase("id")){
			driver.findElement(By.id(locator)).click();	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.name(locator)).click();	
		}
		
	}
	
	public static void clickLink(WebDriver driver, String identifyBy, String locator){
		if (identifyBy.equalsIgnoreCase("xpath")){
			driver.findElement(By.xpath(locator)).click();
		}else if (identifyBy.equalsIgnoreCase("id")){
			driver.findElement(By.id(locator)).click();	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.name(locator)).click();	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.linkText(locator)).click();	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.partialLinkText(locator)).click();	
		}
	}
	
	public static void typeinEditbox(WebDriver driver, String identifyBy, String locator, String valuetoType){
		if (identifyBy.equalsIgnoreCase("xpath")){
			driver.findElement(By.xpath(locator)).sendKeys(valuetoType);
		}else if (identifyBy.equalsIgnoreCase("id")){
			driver.findElement(By.id(locator)).sendKeys(valuetoType);	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.name(locator)).sendKeys(valuetoType);	
		}
		
	}
	
	public static void selectRadiobutton(WebDriver driver, String identifyBy, String locator){
		if (identifyBy.equalsIgnoreCase("xpath")){
			driver.findElement(By.xpath(locator)).click();
		}else if (identifyBy.equalsIgnoreCase("id")){
			driver.findElement(By.id(locator)).click();	
		}else if (identifyBy.equalsIgnoreCase("name")){
			driver.findElement(By.name(locator)).click();	
		}
		
	}
	
	public static void selectCheckbox(WebDriver driver, String identifyBy, String locator, String checkFlag){
		if (identifyBy.equalsIgnoreCase("xpath")){
			if ((checkFlag).equalsIgnoreCase("ON")){
				if (!(driver.findElement(By.xpath(locator)).isSelected())){
					driver.findElement(By.xpath(locator)).click();
				}
			}
		}else if (identifyBy.equalsIgnoreCase("id")){
			if ((checkFlag).equalsIgnoreCase("ON")){
				if (!(driver.findElement(By.id(locator)).isSelected())){
					driver.findElement(By.id(locator)).click();
				}
			}
		}else if (identifyBy.equalsIgnoreCase("name")){
			if ((checkFlag).equalsIgnoreCase("ON")){
				if (!(driver.findElement(By.name(locator)).isSelected())){
					driver.findElement(By.name(locator)).click();	
				}
			}
		}
	}

	public static void selectValue(WebDriver driver, String valToBeSelected){
        List <WebElement> options = driver.findElements(By.tagName("option"));
		for (WebElement option : options) {
			if (valToBeSelected.equalsIgnoreCase(option.getText())){
				option.click();
			}
		    } 
	}
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		System.out.println("Execution completed.....");
		//driver.quit(); //if you want to stop the webdriver after execution, then remove the comment
	}

}

Above example showcases all the basic operations of Test Automation through Selenium 2 WebDriver.  Try to replicate the code and execute.

This should fill up the form, clicks save & closes the popup, and then navigates to the other page and comes back by clicking the links on the page.

Running Selenium Tests with ChromeDriver on Linux

Some of the pre-requisites has to be setup to execute the Selenium WebDriver tests with chromedriver on Linux

Download the following Softwares before starting to write tests in eclipse.

  1. Download Google Chrome – Chrome for Linux
  2. Download ChromeDriver – ChromeDriver for Linux

Install the Google Chrome on the Linux ennvironment by using the following methods:

  1. Double click or use rpm command if the package is “.rpm” (am currently using Fedora) to install the google chrome
  2. Use apt-get / YUM command to download and then install the package for different Linux flavors accordingly

Executing ChromeDriver Server:

  1. Inside /home/${user} – create a new directory “ChromeDriver”
  2. Unzip the downloaded chromedriver into this folder
  3. Using chmod +x filename or chmod 777 filename make the file executable
  4. Go to the folder using cd command
  5. Execute the chrome driver with ./chromedriver command
  6. Now the chromedriver will start executing in the 9515 port
[seetaram@Linux chromedriver]$ ./chromedriver
Started ChromeDriver
port=9515
version=14.0.836.0

Above is the output of the chromedriver server executing in Linux terminal.

After the above is accomplished, try to setup the test on the eclipse

  1. Download the Selenium server 2.0
  2. Download JUnit
  3. Unzip both the files and configure them to build path in the eclipse
  4. Write the test code as below in the Eclipse – Java file
package com.selftechy.wdriver;

import java.io.File;
import java.io.IOException;
import java.net.*;

import org.junit.*;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

public class ChromeRemoteDriver {
    
    public static void main(String []args) throws MalformedURLException{
        new DesiredCapabilities();
            URL serverurl = new URL("http://localhost:9515");
            DesiredCapabilities capabilities = DesiredCapabilities.chrome();
            WebDriver driver = new RemoteWebDriver(serverurl,capabilities);
        driver.get("http://www.google.com");
        WebElement searchEdit = driver.findElement(By.name("q"));
        searchEdit.sendKeys("Selftechy on google");
        searchEdit.submit();

    }
}

Now, try to execute the code by clicking Run As –> JUnit Test.  It should be executing the test to the completion.

Selenium – Creating XML Reports

XML is the abbreviation for Extensible Markup Language.  XML is used in many aspects of software development, data storage, to communicate between different applications, data sharing, etc.  In Test Automation if the reports are generated in XML format that can be utilized to generate customized HTML reports and also can be imported into Spreadsheet like Microsoft Excel for better visibility.  This forces the Automation Testers to generate XML reports.  In this post I have given Java code which generates the XML report in the below format:

<testsuite>
    <testcase>
        <ID>Test_01</ID>
        <Status>Pass</Status>
        <Error>Null</Error>
    </testcase>
    <testcase>
        <ID>Test_02</ID>
        <Status>Pass</Status>
        <Error>Null</Error>
    </testcase>
</testsuite>

The above xml contains testsuite tag, under that testcase tag.  Each of the testcase tag will have different attributes such as ID, status, and error.  If we generate the output of an execution of Test Automation Suite in this format that will help us in analyzing the results.  Hence, we can utilize the same format in test automation with Selenium.

In this example, I have not used Selenium but this can be easily integrated in the test automation suite just by implementing the class and inheriting the class in the Automation Suite.

Let us have a look at the below code:

package com.selftechy.xmlhelpers;

/*
 * 
 * Author - bharathk
 */
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.dom.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;

public class XMLdoc {
    public String getXML()
      throws ParserConfigurationException,
             TransformerException,
             TransformerConfigurationException
             {
		        DocumentBuilderFactory factory
		          = DocumentBuilderFactory.newInstance();
		        DocumentBuilder builder = factory.newDocumentBuilder();
		        DOMImplementation DMi = builder.getDOMImplementation();
		
		        Document dc = DMi.createDocument(null,null,null);
		        Element ts = dc.createElement("testsuite");
		        dc.appendChild(ts);
		
		        Element tc = dc.createElement("testcase");
		        ts.appendChild(tc);
		        
		        Element id = dc.createElement("ID");
		        tc.appendChild(id);
		        id.appendChild(dc.createTextNode("Test_01"));
		
		        Element sts = dc.createElement("Status");
		        tc.appendChild(sts);
		        sts.appendChild(dc.createTextNode("Pass"));

		        Element err = dc.createElement("Error");
		        tc.appendChild(err);
		        err.appendChild(dc.createTextNode("Null"));

		        Element tc2 = dc.createElement("testcase");
		        ts.appendChild(tc2);
		        
		        Element id2 = dc.createElement("ID");
		        tc2.appendChild(id2);
		        id2.appendChild(dc.createTextNode("Test_02"));
		
		        Element sts2 = dc.createElement("Status");
		        tc2.appendChild(sts2);
		        sts2.appendChild(dc.createTextNode("Pass"));

		        Element err2 = dc.createElement("Error");
		        tc2.appendChild(err2);
		        err2.appendChild(dc.createTextNode("Null"));
		        
		        DOMSource dmSrc = new DOMSource(dc);
		        TransformerFactory tfc = TransformerFactory.newInstance();
		        Transformer transformer = tfc.newTransformer();

		        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
		        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
		        transformer.setOutputProperty(OutputKeys.ENCODING,"ISO-8859-1");
		        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
		        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		        java.io.StringWriter swriter = new java.io.StringWriter();
		        StreamResult sresult = new StreamResult(swriter);
		        transformer.transform(dmSrc, sresult);
		        String xml = swriter.toString();
		        return xml;
    }

    public static void main(String args[])
			    throws ParserConfigurationException,
			    TransformerException,
			    TransformerConfigurationException
     {
        System.out.println(new XMLdoc().getXML());
     }
}

There are different XML parsers / processors available but out of them JAXP is the one which is provided by the JDK.  Here, I have utilized JAXP for XML report creation.  This library provides several classes and methods to accomplish the XML document creation.

Execute the above Java program and the output should look like the one which resembles the above format.

Create a Java class and integrate with Selenium Test Automation Suite.

Selenium 2.0 WebDriver – useful APIs

To start with WebDriver we need to learn about some of the useful APIs that are provided for automating user actions on an application.

Let us list some of the actions that we need to automate while automating a test case:

  1. Click a link, button
  2. Type value in an Edit box
  3. Select a value from the dropdown
  4. “Check / Uncheck “ a checkbox
  5. Select a radio button

This is exactly what I am going to discuss in this post.

Click a link / button:

To click on an object through webdriver first we need to find out which locator we are going to use.  Is it ID, name, xpath, or css? For this purpose we can utilize firebug / xpath checker to find out is there any id / name exists for the object we are going to perform action upon.  Then write the code as below:

driver.findElement(By.xpath(“//a[@href=’CustomerInfo.htm’]”)).click();

In the above line of code “driver” could be FirefoxDriver, InternetExplorerDriver, ChromeDriver, HtmlUnitDriver, etc.  On one of these browsers we are going to find an element and then click as per the code.

findElement is an API provided by the webdriver which requires argument “By.xpath”.  The “xpath” can be replaced by one of the below methods if we need to identify the element with any other attributes such as css, name, classname, etc:

  1. className
  2. cssSelector
  3. linkText
  4. name
  5. partialLinkText
  6. tagName
  7. xpath
  8. id

To understand the above methods one needs the basic understanding of the HTML.  Id, name, input, type, a, etc are the HTML tags / attributes.  Using these HTML tags and attributes “xpath” can be constructed and this I have already explained in one of my earlier posts (How to write xpath)

Type value in an Editbox

Have a look at the below line of code.

driver.findElement(By.name(“FirstName”)).sendKeys(“Google”);

Here the webdriver finds the object first with findElement API and then keys in the value with sendKeysmethod.

Select a value from the dropdown

To select a value from a dropdown, follow the below steps:

  1. Declare a List and assign all the values of dropdown using findElements method
  2. Use a for loop to go through the elements one by one
  3. Using an IF condition match the required option
  4. Click the required option (.setSelected is deprecated)

Use the below code and put that into a function which does the job.

	public static void selectValue(String valToBeSelected){
        List <WebElement> options = driver.findElements(By.tagName("option"));
		for (WebElement option : options) {
			if (valToBeSelected.equalsIgnoreCase(option.getText())){
				option.click();
			}
		    } 
	}

call the static method wherever necessary – selectValue(“Texas”) will select the value Texas from the dropdown country.

“Check / Uncheck “ a checkbox

To “Check / Uncheck” a checkbox, the object needs to be identified using findElement method and then just click.  To find out whether the checkbox is checked or not utilize the method – element.isSelected()

        WebElement kancheck = driver.findElement(By.name("kannada"));
        kancheck.click();
        System.out.println(kancheck.isSelected());

Above code snippet will first click the checkbox named kannada and then verifies whether it is clicked or not.

Select a radio button

Follow the same steps which are used in Checkbox to select a radio button and then verify the status using isSelected() method.

        WebElement gender = driver.findElement(By.xpath("//input[@name='male']"));
        gender.click();
        System.out.println(gender.isSelected());

Above are the basic actions needed for Test Automation.

Thanks,

Selenium – Use Assertions to Verify the Test Output

In Software Testing we need to verify the output of test case against a predefined set of Test Data. Selenium provides various Selenese commands to achieve this.  Let us try to explore some of the situations we come across in Test Automation.

  1. Verify whether an object is visible (such as a button, link, etc)
  2. Verify whether a checkbox is checked or unchecked.
  3. Check if an object is present on the screen
  4. Check if an Editbox is editable (i.e. we can key in values into edit box)
  5. Check if a particular value is selected in the dropdown box

Selenium provides several different APIs for automating the Assertions.

Following are some of the Selenium assertions:

  1. assertAlertPresent – checks whether an alert is present
  2. assertAllButtons – compares the buttons present on the screen with the provided values in the test
  3. assertAllLinks – compares all the links present on the screen with the one’s given in the test
  4. assertChecked – verifies whether the particular checkbox is checked
  5. assertEditable – verifies the Edit box whether it is possible to key in values into the edit box
  6. assertSelectedValue – compares the given value with the selected value in the specified dropdown

Let us try to use these assertions in the Selenium Test by recording a test.  After recording we will export them into JUnit format and compare them to the recorded test in the table format in Selenium IDE.

RecordedAssertions

In the above picture we can see the exact commands used in the Selenium IDE for assertions whereas in the below code which is exported in JUnit format from the Selenium IDE, only assertTrue and assertEquals are present.  Here, other selenium methods such as selenium.getSelectedLabel(“city”), selenium.isTextPresent(“Name of the Customer”), and selenium.getAlert() are used for assertions.

package com.selftechy.assertions;

/*
 * Author - Bharathk
 */
import com.thoughtworks.selenium.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.Assert;

public class SeleniumAssertions extends SeleneseTestCase {
	@Before
	public void setUp() throws Exception {
		selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://www.sqajobs.com/");
		selenium.start();
		selenium.windowMaximize();
	}

	@Test
	public void testAssertions() throws Exception {
		//change the below directory path to the one where you have unzipped the sample website files 
		selenium.open("file:///F:/Helios-Workspace/Sample%20Website/CreateAccount.htm");
		selenium.type("FirstName", "seetaram");
		selenium.type("Lname", "hegde");
		selenium.type("street", "HSR Layout");
		selenium.click("male");
		selenium.click("kannada");
		selenium.click("english");
		selenium.click("hindi");
		selenium.click("Save");
		assertEquals("New Account Created", selenium.getAlert());
		selenium.click("link=Click to View Customer Information");
		selenium.waitForPageToLoad("30000");
		Thread.sleep(200);
		assertTrue(selenium.isTextPresent("Below table contains the information about the Customer's transactions"));
		assertTrue(selenium.isTextPresent("Name of the Customer"));
		selenium.click("link=Go to Account Creation Screen");
		selenium.waitForPageToLoad("30000");
		Thread.sleep(200);
		assertEquals("Bangalore", selenium.getSelectedLabel("city"));
	}

	@After
	public void tearDown() throws Exception {
		//selenium.stop();
	}
}

Use the following Selenium APIs for assertions:

  1. selenium.isTextPresent() – To verify whether the specified text is present
  2. selenium.getAlert() – To close the Javascript alert
  3. selenium.getSelectedLabel() – To get the selected label (dropdown option) from the dropdown
  4. selenium.chooseOkOnNextConfirmation() – To click the OK button on the Javascript alert
  5. selenium.chooseCancelOnNextConfirmation() – To click the Cancel button on the Javascript alert
  6. selenium.doubleClick(“Locator”) – double click an object
  7. selenium.isChecked(“locator”) – Verify whether a checkbox is checked or not
  8. selenium.isEditable(“locator”) – Verify whether an Editbox is editable or not
  9. selenium.isElementPresent(“locator”) – This is a very much useful Selenium method.  Whenever there is a need to wait for some time to load the page then we can use this API in conjunction with Thread.sleep()
  10. selenium.isVisible() – To verify whether the object is visibleThese are most regularly used.

Thanks,

GUI(Graphical User Interface) Testing

To understand GUI Testing lets first understand!!!

What is GUI ?

There are two types of interfaces in a computer application.

Command Line Interface is where you type text and computer responds to that command.

GUI stands for Graphical User Interface where you interact with the computer using images rather than text.

Following are the GUI elements which can be used for interaction between the user and application:

GUI Elements

What is GUI Testing?

Graphical User Interface (GUI) testing is the process of testing the system’s GUI of the System Under Test. GUI testing involves checking the screens with the controls like menus, buttons, icons, and all types of bars – tool bar, menu bar, dialog boxes and windows etc.

What do you Check in GUI Testing ?

The following checklist will ensure detailed GUI Testing.

  • Check all the GUI elements for size, position, width, length and acceptance of characters or numbers. For instance, you must be able to provide inputs to the input fields.
  • Check you can execute the intended functionality of the application using the GUI
  • Check Error Messages are displayed correctly
  • Check for Clear demarcation of different sections on screen
  • Check Font used in application is readable
  • Check the alignment of the text is proper
  • Check the Color of the font and warning messages is aesthetically pleasing
  • Check that the images have good clarity
  • Check that the images are properly aligned
  • Check the positioning of GUI elements for different screen resolution.

Approach of GUI Testing:

GUI testing can be done through three ways:

Manual Based Testing

Under this approach, graphical screens are checked manually by testers in conformance with the requirements stated in business requirements document.

Manual Testing

Record and Replay

GUI testing can be done using automation tools. This is done in 2 parts. During Record , test steps are captured into the automation tool. During playback, the recorded test steps are executed on the Application Under Test. Example of such tools – QTP .

Record and PlayBack Testing

Model Based Testing

A model is a graphical description of system’s behavior. It helps us to understand and predict the system behavior. Models help in a generation of efficient test cases using the system requirements. Following needs to be considered for this model based testing:

  • Build the model
  • Determine Inputs for the model
  • Calculate expected output for the model
  • Run the tests
  • Compare the actual output with the expected output
  • Decision on further action on the model

Some of the modeling techniques from which test cases can be derived:

  • Charts – Depicts the state of a system and checks the state after some input.
  • Decision Tables – Tables used to determine results for each input applied

Model based testing is an evolving technique for the generating the test cases from the requirements.Its main advantage, compared to above two methods, is that it can determine undesirable states that your GUI can attain.

Conclusion:

Success of a software product immensely depends on how the GUI interacts with the user and ease in using its various features. Hence GUI testing is very important. Manual GUI testing can sometimes be repetitive and boring and hence error prone. Automation is highly recommended for GUI testing.

Android Mobile Apps Automation using UI Automator

Currently as a Sr. QA Engineer , I have been spending most of the time at work writing automation scripts for Android apps rather than manual testing. I have already written automation scripts for three android mobile apps for my company.

I never really thought that this would be easy . Google has provided a tool named ‘UI Automator’ for executing Automation scripts for Android in a pretty simple manner. It comes under UI Testing. UI testing ensures that the app returns the correct UI output in response to a user actions on a device, say keyboard input or pressing toolbars, menus, dialogs, images, and other UI controls. It reduces a lot of manual testing job and saves a lot of time.

Android SDK provides with uiautomator , a java library to automate and run the tests. Along with this , it also provides a GUI tool called uiautomatorviewer to inspect the layout hierarchy and view the properties of the individual UI components on your test device.

‘uiautomatorviewer’ Overview –

[1] ‘uiautomatorviewer’ tool can be used to take a snapshot of the foreground UI screen on any Android device which is connected to your machine.

[2] Make sure ‘USB Debugging’ is ‘ON’ when using uiautomatorviewer. For that : Go to ‘Settings’ on your device -> ‘Developer Options’ -> check ‘USB debugging’ option.

usb_debugging

[3] Keep your Android SDK updated to latest version. Open Eclipse -> Go to ‘Window’ in toolbar -> ‘Android SDK Manager’. It will display the updates there. Install all packages and keep it up-to-date.
android_sdk_manager

[4] To take screen shot of foreground UI screen :

  • Connect your device to your development machine.
  • Open command prompt.
  • ‘uiautomatorviewer’ is a batch file which exists inside ‘tools’ folder of ‘sdk’. So you can go to your ‘tools folder inside ‘sdk’ in command prompt and type ‘uiautomatorviewer’ there :

cmd_uiautomatorviewer

or directly click on that batch file from your tools folder and use.

  • One empty window will open :

uiautomatorviewer_blank

[5] Hover on the second ‘green’ button on the top. It shows ‘Device Screenshot’. Click    on it and you will get UI screen of what ever is open on your device :

uiautomatorviewer

Accessing  elements  through  uiautomatorviewer –

[1] Say , we open ‘Clock’ app in any Android device. So that screenshot would appear like :

clock_app_screenshot

[2] Hover on the screenshot to view elements hierarchy. As you keep hovering over        the elements on the screenshot -> you will observe that the ‘Node Detail’ (at right bottom) and the hierarchy (right top) keeps changing.

[3] Say , now I want to access the current date on clock app. So for that , I hover on the date :

clock_app

[4] For reference , I have marked some element properties with red as shown in above screenshot. So from that , we get to know that :

Today’s date has :

  • resource id  : com.android.deskclock:id/date
  • text : Wed , April 23
  • content-desc : Wednesday , April 23
  • index : 0
  • class : android.widget.TextView
  • package : com.google.android.deskclock
  • enabled : true
  • other properties : false

We will create a demo script which shows how to access time on clock.

Frequently  used  Classes  in  UI Automator

Some most common frequently used classes in UI Automator are :

[1] UiDevice :

Provides access to device state , serving purpose like  :

i) ‘Home’ button press :

getUiDevice.pressHome();

ii) Click on something using (x,y) coordinates :

getUiDevice.click(int x , int y);

iii) ‘Back’ button press :

getUiDevice.pressBack();

Full details can be found here for this class here.

[2] UiSelector :

Used to mention search criteria for an element , refining elements based on text , content-desc , class etc. If more than one matching element is found : it returns the first matching element in the hierarchy. If no matching element is found : ‘UiAutomatorObjectNotFoundException’ is thrown. ‘childSelector()’ method ca be used here for nested UiSelector instances.

Some examples to access elements through :

i) text :

new UiObject(new UiSelector().text("abcd");

ii) resource-id:

new UiObject(new UiSelector().resourceId("com.example.abcd");

iii) Nested : Find the first ListView in the currently displayed UI, then search within that ListView to find a UI element with the text property Apps :

UiObject appItem = new UiObject(new UiSelector().className("android.widget.ListView").
instance(1) .childSelector(new UiSelector().text("Apps")));

Full details can be found here for this class here.

[3] UiObject :

Represents a UI element. UiSelector is used to create a UiObject instance showing how to search for element.

Instances can be created as :

UiObject yes_button = new UiObject(new UiSelector().text("YES");
//searching for button on screen
if (yes_button.exists()) {
yes_button.click();
}

UiObject instances can be reused in code.

Full details can be found here for this class here.

[4] UiScrollable :

Can be used for horizontal/vertical scroll on screen. Can be useful when you need to swipe on screen to bring any specific element into view.

Example : how to simulate scrolling down the Settings menu and clicking on an ‘About phone’ option:

UiScrollable settings = new UiScrollable(new UiSelector() .
className("android.widget.ListView"));

UiObject about = settingsItem.getChildByText(new UiSelector() .
className("android.widget.LinearLayout"), "About phone");
about.click(); 

Full details can be found here for this class here.

Executing  Basic  Script –

FIRST  STEP : Creating  a  new  project

[1] Create a new java project in Eclipse :

  • Go to ‘File’ -> ‘New’ -> ‘Java Project’

new_java_project

[2] Add project name and click ‘Next’ –

project_name

[3] Click ‘Finish’ –

project_name_settings

[4] Expand your project. Right click on src folder -> ‘New’ -> ‘Class’ –

new_class

[5] Enter ‘Name’ for class. Also mention ‘Package’ and then click ‘Finish’ –

class_name

[6] You will see something like –

empty_project

SECOND  STEP : Adding  required  jar  files

[1] We need to add uiautomator and android jar files along with JUnit library. For that :

  • Right click on your project -> open ‘Properties’.
  • Go to ‘Java Build Path’ from left menu.
  • Open ‘Libraries’ section –

project_properties

[2] Click on ‘Add External JARs’ . Navigate to your platforms folder inside sdk say like ‘../android-sdk/platforms’ . Select your highest platform here say platform-19 : you will find uiautomator.jar and android.jar. Just select both and add them –

jar_files

[3] Now click -> ‘Add Library’ -> select JUnit –

junit

[4] Click ‘Next’ -> then ‘Finish’. Then ‘Ok’. You will see that the jar files and JUnit are added to your project –

libraries

THIRD  STEP : Writing  script

Now we will be writing basic script say to view current date and time on clock app –

package com.bharath.firsttest;

import com.android.uiautomator.core.UiObject;
import com.android.uiautomator.core.UiObjectNotFoundException;
import com.android.uiautomator.core.UiScrollable;
import com.android.uiautomator.core.UiSelector;
import com.android.uiautomator.testrunner.UiAutomatorTestCase;

public class FirstTestCases extends UiAutomatorTestCase {

  public void testDemo() throws UiObjectNotFoundException,
      InterruptedException {

    // Simulate a short press on the HOME button.
    getUiDevice().pressHome();

    // simulate click on All Apps screen.
    // All Apps button’s content-description property has the value “Apps”
    UiObject allAppsButton = new UiObject(
        new UiSelector().description("Apps"));

    // Simulate a click to bring up the All Apps screen.
    allAppsButton.clickAndWaitForNewWindow();

    // Simulate click on 'Apps' section
    UiObject appsTab = new UiObject(new UiSelector().text("Apps"));

    // Simulate a click to enter the Apps tab.
    appsTab.click();

    // Simulate a user swiping until they come to the Clock app icon
    UiScrollable appViews = new UiScrollable(
        new UiSelector().scrollable(true));

    // Set the swiping mode to horizontal - default is vertical
    appViews.setAsHorizontalList();

    // Create a UiSelector to find the Clock app and simulate
    // a user click to launch the app.
    UiObject clock_app = appViews.getChildByText(new UiSelector()
        .className(android.widget.TextView.class.getName()), "Clock");
    clock_app.clickAndWaitForNewWindow();

    // Validate that the package name is the expected one
    UiObject clock_validation = new UiObject(
        new UiSelector().packageName("com.google.android.deskclock"));
    assertTrue("Unable to detect Clock App", clock_validation.exists());
    System.out.println("Clock App launched");

    // adding 5sec delay after app is launched
    Thread.sleep(5000);

    // get current time
    UiObject time = new UiObject(
        new UiSelector().resourceId("com.android.deskclock:id/time"));
    String current_time = time.getContentDescription();
    System.out.println("Current Time : " + current_time);

    // get current date
    UiObject date = new UiObject(
        new UiSelector().resourceId("com.android.deskclock:id/date"));
    String todays_date = date.getText();
    System.out.println("Today's Date : " + todays_date);
  }
}
FOURTH  STEP : Building  and  Deploying  test

Once you have written your test script , you need to build and deploy your JAR. We can mention all the steps in one batch file and just execute that.

  • Open a text file and write the following steps :
Echo build output jar file
call android.bat create uitest-project -n FirstTest -t 13 -p
D:\Android_Workspace1\FirstTest

Echo set home variable
set ANDROID_HOME=D:\Android Development\android-sdk

Echo navigating to project directory where build.xml file is located
cd D:\Android_Workspace1\FirstTest

Echo build test JAR
call ant build

Echo navigating to platform-tools directory
cd D:\Android Development\android-sdk\platform-tools

Echo deploying generated test JAR file to device
adb push D:\Android_Workspace1\FirstTest\bin\FirstTest.jar /data/local/tmp/

Echo running script
adb shell uiautomator runtest FirstTest.jar -c com.smriti.firsttest.FirstTestCases

Echo Test Complete

  • Save text file as “.bat” extension inside your sdk tools folder.
  • Open cmd now and navigate to your tools folder :
  • run_batch_file
  • Write your batch file name and press ‘Enter’.
  • Script will start and finally output will appear :output

This is how anyone can run a sample script.

It didn’t seem so easy at first but now I am comfortable writing automation scripts for Android and I keep sending automated emails to my team members whenever I run my script on any app builds :)

TestNG Testing Framework

TestNG is a testing framework inspired from JUnit and NUnit covering a wider range of test categories: unit, functional, end-to-end, integration, etc., with more powerful and easy-to-use functionalities. It is an open source automated testing framework; where NG of TestNG means ‘Next Generation’.

TestNG’s main features include:

  • Annotation support.
  • Support for parameterized and data-driven testing (with @DataProvider and/or XML configuration).
  • Support for multiple instances of the same test class (with @Factory)
  • Flexible execution model. TestNG can be run either by Ant via build.xml (with or without a test suite defined), or by an IDE plugin with visual results.
  • Concurrent testing: run tests in arbitrarily big thread pools with various policies available (all methods in their own thread, one thread per test class, etc.), and test whether the code is multithread safe.
  • Embeds BeanShell for further flexibility.
  • Default JDK functions for runtime and logging (no dependencies).
  • Dependent methods for application server testing.
  • Distributed testing: allows distribution of tests on slave machines.

TestNG simplifies the way the tests are coded.

FIRST  STEP : Installing TestNG plugin

[1] To install TestNG plugin:  Go to Help -> install new software -> provide the download link in the ‘Work with’ section –  http://beust.com/eclipse/ :

install_testng

[2] Tap on ‘Add’ – give some name and then check the TestNG checkbox ->  Click on ‘Next’ :

install_testng1

[3] Then click on ‘Next’ -> Agree to terms and conditions an complete the installation.

SECOND  STEP : Creating a new project

[1] Create a new java project in Eclipse :

  • Go to ‘File’ -> ‘New’ -> ‘Java Project’

new_java_project

[2] Add project name and click ‘Next’ –

project_name

[3] Click ‘Finish’ –

project_next

[4] Right click on the ‘src’ folder in your project -> ‘New’ -> ‘Package’ :

create_package

[5] Specify a package name there -> then Click ‘Finish’ :

create_package1

THIRD  STEP : Importing TestNG Library

[1] To import ‘TestNG’ plugin to your project :

Right click on your project -> ‘Properties’ -> ‘Libraries’ -> select ‘TestNG’ –

[2] Click ‘Next’ and then ‘Finish’ –

[3] Now go to ‘Order and Export’ tab and make sure everything is checked and then tap on ‘OK’ –

FOURTH  STEP : Creating a TestNG Test File

[1] Right-click on the “src” folder of your project -> then choose New > Other.. :

[2] Click on TestNG folder and select “TestNG class” -> Click ‘Next’ :

Screen Shot 2014-10-19 at 11.57.15 PM

[3] ‘New TestNG class’ dialog opens up where ‘Source Folder’ , ‘Package name’ and ‘Class name’ would be specified. You can modify the ‘Class name’ there to something relevant to your project –

create_testng_class2

[4] Now , if you see below , some annotations would be mentioned there which we can use in our testng file.

Let us select ‘@BeforeMethod’ , ‘@BeforeTest, ‘@AfterMethod’ , ‘@AfterTest’ for now. ‘@Test’ would be taken as the default one here –

create_testng_class4

[5] Click on ‘Finish’ and you can see your testng template file created –

project_created

The TestNG testing framework can execute your tests in parallel. It can also execute some function just before or right after your tests. For this, such methods and test methods should be marked with special annotations @BeforeMethod, @AfterMethod and @Test.

Let’s take an example :

@BeforeTest
System.out.println(“Setting up Tests”);

@BeforeMethod
System.out.println(“Starting test case”);

@Test
a();

@Test
b();

@AfterMethod
System.out.println(“Test case done”);

@AfterTest
System.out.println(“Everything executed”);

So the way of execution here would be as follows :

First @BeforeTest will be called. Then it will execute parallel as –

@BeforeMethod
a();
@AfterMethod

and
@BeforeMethod
b();
@AfterMethod

And at last @AfterTest will be called.

What TestNG does is – It will find all the methods marked as @Test. After this, it will create two parallel threads, and will start executing each method in its own thread. Before and after each @Test, @BeforeMethod and @AfterMethod are executed in each thread.

BASIC  SCRIPT –

Let’s take one simple java script for example with TestNg annotations . We have assigned some priorities to test cases here in the way in which we want them to be executed –

package com.bharath.firsttestng;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class FirstTestNGTestCases {

    @BeforeTest
    public void setUp() {
        System.out.println("Test Cases : ");
    }

    @BeforeMethod
    public void before() {
        System.out.println("Starting test case");
    }

    @Test(priority = 0)
    public void testmethod1() throws InterruptedException {
        System.out.println("Priority 0 Test");
    }

    @Test(priority = 1)
    public void testmethod2() throws InterruptedException {
        System.out.println("Priority 1 Test");
    }

    @AfterMethod
    public void after() throws Exception {
        System.out.println("Finished a test case");
    }

    @AfterTest
    public void finishtest() throws Exception {
        System.out.println("Finished all test cases");
    }
}

Running the Script –

To run the code , right click on your project and run it as a ‘TestNG Test’ –

Output of this script would be –

Test Cases :

Starting test case

Priority 0 Test

Finished a test case

Starting test case

Priority 1 Test

Finished a test case

Finished all test cases

Thus , the order followed is –

@BeforeTest –> @BeforeMethod –> @Test(priority = 0) –> @AfterMethod –> @BeforeMethod –> @Test(priority = 1) –> @AfterMethod –> @AfterTest

The main advantages of TestNG over JUnit are :

  • Annotations are easier to use  and understand.
  • Test cases can be grouped more easily.
  • TestNG allows us to create parallel tests.
  • We can pass additional parameters to annotations.
  • Annotations are strongly typed, so the compiler will flag any mistakes right away.