Page Object Methods Should Return Objects

Learning the page object model is a very important skill for test automation with Selenium.


When learning test automation with Selenium, the Page Object Model is useful for creating classes that correspond to site pages (or components of pages) so that the WebDriver APIs are moved from the test scripts to the page object classes.


After you create page object classes, make sure that each page object method returns either

- A PAGE OBJECT: if the method generates a page change or a new page (example: changing the sort order for a web page will reload the page)

or 

- THIS KEYWORD: if the method's action does not change anything in the page (example: typing a keyword into a textbox does not change anything else in the page)


To see the benefits of returning objects from page object methods, lets  look at a simple test case with the following steps:

1. open the home page of a web site

2. do a keyword search

3. after the results page is loaded, change the sort order

4. after the results page reloads as a result of changing the sort order, select a different results page (page number 5)

5. after the 5th results page is loaded, change the number of results displayed in the page

6. after the page reloads, select one of the results

7. after the result's details page is loaded, confirm that the result's price is valid

The test script for the test case needs 3 page object classes:


public class HomePage
{
public void search()
}

public class ResultsPage {
public void changeSortOrder(String sortOrder)

public void changeResultsPerPage(int number)

public void changePage(int pageNumber)

public void selectResult(int index)
}

public class DetailsPage
{
public Boolean validPrice()
}


None of the page object methods returns an object.

The test script looks as follows:


@Test
public void testValidPrice()
{

HomePage homePage = new HomePage();

homePage.search();

ResultsPage resultsPage = new ResultsPage();

resultsPage.changeSortOrder("author");

resultsPage.changePage(5);

resultsPage.changeResultsPerPage(25);

resultsPage.selectResult(3);

DetailsPage detailsPage = new DetailsPage();

assertTrue(detailsPage.validPrice(), true);

}




The problems of the test script are evident:

- too many new objects are being created (homePage, resultsPage, detailsPage)


- each action is separate


- the flow of the test script does not follow user actions: when the user changes the sort order on the ResultsPage, a new ResultsPage is created as a result



Lets change the page object classes so that all page object methods return objects:


public class HomePage
{
public ResultsPage search();
}

public class ResultsPage
{

public ResultsPage changeSortOrder(String sortOrder)

public ResultsPage changeResultsPerPage(int number)

public ResultsPage changePage(int pageNumber)

public DetailsPage selectResult(int index)
}

public class DetailsPage
{
public Boolean validPrice()
}

@Test
public void testValidPrice()
{

DetailsPage detailsPage = (new HomePage()).search().changeSortOrder("author").changePage(5).changeResultsPerPage(25).selectResult(3);

assertTrue(detailsPage.validPrice(), true);

}


Multiple improvements result from the new page object classes:

- multiple methods can be chained

- the test script is much more compact

- less objects are created    

     



Get Started With Selenium Test Automation

Many manual testers want to expand their testing knowledge by learning test automation skills and programming.

They are interested in moving from manual testing to test automation or just in having more diverse skills and knowledge.



2 of the most popular test automation types are

- Selenium test automation for web sites

- Appium test automation for mobile applications



The test automation job trends for Selenium and Appium show how important test automation is these days for companies.






How can a manual tester start test automation?

Test automation is about many things such as

- using a programming language

- creating a test automation framework

- locating application elements

- running automated tests


A proper learning process is useful so that learning test automation is being done in a simple and incremental way.


If you are interested in getting started with test automation, the following test automation free tutorial for beginners will help you by providing information on

- reasons why test automation is difficult to learn for manual testers

- test automation skills

- test automation project phases




Subscribe now to read the free ebook
* indicates required

What Programming Language To Learn For Test Automation



A fellow tester asked me recently what programming language would be best to start out learning for test automation.

She tried learning C++ awhile back without success.


She was also asking if , for a tester, knowing a programming language is a "must learn" to succeed and grow in testing.


In other words, do testers have to write code?

I agree that learning a programming language is intimidating and difficult for manual testers.

But it should not be so.




What is the best programming language for test automation?


My suggestion is Java or C#.

Let's take Java for example since C# is very similar to Java.


People say that Python and Ruby are easier to learn for a novice and they are probably right.


I don't know Python and used Ruby for just a month to see how it is (very interesting).



I suggest Java because


- Java is available for a long time compared with Ruby and Python which are rather new



