Arquillian Warp 1.0.0.Alpha2 Released

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

It has been a pretty long road from Alpha1 to this release, focused primarily on polishing the user experience.

So without any further ado, let’s look at the new shiny features!

Highlighted Features

Renaming Warp API methods

The API methods were renamed according to the results of our public survey. (read more)

In the simplest scenario you want to inspect the first request after performing a given client activity. For this purpose, you can use a basic Warp API known from Alpha1:

Warp
    .initiate(Activity)
    .inspect(Inspection);

This will intercept the first request coming from the client and ignore the rest of the potential requests.

Additionally, Warp will ignore requests for favicon.ico which could fail your test unexpectadly.

You can find more samples for this API in a source .

Anonymous and Inner Classes

It’s now much easier to define a verification code, which is also more readable.

In Alpha1, you had to use a top-level or a static inner classes to define inspections.

In Alpha2, you can provide non-static inner class or even anonymous class.

HelloWarp.java
Warp
    // first you need to initiate activity which triggers HTTP request
    .initiate(new Activity() {
        public void perform() {
            ajaxButton.click();
        }
    })

    // and then specify what behavior should be inspected on the server
    .inspect(new Inspection() {

        // don't forget to specify serialVerionUID to allow serialization
        private static final long serialVersionUID = 1L;
        
        // bring JSF context via dependency injection
        @ArquillianResource
        FacesContext facesContext;

        // verify expected behavior in given request phase
        @AfterPhase(RESTORE_VIEW)
        public void beforeServlet() {
            assertTrue(facesContext.isPostback());
        }
    });

This example showed how to use the new API together with anonymous inspections

Multiple Requests / Request Groups

It is possible to intercept several requests during one Warp execution.

Warp allows you to verify more than one request triggered by a single client activity. This allows you to verify e.g. a request for HTML page and all its resources (JS, CSS, images) separately. This feature is called Request Groups.

TestRequestGroups.java
// Request Group execution will return WarpResult
WarpResult result = Warp
    .initiate(Activity)
    // a group specification without name - the name will be generated
    .group()
        .observe(HttpRequestFilter)
        .inspect(Inspection1)
    // a named group specification - the result can be easily accessed
    .group("second")
        .observe(HttpRequestFilter)
        .inspect(Inspection2)
    // you need to execute whole Request Group once it is completely specified
    .execute();
    
    // you can access details of finished execution
    result.getGroup("second").getInspection();

The Request Groups execution returns a WarpResult which contains details about the finished execution. In order to access the results related to a specific group, you can give the group a name

Request Observers & Fluent API

The new API for observing the correct request allows you to select which request should be verified on a server.

When using Request Groups, all of the requests will be inspected by the inspections defined in that group. There might be one or more requests verified by each group.

Since multiple request can be triggered, you might want to choose the correct request to observe. For this purpose, we have the HttpRequestFilter interface, where you specify which HttpRequest should matches the current group.

import static org.jboss.arquillian.warp.client.filter.http.HttpFilters.request;

// will accept only requests for HTML
...group()
    .observe(request().uri().contains(".html"))

// will accept only REST requests for JSON
...group()
    .observe(request().header().containsValue("Accept", "application/json"))

// will accept only POST requests
...group()
   .observe(request().method().equal(POST))

In order to simplify writing the Warp specifications, you can define the observer using a fluent API and static factory methods.

Dependency Injection for Servlets and JSF

Test enrichers now allow the the injection of Servlet and JSF resources. (read more)

Renaming Phaser to Warp JSF

The JSF specific extension was renamed from Phaser to Warp JSF. (read more)

Introduction of Dependency Chain

The dependency chain was introduced to bring in all necessary dependencies by specifying just one dependency. (read more)

Warp Extensions for REST and Spring MVC

Thanks to Jakub Narloch, we have two new additions to Arquillian Galaxy. (read more)

Under the Hood

Usability and Debugging Improvements

A focus of Alpha2 was to polishing the way Warp behave in case of failures and on debuggability of Warp execution.

Validation of Warp Specification

Warp now validates that the number of observed requests match a number of expected requests. It also makes sure that all of defined lifecycle callbacks are executed on the server, to avoid any false positives.

As you can see there are many of new features, so let’s look at them separately:

Renaming Warp API

After Alpha1 we got several requests for clarifying the Warp high-level API:

Warp.execute(ClientAction).verify(ServerAssertion)

The announced survey helped us choose the new API. As a result, 88% of participants reported they found this new API more natural:

Warp.initiate(Activity).inspect(Inspection)

Big thanks to everyone who participated in the survey! This type of collaboration makes me really proud to be part of the team.

Warp Extensions: REST and Spring MVC

Warp was from the beginning built as a project that focused on any framework/technology that is based on top of the Servlet API.

Thus it’s not surprising that there are already two extensions shaping out thanks to Jakub Narloch:

Introduction of Dependency Chain

Putting Warp to work in your Maven project is now as easy as defining a single dependency:

pom.xml
<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-warp</artifactId>
    <version>1.0.0.Alpha2</version>
    <type>pom</type>
</dependency>

This declaration will bring Warp core, which supports Servlet API lifecycle callbacks.

Renaming Phaser to Warp JSF

Initially we had created Phaser as the next generation of the successful JSFUnit. It occured to use that Phaser is an unfortunate name and it just makes it harded to understand the Arquillian eco-system.

That’s why we have come up with a simpler variant – so let me introduce the Warp JSF extension.

You can bring Warp JSF to your project just by adding the following declaration:

