Using Java Remote Method Invocation

Overview

This arctile is a slightly off topic from the normal themes but worth writing about as it’s a tricky subject. The content below is from some slides i produced:

Agenda

•Introduction
•Why Use RMI
•Overview Of RMI
•Sample App
•Gotchas
•More reading

Introduction

•Remote Method Invocation allows method calls to be made from one Java Virtual Machine (JVM) to another JVM
•Operates A Client/Server Model where The Server ‘registers’ classes it wishes to be available for clients to access

Why Use RMI

•Removes the complexity of using Sockets to communicate
•Allows a level of control over which objects you can access
•Makes it easier to simulate real life client/server scenarios
•Lends itself well to TDD

Overview Of RMI

•RMI Registry – holds a list of stub references which have be registered by server application
•Server application – defines interfaces and concrete implementations to be registered on RMI Registry
•Client application – connects to the RMI registry in order to make use of servers classes

Overview Of RMI

overview

Sample Code: Server Application

sampleServer

 

Sample Client Application:

sampleClient

Gothcas:

•How do you make the compile classes available without copying them – use a webserver and have the client code download the classes dynamically
•Connection refused when running clientApp: Check serverApp is running first
•Class not found in client project: make sure you have copied the latest copy of your serverAppImpl.class to the client project
•Class not found exception when running client: ensure on the server application you have imported all of the classes your serverApp requires
More Reading

 

Webdriver Advanced usage tutorial

In this post i talk about the more complex usages of WedDriver which you will inevitably have to face when creating automated tests. If you are new to webdriver i would recommend reading my webdriver basics tutorial first which can be found here

The topics i’m going to discuss are:

– staleElementException explained

– waiting for elements to appear on the page

– testing pages which involve AJAX

StaleElementException explained

Sooner or later you’re going to come across this webdriver exception when you are using driver.findBy() or using WebElement to perform some function on the page. So what does this actually mean ? So this exception is thrown when you are trying to do something on the page which has already changed state since your previous webdriver command. An example of this could be grabbing the items in a dropdown box and then trying to click on one of these items when the dropdown is no longer on the page (either because webdriver has navigated to another page or that item is no longer in the list)

So how can you avoid this? The techniques below will help reduce the likelihood of this occurring. One quick fix is to grab a new instance of the page when the exception is thrown in your tests where this happens often. This means that you have got the ‘most current’ state of the webpage. This should highlight whether or not you should be waiting for other actions to complete on the page first.

Waiting For Elements To Appear On The Page

Another common exception you will face is ElementNotFoundException. This is where webDriver cannot find the element you are looking for even though you know it’s on the page.  This happens because webDriver is not waiting for the element to appear on the page and has received a Dom complete operation from the page. This can happen when you are trying to find elements on the page which involve Javascript. The solution to this problem is to use a polling mechanism on these elements. The code below will continually poll the page every 500ms for 30 seconds waiting for an element to displayed.  This gives enough time for all of the Javascript to complete on the page. As soon as the element appears, the method will return.

public static ListwaitUntilPageLoadedListWebElements(WebDriver driver, By by) {
int pollCount=0;
while (pollCount<sleeptimeout) {
try{
Thread.sleep(250);
List<WebElement> elements =driver.findElements(by);
if(elements.size()>1 ) {
return elements=driver.findElements(by);
}
}catch (Exception e) {
pollCount=pollCount+250;
System.out.println(“waiting for element”);
}
}
return null;
}

The above code will continually poll for an element to be present until the timeout is reached or the element is found. I’ve passed in a ‘By’ as a parameter which means that you could find by id, find by linktext, classname etc

Testing Pages Which Involve AJAX

Webdriver has no idea when AJAX has completed so could return a documentReady state when AJAX is still progressing on the page. An example of this could be that documentReady has been returned but AJAX on the page is still adding and removing elements on the page. This can lead to both elementNotFound and staleElement exceptions thrown by webDriver. One solution to this problem is to insert a custom element into the dom and wait for it to be removed by AJAX. This will let you know that AJAX has finished updating the page and has removed your custom element

WebDriver driver;

JavascriptExecutor js = (JavascriptExecutor) driver;

js.executeScript(“document.getElementById(‘myDiv’).appendChild(document.createTextNode(‘ WaitForAJax’))”) //code to add custom element to the DOM

private void verifyAJaxCompleted() throws Exception{
int sleeptimeout=30000;
int pollCount=0;
while (pollCount<sleeptimeout) {
Thread.sleep(250);
WebElement element =driver.findElement(By.id(“search-gen-res”));
if(element.getText().contains(“WaitForAjax”) ) {
pollCount=pollCount+250;
System.out.println(“waiting for AJax To Complete”);;
}else {
return;
}
}
throw new Exception(“Ajax Update Did not Complete Within 30s”);
}

so the code above creates a custom txt element to the node “search-gen-res”. The method waitForAjax method will return one the custom element is no longer present. If the element did not get removed from the page during the AJAX request then an exception is thrown

Summary

This arcticle touches on some of the more advanced features of webdriver when using feature rich webpages and explains how to avoid staleElementExceptions

Website Testing 101 – Webdriver basic usage tutorial

In this day and age, websites are complex and are changing all the time. A software tester cannot simply perform manual regression testing on a new piece of functionality without having some reliance on automated tests. There are a number of tools out there each with their own benefits but this article will be focusing on the one which I’ve had most experience: Webdriver. The aim of this article is to get you up and running quickly with using this tool.

