JSFUnitPerformanceAnalysis

Introduction

JSFUnit provides a JSFTimer class that tracks the time spent in each phase of the JSF lifecycle.  It also allows you to see the total lifecycle time.  The JSFTimer remains accurate, even when JSF lifecycle phases are skipped.  And, it can be used in your application code as well as in JSFUnit tests.

 

Enabling the JSFTimer

The JSFTimer is disabled by default.  To enable it, you need to add the JSFTimerPhaseListener to your test setup.  You can add this in your application's faces-config.xml, but it is cleaner to do it in a separate file so that you don't have to modify the application.  JSFUnit only requires modification to web.xml.  So you can add a declaration for the new file there.  To configure it this way, add this to your "jsfunified" web.xml:

<context-param>
  <param-name>javax.faces.CONFIG_FILES</param-name>
  <param-value>/WEB-INF/timer-config.xml</param-value>
</context-param>

Your timer-config.xml file will look like this:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE faces-config PUBLIC
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>
  <lifecycle>
    <phase-listener>org.jboss.jsfunit.framework.JSFTimerPhaseListener</phase-listener>
  </lifecycle>
</faces-config>

Geting a reference to JSFTimer

You just call the static getTimer() method to get a timer for the previous (or current) request.  If you are using the timer from within the JSF lifecycle, it will return accurate statistics for time spent up to the last completed phase.

JSFTimer timer = JSFTimer.getTimer();

 

Using the JSFTimer in a JSFUnit Test

A typical test case is to make sure that JSF request processing doesn't fall below a certain threshold in regression tests.  A new JSFTimer instance is created for each request, so you need to call getTimer() after each submit.  Note that total time is returned in milliseconds.

public void testJSFPerformance() throws IOException
{
   JSFClientSession client = new JSFClientSession("/index.faces");
   client.setValue("inputText", "Foo"); 
   client.click("submit_button");
   
   JSFTimer timer = JSFTimer.getTimer();
   assertTrue(timer.getTotalTime() < 3000);
}

 

This test case makes sure that the application processing phase didn't take too long:

public void testAppLogicPerformance() throws IOException
{
   JSFClientSession client = new JSFClientSession("/index.faces");
   client.setValue("inputText", "Foo"); 
   client.click("submit_button");
   
   JSFTimer timer = JSFTimer.getTimer();
   assertTrue(timer.getPhaseTime(PhaseId.INVOKE_APPLICATION) < 2000);
}

 

Using the JSFTimer outside of JSFUnit Tests

The JSFTimer can be used outside of JSFUnit tests.  You just need to put the JSFUnit core jar in your WEB-INF/lib directory and add the phase-listener declaration as shown above.  When using the JSFTimer in this way, you would reference the JSFTimer from your application code instead of your tests.