Testing JSF applications with JSFUnit

In this recipe, we will discuss the JSFUnit, which is a JBoss framework for testing JSF applications. JSFUnit is based on the well known JUnit framework, but is more dedicated to JSF, because it runs in the container and it was created for understanding the main JSF concepts, such as JSF lifecycle, JSF components, Faces Context, EL expressions, and so on.

To describe it in detail, JSFUnit can be used for the following tests (as you can conclude from the following list, JSUnit can test JSF-specific tasks and more):

  • Managed beans
  • Navigation rules
  • Invalid input
  • View components
  • Application configuration
  • Anything else

Getting ready

We developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.

When this book was written, the JSFUnit stable version was 1.1.0 GA. You can download this version from http://labs.jboss.com/jsfunit/downloads/. Depending on your needs, you can download:

  • JSFUnit Core (this is used in our example)
  • JSFUnit RichFaces/Ajax4jsf
  • JSFUnit Ant
  • JSFUnit Deployer for JBoss AS 5.x

In addition, Maven fans can download JSFUnit distributions from JBoss Maven Repository at http://repo1.maven.org/maven2. The POM declarations are:

<repositories>
<repository>
<id>jboss</id>
<name>JBoss Repository</name>
<url>http://repository.jboss.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<!-- Core jar needed for all JSFUnit tests -->
<dependency>
<groupId>org.jboss.jsfunit</groupId>
<artifactId>jboss-jsfunit-core</artifactId>
<version>1.1.0.GA</version>
</dependency>
<!-- RichFaces and Ajax4jsf Client jar -->
<dependency>
<groupId>org.jboss.jsfunit</groupId>
<artifactId>jboss-jsfunit-richfaces</artifactId>
<version>1.1.0.GA</version>
</dependency>
<!-- Ant task used to "jsfunify" a WAR file -->
<dependency>
<groupId>org.jboss.jsfunit</groupId>
<artifactId>jboss-jsfunit-ant</artifactId>
<version>1.1.0.GA</version>
</dependency>

Finally, you can try to access it directly from the JBoss Maven Repository at http://repository.jboss.org/maven2/org/jboss/jsfunit/.

Note

JSFUnit 1.1.0 GA is updated to the latest beta version of JSF 2, so now you can use JSFUnit with JSF 1.1, JSF 1.2, and JSF 2.0 Beta 2. It is important to use HtmlUnit 2.5 instead of 2.4. The JSFUnit libraries (including necessary dependencies) are in the book bundle code, under the /JSF_libs/JSFUnit JSF 2.0 folder. The Xerces and Xalan distributions are required only if the container doesn't provide one or if you explicitly want to use others. These are, however, totally excluded in JBoss 5.x AS.

How to do it...

Next, we will develop a JSFUnit test for a basic JSF application named Working_with_JSFUnit. For starters, we present the pure JSF application, without any JSFUnit involved. After that, we will configure the JSFUnit test, and we will make proper configurations.

Our application contains three parts as follows (the code is very simple and self explanatory, therefore no more details are provided):

  • The start page (a simple JSF form):
    …
    <h:form id="UserForm">
    <h:outputText value="Enter your name:"/>
    <h:inputText value="#{userBean.firstName}" id="userId" />
    <h:commandButton value="Submit"
    action="response?faces-redirect=true"
    id="submit_button"/>
    </h:form>
    …
    
  • The end page (displays what was inserted into the form):
    …
    <h:outputText value="Inserted name:"/>
    <h:outputText value="#{userBean.firstName}"/>
    …
    
  • And a simple managed bean:
    package users;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    @ManagedBean
    @SessionScoped
    public class UserBean {
    private String firstName = "Rafael Nadal";
    public String getFirstName(){
    return this.firstName;
    }
    public void setFirstName(String firstName){
    this.firstName=firstName;
    }
    }
    