So what is Webdriver?

Webdriver allows you to simulate actions performed by a user and then verifying the state of the page after actions have been performed. This can be done using a virtual browser (also called a headless browser) or by physically opening a browser on the user’s desktop to perform the actions a typical user would (e.g., clicking on links, selecting items in a drop-down list etc). The headless browser is unable to perform any actions which require JavaScript to be executed on the page. The benefit of the headless browser is that it’s much faster than opening a physical browser and does provide a close enough environment akin to a real browser.

What do i need to use Webdriver?

you will need the following:

– Latest version of Java SDK: Java SDK  (Webdriver can be used with out languages but my preference is Java)

– An IDE: I would recommend Intellij IDEA as it’s awesome: IntelliJ IDEA

– Webdriver JAR’s: Webdriver JAR

– Latest Version Of Firefox (Other browsers can be used by I’m going to focus on Firefox for this tutorial)

– Firebug add-on for Firefox.

Setting up your environment

Step 1: download all of the above files

Step 2: Create a new project and import the Webdriver jar into it

How Webdriver and website testing works

So before we dive in a write some code i need to give an overview of what we’re going to use Webdriver for in terms of Website testing. Webdriver works by looking for elements on the page, interacting with them and verifying the outcome of the interaction is correct.

An element can be something like a button, a link on a page, a checkbox etc. By interacting with them i mean the following:

– Checking if is on the page

– Checking the status of an element (e.g. if a checkbox is disabled)

– Clicking on an element to perform some other action

The final part is verifying the outcome. We do this by performing assert statements at the end of the interaction. Asserting something is verifying an element is in the state you expect it to be. Examples of these can be AssertTrue, AssertEqual, etc. Asserting statements are included within the Webdriver Jar

A very simple example

So the first thing we’re going to do is make sure that the Jar file has been imported correctly into your project and that you can load a Firefox browser. Copy and paste the following code into your IDE:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

public class AppInit {
public static void main(String args[]) {
WebDriver driver= new FirefoxDriver(new FirefoxProfile());
}
}

If you get any errors regarding classes not found then you have not imported the selenium jar correctly. Not only do you have to import the single jar but also ALL the jars in the lib folder. Run this code and it should load a Firefox browser at the end of it. So lets look over the code:

WebDriver driver= new FirefoxDriver(new FirefoxProfile());

so WebDriver is an interface that other classes implement (e.g. FirefoxDriver) so it cannot be instantiated. The FirefoxDriver takes an argument of a FirefoxProfile. The FirefoxProfile allows you customize what type of Firefox Browser is loaded (e.g. a non caching browser). In this example i have loaded a default profile.

Lets look some more basic commands:

driver.get(URL) //allows you to navigate to different pages

driver.findElement(By) // allows you to find elements on the page you are interested in. Remember, an element can be a dropdown menu, a button etc. A few examples of finding an element are find by ID, by Name, by Link Text. We’ll go into more detail on this later.

driver.findElements(By) // when there is more that one item with the same name/id then you can store them in an array

driver.close() //closes the firefox browser

WebElement //once you have found the element you are looking for, you can assign it to a WebElement object. This then allows you to perform operations on it such as clicking, sending text to it, checking if it is disabled etc

So lets put all of this together into another example:

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

public class AppInit {
public static void main(String args[]) {
WebDriver driver= new FirefoxDriver(new FirefoxProfile());
driver.get(“http://www.amazon.co.uk&#8221;);
WebElement element= driver.findElement(By.id(“twotabsearchtextbox”));
element.sendKeys(“kindle”);
element.sendKeys(Keys.ENTER);
}
}

So this code is navigating to the amazon website, finding the search box by id and then performing a kindle search. But how did you know the id of the search box i hear you ask? This is where firebug comes into play. So I went to the amazon homepage manually, right clicked on the search box and selected inspect element with firebug. I was then presented with the following image below:

As you can see from the image it has input id=”” . This is what I’m searching for when using driver.findElement(By.id()). I would recommend using finding by id’s rather than link text as they are less like to change.

So the final part of the example is using asserts. This is making sure that the actions you have performed actually produce the desired outcome. Again we’re going to stick with the amazon example but add some verification steps too:

import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import java.util.List;

import static org.testng.Assert.assertEquals;

public class AppInit {
public static void main(String args[]) {
WebDriver driver= new FirefoxDriver(new FirefoxProfile());
driver.get(“http://www.amazon.co.uk&#8221;);
WebElement element= driver.findElement(By.id(“twotabsearchtextbox”));
element.sendKeys(“kindle”);
element.sendKeys(Keys.ENTER);

List<WebElement> elements =driver.findElements(By.className(“number”));
assertEquals(16,elements.size());
}
}

So in the last 2 steps we’re looking for the number of results on the page and asserting that the number of search results on the page is 16. If this changed for any reason then the assert statement would fail. Try it yourself, change the assertEqual to 17 and see what happens. Other asserts you could have used here are checking the page URL is correct by writing assertEquals(“User is not on the correct page”,”http://amazon.co.uk/search&#8221;,driver.getCirrentURL())

Summary

So this article has talked about the need for automated testing and a basic introduction on how to perform this using WebDriver. The next article in this series will look at more advanced features including waiting for elements to be displayed and polling for elements to be in the correct state