JWebUnit Quickstart

This quickstart contains sample code and guidance to get you started with JWebUnit. To see all of the methods available, consult the Javadocs - particularly the WebTestCase class for full documentation.

Creating a TestCase

JWebUnit uses two approaches for creating test cases: inheritance and delegation. The simplest is to inherit from WebTestCase rather than junit.framework.TestCase.

import net.sourceforge.jwebunit.junit.WebTestCase;

public class ExampleWebTestCase extends WebTestCase {
	
    public void setUp() {
        super.setUp();
        setBaseUrl("http://localhost:8080/test");
    }

    public void test1() {
        beginAt("/home");
        clickLink("login");
        assertTitleEquals("Login");
        setTextField("username", "test");
        setTextField("password", "test123");
        submit();
        assertTitleEquals("Welcome, test!");
    }
}
	
An alternative is to include an instance of the WebTester class in your TestCase and delegate navigation and assertions to it. This is provided in case you need or prefer delegation.
import junit.framework.TestCase;
import net.sourceforge.jwebunit.junit.WebTester;

public class ExampleWebTestCase extends TestCase {
    private WebTester tester;

    public void setUp() {
        super.setUp();
        tester = new WebTester();
    }
    
    public void test1() {
        tester.beginAt("/home");
        tester.clickLink("login");
        tester.assertTitleEquals("Login");
        tester.setTextField("username", "test");
        tester.setTextField("password", "test123");
        tester.submit();
        tester.assertTitleEquals("Welcome, test!");
    }
}
	
In the following samples, inheritance will be used.

Selecting the plugin you want to use

JWebUnit can use different plugins to execute the tests you write. Only one line makes the difference:

import net.sourceforge.jwebunit.junit.WebTestCase;
import net.sourceforge.jwebunit.util.TestingEngineRegistry;

public class ExampleWebTestCase extends WebTestCase {
    public void setUp() {
        super.setUp();
        setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT);    // use HtmlUnit
        setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_SELENIUM);    // use Selenium
    }
}
NB: If you have only one plugin in your classpath, you don't need to explicitly specify to use it, JWebUnit will find and use it.

Navigating Your Web Application

The primary way that JWebUnit allows you to test your web application is through navigation of the application itself. You can consider each test case as a use case through the application itself. The first step is to point where the testable application is hosted so that it may be accessed by JWebUnit.

    public void setUp() throws Exception {
        super.setUp();
        setBaseUrl("http://myserver:8080/myapp");
    }

Note that you should not be pointing to the production version of your web application, but rather a sandboxed development or testing server!

Now that the TestCase is pointed at your application, you can navigate to a particular resource to ensure that it exists, and contains the content you expect. For example, if your application starts at index.html and contains a link to your login page under "Login", you may test these assertions through the following code:

    public void testIndexLogin() {
        beginAt("/index.html");        // start at index.html
        assertTitleEquals("Home");     // the home page should be titled "Home"
        assertLinkPresent("Login");    // there should be a "Login" link
        clickLink("Login");            // click the link
        assertTitleEquals("Login");    // we should now be on the login page
    }
assertLinkPresent() searches for links by a string ID; assertLinkPresentWithText() searches for links that contain a text string. For more information on the differences between the various testing methods, check out the Javadocs.

Working With Forms

Now that we can access the Login page, we can use JWebUnit to fill out the form and assert that it works as expected.

    public void testFormSubmission() {
        beginAt("/login.html");
        assertTitleEquals("Login");    // we should be on the login page
        
        // fill out the form
        assertLinkNotPresent("Logout");		// we should not be logged in
        assertFormPresent("login_form");
        assertFormElementPresent("username");
        assertFormElementPresent("password");
        setTextField("username", "test");
        setTextField("password", "test123");
        assertFormElementEquals("username", "test");
        submit();
        
        // now that we have filled out the form,
        // we can assert that we can logout
        assertLinkPresent("Logout");		// we should now be logged in
    }

JWebUnit, through HtmlUnit/Selenium, automatically keeps track of cookies and session variables specified by the web application, allowing you to traverse through your site as if you were a normal user.

For pages with more than one form, JWebUnit will usually establish which form is being worked with implicitly from the form elements being accessed. You can also set the form explicitly by form ID or name:

    public void testBottomFormSubmission() {
        beginAt("/twoForm.html");
        setWorkingForm("bottomForm");
        submit();
    }