- Java is very popular; it is the language with the highest popularity increase (5.94%) in 2015







- a lot of documentation is available on the internet for Java, many online Java courses and many Java books


- learning the first language is difficult regardless of the chosen language; some people recommend learning first Python and Ruby and then learning Java; but if you will put the effort and time into learning, why not learn Java from the start?


- learning Java may be more difficult than Python and Ruby, especially the object oriented part of it; but as soon as you learn it, Java can be applied to many testing types like test automation with Selenium for web and mobile apps, API testing, performance testing (with JMETER)



- while learning the new language, you will have a lot of questions and may get stuck; if your learning is through a Java course, you can ask your instructor for answers; otherwise, it is important to know people that have experience with the language that you are learning; most of developers know Java or C#; Ruby and Python developers are rather rare; I still haven't met a developer on the local market (Vancouver, Canada) that uses these languages for work projects; most of developers use either Java or C#



- Java has a very good IDE (Eclipse)



- if you are planning on using Java for test automation, 65% from all Selenium downloads are for Java







Is learning a programming language a "must-do" for a tester?


More and more companies are moving away from hiring pure manual testers and prefer testers with test automation skills.

Learning a programming language has additional benefits to get you started with test automation.


A tester that knows a programming language will speak the same "language" as developers.


He will understand better what developers do and get a better appreciation of how complicated development is.


He can do unit testing and participate in code reviews.




Test Automation For Android app

The Android apps test automation can be done using 

- UI Automator Java library from Google or 

- Appium.

This article explains how the UI Automator library works.

The test automation process has 3 parts:

1. set up the environment

2. write the java test automation code

3. run the code


1. Set up the environment

Install the Android device driver

First, confirm that the Android device (Nexus 5 in this case) does not have any errors in Device Manager:

- open Control Panel

- click System

- click Device Manager

- expand the Portable Device category

- check if an error icon is displayed for Nexus 5

If there is an error icon for Nexus 5, most probably, there is no driver installed for the device.

To install it, the driver needs to be downloaded first from 
http://developer.android.com/sdk/win-usb.html#top

After the driver archive is downloaded, extract the files in a folder and update the Nexus 5 driver in Device Manager:






Install the Android SDK

The Android SDK is also required.

It can be installed from http://developer.android.com/sdk/index.html.

The download includes the ECLIPSE ADT (Eclipse IDE bundled with ADT = Android Development Tools).

The path of the SDK folder needs to be added to the PATH environment variable (Control Panel --> System --> Advanced Settings --> Environment Variables --> System Variables).

Extract the files from the archive in a folder that will look in the end like this:






Eclipse can be opened using Eclipse.exe from the eclipse folder. 

Eclipse is integrated with the Android SDK as the following options are visible in the toolbar:

Android SDK Manager

Android Virtual Device Manager




The Android SDK has multiple components that we will use:

ADB (Android Debug Bridge)

This is a command tool that allows communication with the connected Android device.

You can see how it works on this link: http://developer.android.com/tools/help/adb.html.

You can find this tool in the platform-tools folder of the Android SDK.

The path of the SDK folder needs to be added to the PATH environment variable (Control Panel --> System --> Advanced Settings --> Environment Variables --> System Variables).



ANDROID.BAT

It creates the required build configuration files to build the output JAR for the project.

You can find it in the Tools folder of the Android SDK.

The path of the SDK folder needs to be added to the PATH environment variable (Control Panel --> System --> Advanced Settings --> Environment Variables --> System Variables).




UIAUTOMATOR JAR FILE

The test automation code will be written in a class file included in an Eclipse project.

To have access to the UIAUTOMATOR library, the following JAR files need to be added to the project in Eclipse (Properties --> Java Build Path --> Libraries):

android.jar
uiautomator.jar

You can find these files in the platforms\android-21 folder of the Android SDK.


Install ANT

Apache Ant is a Java library and command-line tool that help building software.

Download it from http://ant.apache.org/bindownload.cgi

Extract the files from the archive in a folder.

Make changes to environment variables:


  • Add the bin directory to your path.
  • Set the ANT_HOME environment variable to the directory where you installed Ant
  • Optionally, set the JAVA_HOME environment variable. This should be set to the directory where your JDK is installed.

UITESTAUTOMATOR VIEWER


