Enter Selenium.
Selenium is an open source project for automating UI testing.
Let us write a JUnit test which uses Selenium to test the UI for the JSON example project we created in the earlier post.
First, we need to download the selenium.jar.
Update your ivy.xml to create a dependency on Selenium, like this:
(Note - due to the way my internal repository is setup, I had to explicitly declare dependencies on other jars on which Selenium depends - you might not have to do this if you are pointing to the Maven central repository).
<ivy-module version="2.0">
<info organisation="org.confucius" module="helloworld"/>
<dependencies>
<dependency org="commons-logging" name="commons-logging" rev="1.1.1"/>
<dependency org="org.apache.httpcomponents" name="httpcore" rev="4.2-alpha2"/>
<dependency org="org.apache.httpcomponents" name="httpclient" rev="4.2-alpha1"/>
<dependency org="org.apache.commons" name="commons-exec" rev="1.1"/>
<dependency org="com.google.guava" name="guava" rev="r09"/>
<dependency org="org.seleniumhq.selenium" name="selenium-api" rev="2.17.0"/>
<dependency org="org.seleniumhq.selenium" name="selenium-remote-driver" rev="2.17.0"/>
<dependency org="org.seleniumhq.selenium" name="selenium-firefox-driver" rev="2.17.0"/>
<dependency org="org.seleniumhq.selenium" name="selenium-java" rev="2.16.1"/>
<dependency org="junit" name="junit" rev="4.10"/>
<dependency org="org.json" name="json" rev="20090211"/>
<dependency org="javax.servlet" name="servlet-api" rev="2.5"/>
<dependency org="javax.servlet" name="jsp-api" rev="2.0"/>
<dependency org="jstl" name="jstl" rev="1.2"/>
<dependency org="log4j" name="log4j" rev="1.2.16"/>
</dependencies>
</ivy-module>
Run the Ant resolve target to download all the jars.
Next, we need to update Eclipse Classpath to include these jars.
Go to Project->Properties->Java Build Path ->Add Jars
and add all the newly downloaded jars.
We also need to update the Classpath for Ant.
Update your build.xml to include the new jars, like this:
<project name="HelloWorld" xmlns:ivy="antlib:org.apache.ivy.ant" >
<target name="resolve" description="--> retrieve dependencies with ivy">
<ivy:retrieve />
</target>
<target name="init" depends="resolve">
<mkdir dir="classes"/>
<mkdir dir="target"/>
</target>
<path id="build.classpath">
<pathelement location="lib/commons-logging-1.1.1.jar"/>
<pathelement location="lib/httpcore-4.2-alpha2.jar"/>
<pathelement location="lib/httpclient-4.2-alpha1.jar"/>
<pathelement location="lib/commons-exec-1.1.jar"/>
<pathelement location="lib/guava-r09.jar"/>
<pathelement location="lib/selenium-api-2.17.0.jar"/>
<pathelement location="lib/selenium-firefox-driver-2.17.0.jar"/>
<pathelement location="lib/selenium-java-2.16.1.jar"/>
<pathelement location="lib/selenium-remote-driver-2.17.0.jar"/>
<pathelement location="lib/junit-4.10.jar"/>
<pathelement location="lib/json-20090211.jar"/>
<pathelement location="lib/servlet-api-2.5.jar"/>
<pathelement location="lib/jsp-api-2.0.jar"/>
<pathelement location="lib/log4j-1.2.16.jar"/>
</path>
<target name="compile" depends="init">
<javac srcdir="." destdir="classes">
<classpath refid="build.classpath"/>
</javac>
</target>
<path id="test.classpath">
<pathelement location="classes"/>
<pathelement location="lib/junit-4.10.jar"/>
<pathelement location="lib/selenium-api-2.17.0.jar"/>
<pathelement location="lib/selenium-firefox-driver-2.17.0.jar"/>
<pathelement location="lib/selenium-java-2.16.1.jar"/>
<pathelement location="lib/selenium-remote-driver-2.17.0.jar"/>
<pathelement location="lib/guava-r09.jar"/>
<pathelement location="lib/commons-exec-1.1.jar"/>
<pathelement location="lib/httpclient-4.2-alpha1.jar"/>
<pathelement location="lib/httpcore-4.2-alpha2.jar"/>
<pathelement location="lib/commons-logging-1.1.1.jar"/>
</path>
<target name="test" depends="compile" >
<junit failureproperty="junit.failure">
<test name="org.confucius.TestCalculator"/>
<classpath refid="test.classpath"/>
<formatter type="plain" usefile="false" />
</junit>
<fail if="junit.failure" message="Unit test(s) failed. See reports!"/>
</target>
<target name="dist" depends="test">
<war destfile="target/HelloWorld.war" webxml="web.xml">
<classes dir="classes"/>
<lib dir="lib">
<exclude name="jsp-api*.jar"/>
<exclude name="servlet-api*.jar"/>
</lib>
<fileset dir="web-content"/>
<webinf dir="WEB-INF"/>
</war>
<echo>Build executed at ${TIME_NOW}</echo>
</target>
<tstamp>
<format property="TIME_NOW" pattern="hh:mm:ss aa MM/dd/yyyy"/>
</tstamp>
</project>
We also need to give an "id" to the button in HelloWorld.jsp, like this:
<html>
<head>
<script src="../js/jquery-1.7.1.min.js"></script>
<script type="text/javascript">
function getMusicSchool()
{
// Create AJAX object
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest(); // IE7+, Firefox, Chrome, Opera, Safari
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); // IE6, IE5
// Associate a method for AJAX response
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200) // Successful response
getJSONObject(xmlhttp.responseText);
}
// Send AJAX request
xmlhttp.open("GET","http://localhost:8080/HelloWorld/music-school",true);
xmlhttp.send();
}
function getJSONObject(jsonStr)
{
if (null != jsonStr && 0 != jsonStr.length)
{
alert(jsonStr)
try
{
jsonObj = $.parseJSON( jsonStr );
displatStr = jsonObj.name + ", located at " + jsonObj.address + " teaches " + jsonObj.instruments.length + " instruments, including " + jsonObj.instruments[1] + ".";
alert(displatStr);
}
catch(e)
{
alert(e.toString());
}
}
}
</script>
</head>
<body>
<form>
<button id="musicButton" type="button" onclick="getMusicSchool()">Show Music School</button>
</form>
</body>
</html>
Now let us write a Junit test and use Selenium to test the UI.
In your /test/org/confucius folder, create a class TestHelloWorldUI.java, like this:
package org.confucius;
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;
import junit.framework.TestCase;
public class TestHelloWorldUI extends TestCase {
public void testMusicSchool(){
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:8080/HelloWorld/jsp/HelloWorld.jsp");
WebElement element = driver.findElement(By.id("musicButton"));
element.click();
Alert jsonAlert = driver.switchTo().alert();
String jsonText = jsonAlert.getText();
String expectedJSONString = new String("{\"address\":\"9000 Cliff Drive, Santa Cruz, California\",\"name\":\"Beethoven Music School\",\"instruments\":[\"Piano\",\"Guitar\",\"Trumpet\",\"Violin\"]}");
assertTrue(jsonText.trim().equals(expectedJSONString.trim()));
jsonAlert.accept();
Alert javascriptAlert = driver.switchTo().alert();
String javascriptText = javascriptAlert.getText();
String expectedJavascriptString = new String("Beethoven Music School, located at 9000 Cliff Drive, Santa Cruz, California teaches 4 instruments, including Guitar.");
assertTrue(javascriptText.trim().equals(expectedJavascriptString.trim()));
javascriptAlert.accept();
driver.close();
}
}
Note that we are testing in the Firefox browser.
In the above test:
- We open a browser
- Go to http://localhost:8080/HelloWorld/jsp/HelloWorld.jsp
- Click on the musicButton
- Check the text in the alert boxes which popup
- Close the browser
If you run this JUnit test, you will see the Browser popup and Selenium clicking around.
No comments:
Post a Comment