35.3. Integration testing Seam application user interactions

It is more difficult to emulate user interactions, and to place assertions appropriately. Some test frameworks let us test the whole application by reproducing user interactions with the web browser. These are useful, but not appropriate during development.
SeamTest lets you write scripted tests in a simulated JSF environment. A scripted test reproduces the interaction between the view and the Seam components, so you play the role of the JSF implementation during testing. You can test everything but the view with this approach.
Consider a JSP view for the component we unit tested above:
<html>
  <head>
    <title>Register New User</title>
  </head>
  <body>
    <f:view>
      <h:form>
        <table border="0">
          <tr>
            <td>Username</td>
            <td><h:inputText value="#{user.username}"/></td>
          </tr>
          <tr>
            <td>Real Name</td>
            <td><h:inputText value="#{user.name}"/></td>
          </tr>
          <tr>
            <td>Password</td>
            <td><h:inputSecret value="#{user.password}"/></td>
          </tr>
        </table>
        <h:messages/>
        <h:commandButton type="submit" value="Register" 
                         action="#{register.register}"/>
      </h:form>
    </f:view>
  </body>
</html>
We want to test the registration functionality of our application (that is, what happens when a user clicks the Register button). We will reproduce the JSF request life cycle in an automated TestNG test:
public class RegisterTest extends SeamTesFt {
   
  @Test
  public void testRegister() throws Exception {
            
    new FacesRequest() {

      @Override
      protected void processValidations() throws Exception {
        validateValue("#{user.username}", "1ovthafew");
        validateValue("#{user.name}", "Gavin King");
        validateValue("#{user.password}", "secret");
        assert !isValidationFailure();
      }
         
      @Override
      protected void updateModelValues() throws Exception {
        setValue("#{user.username}", "1ovthafew");
        setValue("#{user.name}", "Gavin King");
        setValue("#{user.password}", "secret");
      }

      @Override
      protected void invokeApplication() {
        assert invokeMethod("#{register.register}").equals("success");
      }

      @Override
      protected void renderResponse() {
        assert getValue("#{user.username}").equals("1ovthafew");
        assert getValue("#{user.name}").equals("Gavin King");
        assert getValue("#{user.password}").equals("secret");
      }
    }.run();   
  }
  ...
}
Here, we extend SeamTest to provide a Seam environment for our components, and our test script is written as an anonymous class that extends SeamTest.FacesRequest, which provides an emulated JSF request life cycle. (There is also a SeamTest.NonFacesRequest for testing GET requests.) Our code includes methods named for various JSF phases, to emulate the calls that JSF would make to our components. We have then included various assertions.
The Seam example applications include integration tests demonstrating more complex cases. You can run these tests with Ant, or with the TestNG plug-in for Eclipse:

35.3.1. Configuration

If you created your project with seam-gen, you can start writing tests immediately. Otherwise, you must first set up a testing environment in a build tool such as Ant, Maven, or Eclipse.
You will require at least the following dependencies:

Table 35.1. 

Group ID Artifact ID Location in Seam
org.jboss.seam.embedded hibernate-all lib/test/hibernate-all.jar
org.jboss.seam.embedded jboss-embedded-all lib/test/jboss-embedded-all.jar
org.jboss.seam.embedded thirdparty-all lib/test/thirdparty-all.jar
org.jboss.seam.embedded jboss-embedded-api lib/jboss-embedded-api.jar
org.jboss.seam jboss-seam lib/jboss-seam.jar
org.jboss.el jboss-el lib/jboss-el.jar
javax.faces jsf-api lib/jsf-api.jar
javax.el el-api lib/el-api.jar
javax.activation javax.activation lib/activation.jar
Do not put the compile-time JBoss Enterprise Application Platform dependencies from lib/ (such as jboss-system.jar) on the classpath, as this will prevent Embedded JBoss from booting. Add dependencies such as Drools and jBPM as you require them.
You must include the bootstrap/ directory on the classpath, since it contains the configuration for Embedded JBoss.
You must also include your built project, tests, and the jar for your test framework on the classpath, as well as configuration files for JPA and Seam. Seam asks Embedded JBoss to deploy any resource (JAR or directory) with seam.properties in its root. If the structure of the directory containing your built project does not resemble that of a deployable archive, you must include seam.properties in each resource.
By default, a generated project uses the java:/DefaultDS (a built in HSQL datasource in Embedded JBoss) for testing. To use another datasource, place the foo-ds.xml into bootstrap/deploy directory.