The viewer can be found in the Tools folder of the Android SDK.

This is what you will see after double clicking on uitestautomatorviewer.bat.




To inspect the app, first take a screenshot from the device by clicking on the second icon in the toolbar. 

Then, as soon as the screeshot is displayed, click on an element in it. 

You should be able to see the element details in the right side of the viewer:







2. Write the java test automation code

First, open ECLIPSE ADT and create a new projects.

Add the uiautomator.jar and android.jar files to the project as explained above.

Add a class file to the project.

Add the java code to it. The following code does the following:

1. taps the  home button of the device

2. tap the All Apps button

3. swipes right to get the second page of apps

4. taps on the Settings app

5. check that the settings app exists

import org.junit.Test;
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 AndroidProject extends UiAutomatorTestCase{

@Test
public void testApp() throws UiObjectNotFoundException {

getUiDevice().pressHome();

UiObject allAppsButton = new UiObject(new UiSelector().description("Apps"));

allAppsButton.clickAndWaitForNewWindow();

UiScrollable appViews = new UiScrollable(new UiSelector().scrollable(true));

appViews.setAsHorizontalList();

UiObject settingsApp = appViews.getChildByText(new UiSelector().className(android.widget.TextView.class.getName()), "Settings");

settingsApp.clickAndWaitForNewWindow();

UiObject settingsValidation = new UiObject(new UiSelector().packageName("com.android.settings"));

assertTrue("Unable to detect Settings", settingsValidation.exists());
}
}

Save the changes.




3. Run the code

The remaining part will happen in the command prompt:

1. change the active folder to the project folder

2. run adb devices to see that there are connected devices; for any connected device, you will be able to see its serial number





3. run the following command to generate the build.xml file; this file will be used further for generating the jar file with the test automation code

android create uitest-project -n AndroidProject -t 1 -p                                    C:\Users\home\workspace\AndroidProject


4. run the following command to generate the test automation jar file in the bin sub-folder from the project folder:

ant build



5. run the following command to deploy the jar file to the device:

adb push C:\Users\home\workspace\AndroidProject\bin\AndroidProject.jar  /data/local/tmp/






6. run the following command to execute the automated tests:

adb shell uiautomator runtest AndroidProject.jar -c AndroidProject




After starting the command, you can see everything taking place on the device.





From Manual Testing To Test Automation

The tester profession is relatively new compared with to the developer one.

Initially, the testing jobs were mostly about manual functional testing for client-server apps and websites.

Mobile devices and mobile applications existed on a very limited scale until a few years ago.

Many companies did not have a testing team at all so the testing of their products was done by their developers and clients.

Slowly, these companies begun to realize more and more that having a testing team is as important as having a development team.

So they hired many manual testers.

Being a manual tester was not difficult as, due of the novelty of the testing field, there was no formal education available.

Without formal education, a manual tester needed mostly soft skills and almost no technical ones:

– cognitive skills

– attention to details

– willingness to learn new things

– verbal and written communication

– ability of questioning how things work

– creativity

Testers were not technical compared to developers.

Test automation was in its infancy and the manual testing was in many cases the only testing done:



Things were good for manual testers for a number of years but then things started to change.

Websites were no longer sufficient for businesses so they launched mobile sites and native mobile apps.




The technology and testing advanced too with Selenium, cloud computing, test automation and API testing gaining importance.

The amount of manual testing done for business applications started to change as companies began looking at automating the repetitive testing tasks so more complex testing is possible:



So where is manual testing today?

I occasionally speak to IT recruiters about the job market.

I asked them about the testing jobs available today.

Are manual testing jobs still in high demand?

One answer was the “pure” manual testing opportunities are few.

When one is available, the competition is fierce with 40-50 people applying for it.

There are, however, more and more opportunities for testers with test automation skills.

Many companies have test automation frameworks that need to be maintained and improved or want to start their own frameworks.

Another answer was that most of testing roles seem to be hybrid roles.



The job requirement is that the tester is cross-functional and know both manual testing, a programming language, and a test automation framework.

For this type of job opportunity, the competition is low.

The recruiters cannot often find qualified people available and positions stay open for a long time.

Will this trend continue?

I believe that it will.

Testers that invest in their own career, know a programming language and have other technical skills will have the first chance of getting into the most of the job interviews  going forward. 

