Use strutstestcase for test-driven development

Source: Internet
Author: User
Document directory
  • Introduction to strutstestcase
  • Strutstestcase practices
  • Test struts error handling
  • Custom test environment
  • Level 1 Performance Test
  • Conclusion
Use strutstestcase for test-driven development

Time: 2006-05-31
Author: John Ferguson smart
Browsing times:

788
Keyword: struts, strutstestcase, JUnit, J2EE, mockstrutstestcase, unit test, test-driven development
Document tools
Recommended to friends
Print article

Strutstestcase is a powerful and easy-to-use testing framework used to test struts actions. Combined with the traditional JUnit testing, Struts and strutstestcase will provide you with high coverage testing to improve product reliability.

Strutstestcase is a struts action test framework based on JUnit. Struts provides a simple and effective way to test the struts rule class of an application.

A typical J2EE application is built in layers. Its structure 1 is shown below:

  • The Dao layer encapsulates database access. These include hibernate ing, object class, Hibernate query, entity EJB, and other object-link Persistence Technologies.
  • The business layer includes more advanced business services. Ideally, the business layer is relatively independent of the database implementation. This layer often uses EJB transactions.
  • The presentation layer displays application data to users and explains user requests. In struts applications, this layer usually uses JSP/jstl pages to display data and uses STRUTS actions to explain Users' Query requests.
  • The client layer is primarily a web browser running on a user's machine. Client logic (such as JavaScript) is sometimes placed at this layer, although it is difficult to perform effective tests on it.


Figure 1: typical J2EE architecture

Depending on the specific architecture, Dao and business layers can use the JUnit classic test method or a variety of JUnit extension tools for testing. Dbunit is a good choice for testing database units. (For more information about dbunit, see the sensitive unit testing with dbunit written by Andrew glover.)

On the other hand, it is usually difficult to test struts actions. Even if the business logic is completely limited to the business layer, Struts actions usually include important data verification, data conversion, and data flow control code generation. If you do not test the struts action, the code coverage is left blank. Strutstestcase will fill these gaps.

Unit Tests on the Action layer bring other benefits:

  • The view layer and control layer are easier to design and generally more concise and clear.
  • It is easier to refactor the category class.
  • This helps avoid redundant and useless callback classes.
  • Test cases help you write action-layer documents that can help you compile JSP pages.

These are some of the common advantages of test-driven development. These advantages apply to the struts action layer and other places.

Introduction to strutstestcase

Strutstestcase provides a flexible and convenient way to test struts actions within the JUnit framework. You can set Request Parameters and check the request or session Status generated after the call Action to perform a white-box test on the struts action.

Strutstestcase supports the use of frameworks to simulate testing methods for Web Server containers, or the use of cactus frameworks in server containers (such as Tomcat) for testing. In general, I prefer the simulated testing method because it is more lightweight and runs faster, so as to achieve a more compact development cycle.

All strutstestcase unit test classes are derived from mockstrutstestcase for simulated testing or cactusstrutstestcase for intra-container testing. Because the simulated testing method is easier to set and runs faster, we will focus on the simulated testing method here.

Strutstestcase practices

To use strutstestcase to test this action, we will create a new class that extends the mockstrutstestcase class. This class provides some methods for building a simulated HTTP request, calling the corresponding struts action, and verifying the application status after the action is completed.

Imagine an online database for accommodation arrangement with a composite condition search function. The search function is implemented through the/search. Do action. This action performs a composite condition search based on a specific condition and places the search result list in the Results attribute. The scope of this attribute is within the request range. For example, the following URL will display a list Of all accommodation locations in France.

/search.do?country=FR

Now let's assume that we use the test driver method to implement this method. Compile the rule class to update the struts configuration file. Write a test case to test the testing class (null ). Use a strict test-driven development method. First, write test cases and then implement code that complies with the test cases. In actual situations, the specific sequence varies depending on the test code.

The initial test case should look as follows:

public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
}

Here, we set the call path (setrequestpathinfo () and add the request parameter (addrequestparameter ()).

Next, use the invoke class. In this way, the struts configuration is verified and the corresponding rule class is called, but the actual function of the action is not tested. To test the actual function of an action, we need to verify the action result.

public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyForward("success");
assertNotNull(request.getAttribute("results"));
}

Here, we need to verify three points:

  • No actionerror message (verifynoactionerrors ()).
  • The success redirection path is returned.
  • The results attribute is placed within the request range.

