Testing Ajax with Arquillian
With ever growing demands on a rich and highly interactive user interface across a wide range of devices, automated testing becomes a crucial part of development routine. To my experience, it is often arguable whether the effort spent on writing tests really pays off. Arquillian is a tool I value for its ease of use and overall effectiveness. Today, I would like to share an example of how Arquillian can be used to test an Ajax-driven web application.
To keep the demo easy to follow the application is limited to choosing a preferred color. This idea is not mine. After some googling around I got inspired by an example at Rob’s.
@RunWith(Arquillian.class) public class SimpleWebTest { .. import org.jboss.arquillian.junit.Arquillian; import org.jboss.arquillian.container.test.api.Deployment; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.EmptyAsset; .. @Deployment(testable=false) public static WebArchive createDeployment() { return ShrinkWrap.create(WebArchive.class, "login.war") .addClasses(Credentials.class, User.class, Login.class) .addAsWebResource(getFile("login.xhtml")) .addAsWebResource(getFile("home.xhtml")) .addAsWebInfResource(getFile("faces-config.xml")) .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); } .. }
To make this happen we have to tell Arquillian where to find the application server. In the arquillian.xml:
<container qualifier="jboss7" default="true"> <configuration> <property name="jbossHome"> /Users/tom/apps/jboss-as-7.1.1.Final </property> </configuration> </container>
Let’s move on the actual testing. The application is powered by JSF 2.0 and all server calls are asynchronous to cater for partial page updates. Testing Ajax could be cumbersome. Fortunately, Arquillian provides an enhanced Selenium extension called Graphene which makes this task really simple:
import org.jboss.arquillian.drone.api.annotation.Drone; import org.jboss.arquillian.ajocado.framework.GrapheneSelenium; import static org.jboss.arquillian.ajocado.Graphene.waitForXhr; import static org.jboss.arquillian.ajocado.Graphene.id; .. public static final IdLocator CHANGE_COLOR_BUTTON = id("menu:changeColor"); .. @Drone private GrapheneSelenium browser; .. // The button click triggers an Ajax request. waitForXhr(browser).click(CHANGE_COLOR_BUTTON); // The change is done. Let's test the results ..
Another feature I find extremely useful is the ability to capture screenshots during the test execution. To me, the ability to visually retrospect substantial UI changes increases credibility of the automated testing and adds to overall confidence in the development team. Capturing a screen boils down to a single call:
browser.captureScreenshot();
In fact, it is way too simple. I would expect I could pass a file name as argument. Nevertheless, I was able to work around this limitation by using the ImageIO library:
import javax.imageio.ImageIO; .. ImageIO.write(browser.captureScreenshot(), "png", new File("screenshots/" + filename + ".png")); ..
Here is an example of what to expect. Notice the highlighted radios:
All in all, I enjoyed using Arquillian and see a great potential in it. The only drawback is a lengthy list of maven dependencies. I won’t bore you with further details, all you need is to read the docs, first two guides will do.
That’s all I wanted to say today. As usual, the source code is attached at the end of the post. Next time, I will look into Arquillian on a mobile platform.
Download Source Code or Explore It