These testers will continue to get closer and closer to software developers in their daily job requirements and skills.

So manual testers will become software engineers in test or test developers.

Top 3 skills needed for test automation

You are a manual tester and think about starting to learn test automation. 

And you heard that, in automation projects,  test automation skills are being used such as 

- XPATH and CSS for creating web element locators 

- JUNIT for the automated test scripts 

- a programming language 

- a test automation framework (Selenium WebDriver for example) 

- page object model 

But which are the most important test automation skills?



Here they are: 

1. programming language 

2. programming language 

3. programming language 


Why is the programming language so important? 




Because record and play test automation does not work, despite what the test automation vendors say







Test automation means writing code that uses the test automation framework for interacting with an application. 



Based on this definition, you may say that learning a test automation framework is for sure one of the top 3 skills as well. 

Wrong! 

Let's take Java as an example of a programming language. 

Learning Java means that you will learn about 

- data types 

- variables 


- operators 


- simple statements (if/else, switch, for, while) 


- arrays 


- classes 


- objects 


- OOP concepts (inheritance, polymorphism)


- etc.



It also means learning how to use the classes included in the JAVA framework such as 

- List class

- File class

- Reader class

- Writer class

- Connection class

- ResultSet class

- XMLStreamReader class

- XMLStreamWriter class

- etc.




Once you understand how to use the JAVA framework, learning the Selenium WebDriver framework is straightforward because this is just another framework. 


So, learn a programming language and learn it well if you want to go far with your test automation projects

Which programming language you choose matters less. 

I suggest learning Java for Selenium test automation as most of the documentation/blogs/books use it. 

But you can learn as well Ruby or C#.

Test Automation Tips - dont use WebDriver APIs in your test script

If your WebDriver test scripts look similar to the following script, you are not doing test automation correctly:

@Test
public void testFirstResult() {

driver.get("http://www.vpl.ca");   


WebElement searchField = driver.findElement(By.xpath("//input[@id='globalQuery']"));


searchField.click();           

searchField.sendKeys("java");
    
WebElement searchButton = driver.findElement(By.xpath("//input[@class='search_button']"));

searchButton.click();        
            
WebElement searchResultLink = driver.findElement(By.xpath("(//a[@testid='bib_link'])[1]"));
    
searchResultLink.click();
        
WebElement bookTitleElement = driver.findElement(By.xpath("//h1[@id='item_bib_title']"));    
String bookTitleValue = bookTitleElement.getText();
      
assertEquals(bookTitleElement.isDisplayed(), true); 
assertTrue(bookTitleValue.length() > 0);
    
WebElement bookAuthorElement = driver.findElement(By.xpath("//a[@testid='author_search']"));
String bookAuthorValue = bookAuthorElement.getText();
      
assertEquals(bookAuthorElement.isDisplayed(), true); 
assertTrue(bookAuthorValue.length() > 0);

}


The script includes many WebDriver API objects and methods:


  • WebElement objects
  • driver.findElement() method
  • isDisplayed() method
  • getText() method
  • click() and sendkeys() methods()
  • get() method



Even if this script works correctly, it is very difficult to change and maintain.

Imagine having 50 scripts similar to this and some of them failing one day because of site changes (UI and functional).

Modifying 50 scripts would be a very difficult and time consuming task.

To remove the WebDriver API objects and methods from the test script, you should start using the Page Object Model.

"A page object wraps an HTML page, or fragment, with an application-specific API, allowing you to manipulate page elements without digging around in the HTML." Martin Fowler

What you need to do is create classes that correspond to web pages or web page components and implement the interaction with the site inside of them.

These classes will be used then by the test scripts.

All WebDriver API methods will be moved from the test scripts to the page object classes so a test script looks as follows:

@Test
public void testResultsInfo() throws InterruptedException{        

HomePage home = new HomePage(driver);


assertTrue(home.correctTitle());          

  
ResultsPage results = home.search();

assertTrue(results.correctTitle());


assertTrue(results.keywordDisplayed());            


assertTrue(results.resultsCount() > 0);         


}  


No WebDriver API classes and methods are included in this script.

The script uses 2 page object classes (HomePage and ResultsPage) that implement all interactions with the web pages.



Read more about Page Object Model on these 2 links:

http://martinfowler.com/bliki/PageObject.html

https://code.google.com/p/selenium/wiki/PageObjects