Since we wrote this post we didn't laze around. Check our latest announcement.

The Arquillian team is proud to announce the 1.0.0.Alpha1 release of the Arquillian Warp component!

Have you ever wanted to test a web application using real HTTP requests, but still have the opportunity to verify server-side state and behavior?

Wouldn’t it be great to have the full power of Arquillian Drone, driving Selenium or WebDriver on the client, then combine that with an Arquillian in-container test?

Now you can!

Ike’s innovative army has created yet another powerful weapon for your testing arsenal, Arquillian Warp.

Testing on both sides of the request

Arquillian Warp fills the void between client-side and server-side testing. Using Warp, you can initiate an HTTP request using a client-side testing tool such as WebDriver and, in the same request cycle, execute in-container server-side tests. This powerful combination lets you cover integration across client and server.

Now you can send real requests that execute real application logic and render content in a real browser and test it end-to-end. Mocks? Who needs those? Imagine the debugging possibilities this opens up!

This may sound like sci-fi, but it’s a reality. It’s advanced alien technology for killing real bugs that you can get your hands on today!

Let’s warp to the code

We’ll start with a normal Arquillian Drone client-side test with one enhancement, a @WarpTest annotation on the test class. This extra annotation instructs Arquillian Warp to enhance the request.

@WarpTest @RunWith(Arquillian.class) public class BasicWarpTest { @Drone WebDriver browser; @ArquillianResource URL contextPath; @Deployment public static WebArchive createDeployment() { ... } @Test @RunAsClient public void test_initial_page() { // triggers a HTTP request to a server browser.navigate().to(contextPath); // stay tuned... } }

Note that you can use any HTTP client. For the sake of simplicity we’ve used @Drone to hook WebDriver (Selenium 2) into our test. Additionally, we’ve declared a web archive to be tested and injected its URL into the test case.

So far, we’ve defined a basic Drone test. Let’s start to warp this test so we can use it to test server-side logic as well. We begin by defining an implementation of ServerAssertion as an inner class of the test:

public static class InitialRequestAssertion extends ServerAssertion { @Inject TowelBean towel; @AfterPhase(RENDER_RESPONSE) public void test_initial_state() { // verify we are on right viewId assertEquals("/index.xhtml", FacesContext.getCurrentInstance().getViewRoot().getViewId()); // assert the bean state assertNull(42, towelBean.getAnswerToLife()); } }

An object of this assertion class will be later enriched on the server (i.e., TowelBean will be injected) and then the lifecycle method annotated with @AfterPhase will be invoked in an appropriate phase of the request (after the response is rendered in the JSF lifecycle). This lifecycle method is effectively our server-side test.

All we need to do now is hook this assertion class to the request that is initiated by the browser. To do that, we warp the Selenium call in a Warp action:

@Test @RunAsClient public void test_initial_page() { // define the client action which will lead to HTTP request Warp.execute(new ClientAction() { public void action() { // the original request browser.navigate().to(contextPath); } // enhance the subsequent HTTP request with ServerAssertion }).verify(new InitialRequestAssertion()); }

That’s it! Here’s how it plays out:

The Selenium-controlled browser initiates an HTTP request The request is trapped and enhanced with the InitialRequestAssertion object (which gets added as a payload of the request) When the request arrives at the server, the InitialRequestAssertion assertion object is registered with Arquillian and the request lifecycle proceeds After the response is rendered on the server, the InitialRequestAssertion object is enriched with all the required resources (EJB beans, CDI beans, Spring beans or Arquillian resources) and the lifecycle (test) method is invoked Once the request is complete, the InitialRequestAssertion object is sent back to the client If anything on the server-side failed (including assertions you defined), the failure is propagated back to the client and handled as a test failure

Currently, Warp supports lifecycle callbacks for the Servlet and JSF lifecycles, but it’s designed to be able to handle any server-side lifecycle.

Some of the highlights in this release

Support for Servlet events Warp gives you the ability to test any Servlet lifecycle with these two lifecycle annotations: @BeforeServlet – triggered before the request is processed by the Servlet

@AfterServlet – triggered after the request is processed by the Servlet

Support for JSF lifecycle events (Phaser extension) Warp’s Phaser extension provides integration with the JSF lifecycle. You can use these lifecycle annotations to test the application in any JSF phase: @BeforePhase(Phase) – triggered before the given JSF phase is executed

@AfterPhase(Phase) – triggered after the given JSF phase is executed

Compatible with any HTTP client Warp works with any HTTP client: Selenium, HtmlUnit, HttpUnit, REST client, JavaScript test, Android device. No boundaries here!

Open to more protocols Only the HTTP protocol is supported currently, but other protocols can be supported as well! (An SPI will be defined in a later releases)

Open to more frameworks Warp is designed to support any server-side web framework based on the Servlets API

Need to know more?

You can find the complete Maven-based sample usage in the Arquillian Showcase.

Additionally, you can look at the functional tests in the Warp test suite:

Roadmap

In future releases, we’ll be looking into further improving the extension, most notably by providing framework-specific enrichments:

Injectable HttpServletRequest

Injectable FacesContext

etc.

Warp offers many possibilities for integration:

Support for wide range of server-side web frameworks (Wicket, Vaadin, GWT, Tapestry, …)

(Wicket, Vaadin, GWT, Tapestry, …) Support for alternative protocols (WebSockets)

(WebSockets) Built-in support for variety of client-side testing tools

Call to action

If you would like to have support for your favorite web framework, you see features that are missing or you can see room for improvement, don’t hesitate and come to the Arquillian forums or the #arquillian channel on Freenode IRC!

We would love to hear your ideas and feedback for how to stretch Warp to reach beyond the boundaries of the test galaxy!

What is Arquillian?

Arquillian is open source software that empowers you to test JVM-based applications more effectively. Created to defend the software galaxy from bugs, Arquillian brings your test to the runtime so you can focus on testing your application's behavior rather than managing the runtime. Using Arquillian, you can develop a comprehensive suite of tests from the convenience of your IDE and run them in any IDE, build tool or continuous integration environment.

Release details

Published artifacts org.jboss.arquillian.extension

Release notes and resolved issues 9

First Release of Warp Extension

Enhancement ARQ-931 - Warp: Define API/SPI

ARQ-933 - Warp: server exception propagation

ARQ-948 - Make the ServerAssertion abstract class to ensure future compatibility

ARQ-955 - Warp: Define BOM

Feature Request ARQ-578 - Create a Extension for handling Server State assertion during normal Servlet/JSF requests

ARQ-957 - Add Warp Showcase sample

Bug ARQ-935 - Should handle de-enrich of final fields

ARQ-943 - Should be able to detect Serialization problems

Thanks to the following list of contributors: Lukas Fryc, Ken Finnigan, Aslak Knutsen