Version 6, last updated by johan.seland at 15 May 20:42 UTC
Testing With Selenium
Highlevel testing with Selenium
It’s surprisingly easy to test your web applications using Selenium. You have to do the following:
- Get the Selenium jars and add them to your project (see code below for SBT users)
- Write tests using your favorite testing library. In this example we’ll use ScalaTest.
In your tests you want to do the following before running any tests:
- Start your web application programmatically
- Start the Selenium client programmatically
You can either record tests using the Selenium firefox plugin and export as java code and translate to Scala or just can simply write the tests by hand.
Add the following to your SBT Project definition to grab the jars:
"org.scalatest" % "scalatest" % "1.6.1" % "test->default",
"org.seleniumhq.selenium" % "selenium-java" % "2.21.0" % "test->default",
Now you can create a test class like this:
class AddEventTest extends FunSuite with BeforeAndAfterAll with Logger {
private var server : Server = null
private var selenium : WebDriver = null
private val GUI_PORT = 8080
private var host = "http://localhost:" + GUI_PORT.toString
override def beforeAll() {
// Setting up the jetty instance which will be running the
// GUI for the duration of the tests
server = new Server(GUI_PORT)
val context = new WebAppContext()
context.setServer(server)
context.setContextPath("/")
context.setWar("src/main/webapp")
server.addHandler(context)
server.start()
// Setting up the Selenium Client for the duration of the tests
selenium = new HtmlUnitDriver();
selenium.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
override def afterAll() {
// Close everyhing when done
selenium.close()
server.stop()
}
// a test to navigate to the list Events page, from there click the 'New Event' link
// create a new Event entry, and then check that the new Event is on the
// list page
val listPageURL = host + "/event/listevent"
val createPage = host + "/event/createevent"
val listPageTitle = "App: List Events"
// create random name to help avoid clashes with existing names
val eventNameText = Random.nextString(8)
test("From the list page add an new event" ) {
// navigate to our list page
selenium.get(listPageURL)
// check that we are on the right page
expect(listPageTitle) {selenium.getTitle}
// check the link to create a new event exists and that it points to the right page
// note that findElement throws an exception if it cannot find requested item
var newEventLink: Box[WebElement] = tryo( selenium.findElement(By.linkText("New Event")) )
assert(newEventLink.map(_.getAttribute("href")).openOr("") == createPage)
// get the html node that contains the list of events
var eventList: Box[WebElement] = tryo( selenium.findElement(By.id("eventlist")) )
assert(! eventList.isEmpty )
// get the <td class="eventName">..</td> elements within the list
// note we've just asserted that eventList is not empty, so OK to use open_!
var events : scala.collection.mutable.Buffer[WebElement]=
eventList.map(_.findElements(By.className("eventName"))).open_!
// make sure none of them contain the new name
assert(!events.map(_.getText).contains(eventNameText))
// navigate to the new event page
newEventLink.foreach(_.click)
// locate the name input element
var eventName: Box[WebElement] = tryo(selenium.findElement(By.id("eventname")))
assert(!eventName.isEmpty)
// enter the value text of the name and submit
eventName.foreach(x => {
x.sendKeys(eventNameText)
x.submit
})
// we should now be back at the list page
expect(listPageTitle) {selenium.getTitle}
var eventList2: Box[WebElement] = tryo( selenium.findElement(By.id("eventlist")) )
assert(! eventList2.isEmpty )
// get the <td class="eventName">..</td> elements within the list
// note we've just asserted that eventList is not empty, so OK to use open_!
var events2 : scala.collection.mutable.Buffer[WebElement]=
eventList2.map(_.findElements(By.className("eventName"))).open_!
// now make sure one of them contain the new name
assert(events2.map(_.getText).contains(eventNameText))
}