If the tiles framework is used, verifytilesforward () can also be used to check whether the success redirects to the correct tiles definition.

public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyTilesForward("success",
"accommodation.list.def");
assertNotNull(request.getAttribute("results"));
}

In practice, we may want to perform business-specific tests on the test results. For example, if the results attribute is expected to be a list containing 100 hotel domain objects, we need to confirm that all the hotels on the list are in France. To implement such a test, the Code must be very similar to the standard JUnit test:

public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyForward("success");
assertNotNull(request.getAttribute("results"));
List results
= (List) request.getAttribute("results");
assertEquals(results.size(), 100);
for (Iterator iter = results.iterator();
iter.hasNext();) {
Hotel hotel = (Hotel) iter.next();
assertEquals(hotel.getCountry,
TestConstants.FRANCE);
...
}
}

You may want to test a series of actions in a more complex test scenario. For example, you can search all French hotels and click any search result to view details. Suppose we have a struts action that shows the details of a specific hotel. This action can be called as follows:

/displayDetails.do?id=123456

With strutstestcase, we can easily simulate a series of actions in the same test. You can search all French hotels and click View Details.

public void testSearchAndDisplay() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
actionPerform();
verifyNoActionErrors();
verifyForward("success");
assertNotNull(request.getAttribute("results"));
List results
= (List) request.getAttribute("results");
assertEquals(results.size(),100);
Hotel hotel = (Hotel) results.get(0);

setRequestPathInfo("/displayDetails.do");
addRequestParameter("id", hotel.getId());
actionPerform();
verifyNoActionErrors();
verifyForward("success");
Hotel hotel
= (Hotel)request.getAttribute("hotel");
assertNotNull(hotel);
...
}
Test struts error handling

The error handling test is very important. Suppose we want to test whether the application has good error response capability when error country code is given. We compile a new test method and use verifyactionerrors () to check the error message (errormessages) returned by struts ):

public void testSearchByInvalidCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "XX");
actionPerform();
verifyActionErrors(
new String[] {"error.unknown,country"});
verifyForward("failure");
}

Sometimes we want to directly verify the data in the actionform object. We can use getactionform () for implementation, as shown in the following example:

public void testSearchByInvalidCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "XX");
actionPerform();
verifyActionErrors(
new String[] {"error.unknown,country"});
verifyForward("failure");
SearchForm form = (SearchForm) getActionForm();
assertEquals("Scott", form.getCountry("XX"));
}

Here, we verify that the country code of the error is properly saved in actionform after the error occurs.

Custom test environment

Sometimes, we need to override the setup () method, which allows us to specify various non-default configuration options. In this example, we use another struts-config.xml file and set the xml configuration file validation to invalid:

public void setUp() { 
super.setUp();
setConfigFile("/WEB-INF/my-struts-config.xml");
setInitParameter("validating","false");
}
Level 1 Performance Test

A test action or a series of actions is an excellent way to test whether the response time is within the acceptable range. By testing struts actions, we can check the performance of the entire server (when JSP page generation is not included ). A good way is to perform some level-1 performance tests at the unit test level to quickly separate and eliminate performance problems, and integrate the solutions into the compilation process to avoid performance degradation.

Below are some of my basic principles for a level-1 struts performance test:

  • Use combinations of conditions as much as possible for multi-condition queries to verify the correctness of the index definition.
  • Query a large amount of data (a large number of results are returned for this query) to test the response time and result paging (if any ).
  • Perform a single and repeated query test (check the cache performance when the cache policy is used ).

Some open-source libraries can help with performance testing, such as junitperf created by Mike Clark. However, the integration of these databases with strutstestcase is troublesome. In many cases, a simple counter can help solve this problem. The following is a simple and effective method for performing a level-1 performance test:

public void testSearchByCountry() {
setRequestPathInfo("/search.do");
addRequestParameter("country", "FR");
long t0 = System.currentTimeMillis();
actionPerform();
long t1 = System.currentTimeMillis() - t0;
log.debug("Country search request processed in "
+ t1 + " ms");
assertTrue("Country search too slow",
t1 >= 100)
}
Conclusion

In general, unit testing is an important part of Agile programming methods, especially for test-driven development. Strutstestcase provides a simple and effective method for performing unit tests on Struts actions, which is hard to be implemented through JUnit.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.