Now we write a JSFUnit test for the application. Conforming to the documentation (http://www.jboss.org/community/wiki/JSFUnitDocumentation), we wrote a test for the previous managed bean, as follows (in the JSFUnit API recipe, you can see more snapshots of using the JSFUnit API):

package tests;
import java.io.IOException;
import javax.faces.component.UIComponent;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.jboss.jsfunit.jsfsession.JSFServerSession;
import org.jboss.jsfunit.jsfsession.JSFSession;
public class JSFUnitTest extends org.apache.cactus.ServletTestCase
{
public static Test suite()
{
return new TestSuite( JSFUnitTest.class );
}
public void testInitialPage() throws IOException
{
// Send an HTTP request for the initial page
JSFSession jsfSession = new JSFSession("/index.xhtml");
// A JSFServerSession gives you access to JSF state
JSFServerSession server = jsfSession.getJSFServerSession();
// Test navigation to initial viewID
assertEquals("/index.xhtml", server.getCurrentViewID());
// Assert that the prompt component is in the
//component tree and rendered
UIComponent prompt = server.findComponent("userId");
assertTrue(prompt.isRendered());
// Test a managed bean
assertEquals("Rafael Nadal",
server.getManagedBeanValue("#{userBean.firstName}"));
}
}

Before we can run our test, we must configure JSFUnit in web.xml by adding the following lines (these lines will configure JSFUnitFilter and two servlets, ServletRedirector and ServletTestRunner):

<filter>
<filter-name>JSFUnitFilter</filter-name>
<filter-class>
org.jboss.jsfunit.framework.JSFUnitFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>JSFUnitFilter</filter-name>
<servlet-name>ServletTestRunner</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>JSFUnitFilter</filter-name>
<servlet-name>ServletRedirector</servlet-name>
</filter-mapping>
<servlet>
<servlet-name>ServletRedirector</servlet-name>
<servlet-class>
org.jboss.jsfunit.framework.JSFUnitServletRedirector
</servlet-class>
</servlet>
<servlet>
<servlet-name>ServletTestRunner</servlet-name>
<servlet-class>
org.apache.cactus.server.runner.ServletTestRunner
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletRedirector</servlet-name>
<url-pattern>/ServletRedirector</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletTestRunner</servlet-name>
<url-pattern>/ServletTestRunner</url-pattern>
</servlet-mapping>

The reports generated by JSFUnit are rendered through a stylesheet, known as cactus-report.xsl (this is developed under the Apache Cactus project—main page at http://jakarta.apache.org/cactus/). This stylesheet can be downloaded from http://jakarta.apache.org/cactus/misc/cactus-report.xsl, and it should be placed in the /web folder of our application.

After you complete these three steps you can deploy the application and run the test using the next URL:

http://localhost:8080/Working_with_JSFUnit/ServletTestRunner?suite=tests.JSFUnitTest&xsl=cactus-report.xsl

If everything works fine, you should be able to see something like the following screenshot:

How to do it...

How it works...

Well, the important thing here is the part where we run the test. Notice that the test is executed through a servlet named ServletTestRunner that gets two parameters as follows:

  • suite: The value of this parameter represents the fully qualified name of the JSFUnit test class.
  • xsl: The value of this parameter represents the name of an XSLT (EXtensible Stylesheet Language Transformations) document (in our case the cactus-report.xsl).

There's more...

The hardest part about using JSFUnit is preparing your WAR, since the configuration steps are slightly different depending on the platform used. At http://www.jboss.org/community/wiki/GettingStartedGuide page you can find a simple JSFUnit example (including the code) for the following platforms:

  • For older servlet containers (Tomcat 5, Jetty 5, and so on)
  • For non-JEE servlet containers that support JSP 2.1 (Tomcat 6, Jetty 6, and so on)
  • For JEE 5 containers such as JBoss AS 4.2 and Glassfish
  • For JBoss AS 5.x

See also

The code bundled with this book contains a complete example of this recipe. The project can be opened with NetBeans 6.8 and it is named: Working_with_JSFUnit.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset