|
Recipe 13.8. Testing Application FunctionalityProblemYou want to verify that your application, deployed and running on an application server, does what it's supposed to do for a specific use case or scenario. SolutionUse the JWebUnit acceptance testing framework. DiscussionJWebUnit, an extension of the JUnit testing framework, leverages JUnit and Http-Unit for web application acceptance testing. JUnit provides the test harness and basic assertion methods, and HttpUnit (http://httpunit.sourceforge.net) provides a mechanism for programmatically sending requests and reading responses from a web application. JWebUnit exercises a running web application by programmatically sending requests, clicking links, filling out and submitting forms, and inspecting the response. To get started with JWebUnit, download it from the project site, http://jwebunit.sourceforge.net. The source distribution includes everything you need; the JWebUnit Jar file, dependent Jar files, documentation, and the JWebUnit source code. Create a test directory structure in your application's project directory like that shown in Figure 13-10. You will need to copy the Jar files included with JWebUnit to your test/lib directory. Figure 13-10. Project structure with "test" directoryThe easiest way to create a new JWebUnit test class is to subclass net.sourceforge.jwebunit.WebTestCase.
Example 13-11 shows a simple test case verifying that the jsc-ch13 web application is up and running. Example 13-11. Simple JWebUnit test casepackage com.oreilly.strutsckbk.ch13; import net.sourceforge.jwebunit.TestContext; import net.sourceforge.jwebunit.WebTestCase; public class SimpleWebTest extends WebTestCase { public SimpleWebTest(String name) { super(name); } public void setUp( ) throws Exception { TestContext testContext = getTestContext( ); testContext.setBaseUrl("http://localhost/jsc-ch13"); // Use the message resources properties file testContext.setResourceBundleName( "org.apache.struts.webapp.example.ApplicationResources" ); } public void testAppAvailable( ) { beginAt("/index.jsp"); // use the title text from the testContext resource bundle assertTitleEqualsKey("index.title"); } } You can run this test using any of the JUnit test runners. Like any other JUnit test, a successful test run is rather boring to look at; it's more interesting to look at a failed test. Figure 13-11 shows the results from Eclipse's JUnit test runner when the SimpleWebTest of Example 13-11 fails because the application server isn't running. Figure 13-11. Failed run of a JWebUnit test caseEvery JWebUnit test has a test context. This context, typically configured in the setUp( ) method, contains information applicable to the test case such as the base URL. In Example 13-11 this value was set to the web application's context: testContext.setBaseUrl("http://localhost/jsc-ch13"); You can use JWebUnit to test the internationalization features of your web application. The test context allows you to specify the resource bundle for your localized text as well as the locale being tested. JWebUnit looks up properties from the resource bundle using that locale. The locale that you set in the test context is only used on the client side to look up resource bundle properties. To mimic the browser's locale settings, you must set the Accept-Language header to the locale being tested. The Struts MailReader can be localized for Russian. Example 13-12 tests this localization by verifying that the response title has the correct value. Example 13-12. Using JWebUnit to test internationalizationpackage com.oreilly.strutsckbk.ch13; import java.util.Locale; import net.sourceforge.jwebunit.TestContext; import net.sourceforge.jwebunit.WebTestCase; public class LocaleWebTest extends WebTestCase { public LocaleWebTest(String name) { super(name); } public void setUp( ) throws Exception { testContext = getTestContext( ); testContext.setBaseUrl("http://localhost/jsc-ch13"); testContext.setResourceBundleName( "org.apache.struts.webapp.example.ApplicationResources" ); } public void testRussian( ) { testContext.setLocale(new Locale("ru")); testContext.getWebClient( ).setHeaderField("Accept-Language","ru"); beginAt("/index.jsp"); assertTitleEqualsKey("index.title"); } private TestContext testContext; } Want more you say? JWebUnit shines at testing application scenarios and use cases. Say you wanted to verify the registration process of the Struts MailReader. The following simple case illustrates this process:
You can create a JWebUnit test case that implements this use case, as shown in Example 13-13. Example 13-13. Testing user registrationpackage com.oreilly.strutsckbk.ch13; import com.meterware.httpunit.HttpUnitOptions; import net.sourceforge.jwebunit.TestContext; import net.sourceforge.jwebunit.WebTestCase; public class RegistrationWebTest extends WebTestCase { public RegistrationWebTest(String name) { super(name); } public void setUp( ) throws Exception { // disable JavaScript handling HttpUnitOptions.setScriptingEnabled(false); TestContext testContext = getTestContext( ); testContext.setBaseUrl("http://localhost/jsc-ch13"); testContext.setResourceBundleName("org.apache.struts. webapp.example.ApplicationResources"); } public void testRegistration( ) { // start at the welcome page beginAt("/index.jsp"); // find the registration link and click it String regLinkText = getMessage("index.registration"); clickLinkWithText(regLinkText); // check that the registration form is displayed assertFormElementPresent("username"); // use the current time as part of the username for repeatability long ts = System.currentTimeMillis( ); // fill out the form setFormElement("username","t"+ts); setFormElement("password","gotech"); setFormElement("password2","gotech"); String fullName = "George P. Burdell"; setFormElement("fullName", fullName); setFormElement("fromAddress","gpburdell@matech.com"); setFormElement("replyToAddress","gpburdell@matech.com"); // submit the form submit( ); // check that the main menu is displayed with the name included assertTextPresent(getMessage("mainMenu.heading")+' '+fullName); } public void tearDown( ) { // logoff to clean up the session gotoPage("/Logoff.do"); } } This test shows off the power of JWebUnit and, though hidden from view, HttpUnit. For complete details, download JWebUnit and give it a try! See AlsoOther tools provide similar functionality as JWebUnit. Canoo WebTest (http://www.canoo.com) uses an Ant-like XML file to describe a test scenario. If your test writers aren't comfortable with Java, then take a look at this excellent open source tool. |
|