pom.xml
<dependency>
    <groupId>org.jboss.arquillian.extension</groupId>
    <artifactId>arquillian-warp-jsf</artifactId>
    <version>1.0.0.Alpha2</version>
</dependency>

Dependency Injection for Servlets and JSF

After the announcement of the Alpha1 release, we focused on improving Warp to come closer to the Arquillian goal: bring all necessary dependencies to the test (in our case to inspection).

Now, you can not only inject all CDI managed beans (@Inject), EJB beans (@EJB) or container managed resources @Resource, but you can also inject the following resources:

  • Servlet resources
    • ServletRequest or HttpServletRequest
    • ServletResponse or HttpServletResponse
  • JSF resources
    • FacesContext
    • Application
    • ELContext, ELResolver, ExpressionFactory
    • ExceptionHandler
    • Flash
    • NavigationHandler
    • PartialViewContext
    • RenderKit
    • ResourceHandler
    • StateManager
    • UIViewRoot
    • ViewHandler

Migration from Alpha1

We’ve create a little bash script to convert the java source from Alpha1 API to Alpha2 that might help you with the upgrade.

How to Learn Warp?

The best way now is to look at functional tests for Warp or Warp JSF.

Roadmap

The roadmap to Beta1 is pretty clear:

  • documentation and guides
  • adding features known from SeamTest and JSFUnit
  • new injections and event hooks (e.g. improved CDI integration)
  • hardering and usability enhancements (here we rely on your issue reports!)

Along the way we will welcome every idea for integrating Warp with your favorite web framework – so don’t be a stranger and come to us!

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

Component Arquillian Warp
Version 1.0.0.Alpha2 view tag
Release date 2013-01-08
Released by Lukas Fryc
Compiled against

Published artifacts org.jboss.arquillian.extension

  • org.jboss.arquillian.extension » arquillian-warp-bom pom
  • org.jboss.arquillian.extension » arquillian-warp-api jar pom
  • org.jboss.arquillian.extension » arquillian-warp-spi jar pom
  • org.jboss.arquillian.extension » arquillian-warp-impl jar pom
  • org.jboss.arquillian.extension » arquillian-warp-jsf jar pom

Release notes and resolved issues 35

Renaming API methods according to survey; Anonymous/Inner Class; Request Observers/Filters

Bug
  • ARQ-972 - Warp tests should be excluded from scanning by CDI container
  • ARQ-973 - Warp: if primitive field in ServerAssertion is changed during test, it is wrongly changed to initial value on deenrichment
  • ARQ-976 - The exceptions that occurrs in @AfterServlet test is not being propagated back to the client.
  • ARQ-982 - Response header size exceeded in Warp test.
  • ARQ-992 - Warp does not support request redirection.
  • ARQ-1063 - Warp: when both ServerAssertion and ClientAction fails, server error should be reported
  • ARQ-1163 - Warp: response is not properly commited
  • ARQ-1174 - Warp: DeploymentEnricher should check whether current TestClass is annotated with WarpTest
  • ARQ-1195 - Warp: do not remove static inner classes from deployment
  • ARQ-1197 - Warp: report that serialVersionUID was not set for Inspection
  • ARQ-1254 - Warp: RequestPayload decides whether transform class for all inspections instead of each inspection at own
Component Upgrade
  • ARQ-1052 - Upgrade Arquillian Core to 1.0.3.Final
  • ARQ-1053 - Upgrade Arquillian Drone to 1.1.0.Final
Enhancement
  • ARQ-979 - Exposed BeforeServlet and AfterServlet events to SPI
  • ARQ-980 - Make ServletRequest an injectable resource
  • ARQ-981 - Move BeforeServlet and AfterServlet events to SPI
  • ARQ-1060 - Fail to start a Warp test when @Deployment(testable=false) and when no @RunAsClient present
  • ARQ-1120 - Warp: safe propagation server-side failures to client-side
  • ARQ-1223 - Warp JSF: refactor PhaseLifecycleEvent to expose name of the event when debugging
  • ARQ-1224 - Warp: expose RequestContext and RequestScope to SPI
  • ARQ-1236 - Warp: filter favicon.ico requests by default
  • ARQ-1246 - Warp: single execution should observe only first request
Feature Request
  • ARQ-932 - Warp: support for inner/anonymous classes
  • ARQ-937 - Add usage examples to API/SPI classes
  • ARQ-964 - Verify that all tests in ServerAssertion has been called - prevents false negatives
  • ARQ-965 - Warp: Enable common JSF objects (FacesContext, Application) to be injected using @ArquillianResource
  • ARQ-967 - Warp: client-side filters for waiting for "right" request or enriching several requests
  • ARQ-1056 - Warp: Enable common JSF objects (FacesContext, Application) to be injected using @Inject
  • ARQ-1057 - Warp: Resource provider for HttpServletRequest/HttpServletResponse
  • ARQ-1061 - Debug output from Warp when Arquillian logging enabled
  • ARQ-1073 - Warp: buffering writer/stream re-initializes on each getWriter/getOutputStream call
  • ARQ-1204 - Builder for Warp filters.
Task
  • ARQ-1054 - Warp: rename arquillian-warp-phaser to arquillian-warp-jsf
  • ARQ-1055 - Introduce Warp depchain
  • ARQ-1233 - Warp: rename API according to results of survey

Thanks to the following list of contributors: Lukas Fryc, Jakub Narloch, Martin Kouba, Brian Leathem, Aslak Knutsen