When you are writing a JSFUnit test it is really important that you check for errors. It is sometimes quite easy to write tests that do not actually prove your page did what you wanted it to if you do not pay close enough attention to what you are writing.

 

This method is what I use to make sure there were no Error or Fatal messages after clicking an action. This also allows me to go back and look in my log file and see what those errors were so that debugging my tests is a lot easier.

 

 

public static boolean noErrorsFound(JSFServerSession server, Logger log)
    {
        boolean noErrors = true;
        Iterator<FacesMessage> iter =server.getFacesMessages();

 

        if (iter.hasNext() == false) {
            return noErrors;
        }
        // Error detected, lets log the messages for easy JSF Test debugging
        String view = server.getCurrentViewID();
        while (iter.hasNext()) {
            FacesMessage msg = iter.next();
            FacesMessage.Severity level = msg.getSeverity();
            if ((level.compareTo(FacesMessage.SEVERITY_WARN) > 0)) {
                log.warn("Face Message for " + view + ": " + level + " -> "
                    + msg.getDetail());
                noErrors = false;
            }
        }
        return noErrors;
    }

 

Now you just want to assertTrue(noErrorsFound(server, log)) after every action. Obviously using a nice heiarchy means that you only write this code once. My tests never call client.click(id); Instead, all my tests are abstracted away from the actual client and they call my GekkoClient.click(id).

So my GekkoClient.click(String id) method looks like this.

 

public void click(String id) {
        try {
            client.click(id); //Actual JSFUnit client
            validateNoErrorsFound();
        } catch (IOException e) {
            throw ExceptionUtils.createLogged(IllegalStateException.class, log,
                "Error when clicking on component with id: " + id, e);
        }
    }

 

private void validateNoErrorsFound() {
        try {
            Validate.isTrue(JsfUnitTestUtils.noErrorsFound(
server, log), //server = your JSFServerSession
                "An ERROR level faces message was detected. See log for details");
        } catch(IllegalArgumentException iae) {
            throw new IllegalStateException("FACES MESSAGE FOUND: above log lines should contain error");
        }
    }

 

Doing all this also makes it easier to debug your tests especially those of you that are new to JSFUnit. It really can drive you mad sometimes if you don't know what to look for.

public static boolean noErrorsFound(JSFServerSession server, Logger log)
    {
        boolean noErrors = true;
        Iterator<FacesMessage> iter =server.getFacesMessages();

 

        if (iter.hasNext() == false) {
            return noErrors;
        }
        // Error detected, lets log the messages for easy JSF Test debugging
        String view = server.getCurrentViewID();
        while (iter.hasNext()) {
            FacesMessage msg = iter.next();
            FacesMessage.Severity level = msg.getSeverity();
            if ((level.compareTo(FacesMessage.SEVERITY_WARN) > 0)) {
                log.warn("Face Message for " + view + ": " + level + " -> "
                    + msg.getDetail());
                noErrors = false;
            }
        }
        return noErrors;
    }

I'm making this post mainly because I was asked to help someone get JSFUnit running. I'm really much too busy at the moment to explain in detail how to do everything.

So, attached is the guess number example app with a simple JSFUnit test.

 

The main thing to note is the way the WAR is created using the jsf-unit-build ant task.

 

Once that task has been run deploy the newly created war that will be located in ${build.dir}/jsf-unit/guessNumber.war.

 

After that you can simply just navigate to: http://localhost:8080/guessNumber/ServletTestRunner?suite=test.GuessNumberTest&xsl=cactus-report.xsl.

 

 

Or, if you prefer to run your tests in eclipse open up the GuessNumberTest class and select run as junit. Ensuring that you have set your cactus.contextURL jvm arg as explained in this link http://community.jboss.org/wiki/UsingJSFUnitwithEclipse .

It should be something like -Dcactus.contextURL=http://localhost:8080/guessNumber

 

 

Hope this helps.

Tim

 

Attached is the source including the eclipse .project. It is pretty messy and you will need to make sure you fix up the class paths in the build.properties file to match your working environment.

Filter Blog

By date: By tag: