The QuickStart contains sample code and guidance to get you started with JWebUnit. To see all of the methods available, consult the a 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 ExampleWebTestCase(String name) {
super(name);
}
}
import junit.framework.TestCase;
import net.sourceforge.jwebunit.junit.WebTester;
public class ExampleWebTestCase extends TestCase {
private WebTester tester;
public ExampleWebTestCase(String name) {
super(name);
tester = new WebTester();
}
}
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 ExampleWebTestCase(String name) {
super(name);
setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT);
}
}
Navigation is a two step process. First, point the TestCase to your application, then access a particular resource. Let's say that your app is running on http://myserver:8080/myapp . To minimize the number of the times we must set this, we set this either in the constructor or in the setUp() method of the TestCase.
public ExampleWebTestCase(String name) {
super(name);
getTestContext().setBaseUrl("http://myserver:8080/myapp");
}
public void setUp() throws Exception {
setTestingEngineKey(TestingEngineRegistry.TESTING_ENGINE_HTMLUNIT);
getTestContext().setBaseUrl("http://myserver:8080/myapp");
}
Now that the TestCase is pointed at your application, you can navigate to a particular resource. For example, if you have a html page, info.html, located under your application root, then you can access it in a test method with the following code:
public void testInfoPage() {
beginAt("/info.html");
}
<a id="addLink" href="/addPage">Add Widget</a>
<a id="editlink" href="/editPage">Edit Widget</a>
public void testMainPageLinks() {
beginAt("/mainPage");
assertLinkPresent("addLink");
clickLink("addLink");
assertTitleEquals("Widget Add Page");
beginAt("/mainPage");
assertLinkPresentWithText("Edit Widget");
clickLinkWithText("Edit Widget");
assertTitleEquals("Widget Edit Page");
}
You can navigate to a page with a form, check for the presence and correct default values of form elements, set form element values, and submit the form.
public void testFormSubmission() {
beginAt("/info.html");
assertFormPresent("expectedFormName");
assertFormElementPresent("field1");
assertFormElementEquals("field2", "field2_defaultValue");
setTextField("field1", "value1");
setTextField("fieldn", "valuen");
submit();
}
public void testFormSubmission() {
beginAt("/info.html");
assertFormPresent("expectedFormName");
assertSubmitButtonPresent("Add");
assertSubmitButtonPresent("Modify");
setTextField("field1", "value1");
submit("Modify");
}
public void testBottomFormSubmission() {
beginAt("/twoForm.html");
setWorkingForm("bottomForm");
submit();
}
public void testPopupButton() {
beginAt("/info.html");
assertButtonPresent("popupButtonId"); //clickButton will assert this also.
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
//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"); //optional as window above.
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 {
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 .