You can work with non-submit (type='button') buttons as well:
    public void testPopupButton() {
        beginAt("/info.html");
        assertButtonPresent("popupButtonId"); // clickButton() will also check this
        clickButton("popupButtonId");
        assertWindowPresent("popupWindow");
    }

Working With Frames and Windows

You can assert the presence of and navigate to windows by name. For instance, if clicking on a button on the root page should open a window, you could test for this and go to the popup window as follows:

    public void testPopupWindow() {
        beginAt("/rootPage.html");
        clickLink("popupLink");
        assertWindowPresent("popupWindow):  // optional - gotoWindow will// also perform this assertion.
        gotoWindow("popupWindow");
        ...
        gotoRootWindow();  //Use this method to return to root window.
    }

You can work with frames in a similar manner:

    public void testFrame() {
        beginAt("/info.html");
        assertFramePresent("contentFrame");
        gotoFrame("contentFrame");
        ...
    }

Validating Page Content

Once you have navigated to the page you wish to test, you can call the assertions provided by JWebUnit to verify it's correctness.

    public void testCorrectness() {
        beginAt("/mainPage");
        assertTitleEquals("Main Page");
        assertLinkPresentWithText("Add Widget");
        clickLinkWithText("Add Widget");
        setTextField("widgetName", "My Widget");
        submit();
        assertTextPresent("Widget successfully added."):
    }

Validating Table Content

A number of assertions are provided by JWebUnit to validate the contents of tables on a page. You can simply check for the presence of text within a table, or check layout of all or a portion of the table. HttpUnit is used to purge empty rows and columns from the actual table before comparison, so you may leave spacer cells and rows out of your check.

The below test validates against this html table (the table id attribute is "ageTable"):

Name Age
Jim 30ish
Wilkes 20ish

    public void testAgeTable() {
        beginAt("/agePage");
        // check that table is present
        assertTablePresent("ageTable");
        
        // check that a single string is present somewhere in table
        assertTextInTable("ageTable", "Jim");
        
        // check that a set of strings are present somewhere in table
        assertTextInTable("ageTable",
                          new String[] {"Jim", "Wilkes"});
                          
        // check composition of table rows/columns
        assertTableEquals("ageTable",
                          new String[][] {{"Name", "Age"},
                                          {"Jim", "30ish"},
                                          {"Wilkes", "20ish"}});
    }

If you need to validate non-blank table cells that span more than a single column, a set of classes are provided which represent expected tables, rows, and cells.

Age Table
Name Age
Jim 30ish
Wilkes 20ish

    public void testAgeTable() {
        beginAt("/agePage");
        ExpectedTable ageTable = new Table(new Object[][] {
            {new Cell("Age Table", 2, 1)},
            {"Name", "Age"},
            {"Jim", "30ish"},
            {"Wilkes", "20ish"}
        });
        assertTableEquals("ageTable", expectedAgeTable);
    }

Using Element IDs to Validate Content

JWebUnit allows you to check for the presence of any html element by its id, or for text in an element. This can be a useful trick to check for the presence of some logical part of the page. Even in the case of free floating text, a span element can be used to surround the text and give it a logical id:

<span id="welcomeMessage">Welcome, Joe User!</span>

    public void testWelcomeMessage() {
        beginAt("/mainPage");
        
        // check for presence of welcome message by text
        assertTextPresent("Welcome, Joe User!");
        
        // check for presence of welcome message by element id
        assertElementPresent("welcomeMessage");
        
        // check for text within an element
        assertTextInElement("welcomeMessage", "Joe User");
    }

Using Property Files to Validate Content

Another useful testing trick is to use property files for your expected values rather than hard-coded strings. This is especially useful if your application uses property files as a source for static text and messages. The same files can be used to provide the expected values for the tests.

For convenience, most of the JWebUnit assertions that take strings for the expected have an equivalent assertion that will take a property file key. You can use the TestContext to set the bundle to be used as well as the Locale (default is Locale.getDefault()).

    public void setUp() throws Exception {
        super.setUp();
        getTestContext().setbaseUrl("http://myserver:8080/myapp");
        getTestContext().setResourceBundleName("ApplicationResources");
    }

    public void testMainPage() {
        beginAt("/mainPage");
        assertTitleEqualsKey("title.mainPage");
        assertKeyPresent("message.welcome");
        assertKeyInTable("mainPageTable", "header.mainPageTable");
    }
There is also a getMessage() method on WebTester and WebTestCase that can be used to access resource bundle messages directly in your tests.

Whether to check for a given logical chunk of text by hard-coded string, property file lookup, or by use of an element id is up to you.

For more information, consult the Javadocs.