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.
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!");
}
}
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!");
}
}
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
}
}
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
}
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();
}
public void testPopupButton() {
beginAt("/info.html");
assertButtonPresent("popupButtonId"); // clickButton() will also check this
clickButton("popupButtonId");
assertWindowPresent("popupWindow");
}
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");
...
}
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."):
}
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);
}
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");
}
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");
}
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.