Struts behavior Test Framework Strutstestcase Combat

Source: Internet
Author: User
Tags config contains error handling http request implement query string access
   Read the summaryStrutstestcase is a powerful and easy-to-use test framework for struts behavior. Strutstestcase, combined with traditional junit testing, will bring you a fairly high test coverage and improve the reliability of your product.

   first, the introduction

Strutstestcase is a JUnit-based test framework for testing struts behavior. If you use struts, you will notice that it provides an easy and effective way to test your application's struts behavior class.

Typical Java EE applications are layered constructs, as shown in Figure 1.

· The DAO layer encapsulates database access. Hibernate mappings and object classes, hibernate queries, entity EJBs, or some other entity-relationship persistence technologies can be found at this level.

• The business layer contains more advanced business services. Ideally, the business layer would be relatively independent of the database implementation. Session EJBs are often used on this layer.

• The description layer includes displaying application data for the user and interpreting user requests. In a struts application, this layer typically uses JSP/JSTL pages to display data and uses struts behavior to interpret user queries.

• The customer layer is basically a Web browser running on the user's machine. Client logic (for example, JavaScript) is sometimes placed here, although it is difficult to test it effectively.


Figure 1. Typical Java EE architecture

The DAO and business layer tests can be done either by using classic JUnit tests or by using various JUnit extensions, depending on the implementation details of the architecture. Dbunit is a good choice for database unit testing.

On the other hand, it's always difficult to test struts behavior. Even when the business layer is strictly limited to the construction of the business layer, struts behavior includes important data validation, transformation, and Process Control code. Not testing struts behavior will leave a dirty gap in code coverage. Strutstestcase will let you fill this gap.

There are some other benefits to unit testing of the behavior layer:

• Better plan The view and control layer to make it simpler and clearer.

• More easily refactor behavior classes.

• Avoid redundant behavior classes that are not used.

• Test instances Help to archive the behavior layer-which is useful when creating screens.

This is based on the typical benefits of test development, and they can be applied to the struts behavior layer used in various situations.

  Ii. introduction of Strutstestcase

The Strutstestcase project provides a flexible and convenient way to test struts behavior from within the JUnit framework. It allows you to test your struts behavior in a white box-by establishing the request parameters after the call behavior and checking the status of the result request or session.

Strutstestcase allows or is a mock test method-when the framework simulates a Web server container, or a container-like approach-then uses the Cactus framework to run tests from within the server container, such as Tomcat. In general, I prefer to imitate test methods because it is lighter and faster, and thus allows for looser development cycles.
All Strutstestcase unit test classes are either derived from Mockstrutstestcase for imitation testing, or derived from Cactusstrutstestcase for container testing. Here we discuss the mock test first because it requires less configuration and runs faster.

  Third, the actual combat strutstestcase

To test this behavior using Strutstestcase, we create a new class that extends the class mockstrutstestcase. This class provides a series of methods to build a simulated HTTP request, invoke the corresponding struts behavior, and validate the application state once the behavior completes.

You can imagine a live database with a multiple-condition lookup function online. This lookup function is implemented through the/search.do behavior. This behavior completes a multiple-condition lookup based on the specified criteria and places the list of results in a request-scope property called results. For example, the following URL should display a list of all the accommodation results in France:
/search.do?country=fr

Now, suppose we want to implement this method in a test-driven way. We create the behavior class and update the struts configuration file. We also develop test instances to test (empty) This behavior class. By using a rigorous test-driven development approach, we can first create a test instance and then implement the code to match the test instance. In practice, the exact order may vary depending on the code to be tested.

The starting test scenario looks like this:

public void Testsearchbycountry () {
Setrequestpathinfo ("/search.do");
Addrequestparameter ("Country", "FR");
Actionperform ();
}


Here, we establish the path to invoke (Setrequestpathinfo ()) and add a request parameter (Addrequestparameter ()). We then use Actionperform () to invoke the behavior class. This validates the struts configuration and invokes the corresponding action class, but does not test what the behavior actually does. To do this, we need to validate the results of the action.

public void Testsearchbycountry () {
Setrequestpathinfo ("/search.do");
Addrequestparameter ("Country", "FR");
Actionperform ();
Verifynoactionerrors ();
Verifyforward ("Success");
Assertnotnull (Request.getattribute ("results"));
}


In this case, we check three things:

• There is no actionerror message (Verifynoactionerrors ()).

• Return to "success" forward.

The results attribute is placed in the request scope.

If we are using tiles, we can also use Verifytilesforward () to ensure that the "success" forward actually specifies 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 implement a specific business test on this test result. For example, suppose the result property is a list-it contains a list of about 100 hotel objects, and we want to make sure all the hotels in the list are in France. To implement this type of test, the code will 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) iter.next ();
Assertequals (Hotel.getcountry, testconstants.france);
...
}
}


When you are testing more complex situations, you may want to test serialization behavior. For example, suppose a user inquires all the hotels in France and clicks on a portal to display the appropriate query details. Suppose we have a struts behavior to display the details of a given guesthouse, which can be invoked as follows:

/displaydetails.do?id=123456

By using strutstestcase, we can easily mimic a series of behaviors in the same test scenario-a user inquires all the hotels in France, then clicks on a portal to display the appropriate query 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) results.get (0);
Setrequestpathinfo ("/displaydetails.do");
Addrequestparameter ("id", Hotel.getid ());
Actionperform ();
Verifynoactionerrors ();
Verifyforward ("Success");
hotel = (hotel) request.getattribute ("Hotel");
Assertnotnull (hotel);
...
}

   iv. test struts error handling

It is also important to test for error handling. Suppose that if you specify an invalid country code, we want to check that the application is still working well. To do this, we can write a new test method and use Verifyactionerrors () to check the returned struts errormessages:

public void Testsearchbyinvalidcountry () {
Setrequestpathinfo ("/search.do");
Addrequestparameter ("Country", "XX");
Actionperform ();
Verifyactionerrors (new string[] {"Error.unknown,country"});
Verifyforward ("failure");
}


Sometimes you want to validate data directly in the Actionform object. To do this, you can use Getactionform () as follows:

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 can make sure that the country code that is invalid after the error is correctly stored in the Actionform.

   v. Custom TEST Environment

Overloading the Setup () method is sometimes useful-it lets you specify Non-default configuration options. In this example, we use a different struts-config.xml file and do not activate the XML config file checksum:

public void SetUp () {
Super.setup ();
Setconfigfile ("/web-inf/my-struts-config.xml");
Setinitparameter ("Validating", "false");
}


   Vi. First-level performance testing

Testing a behavior or a series of behaviors is a 10 of excellent test methods-it requires the ability to access the number of responses. Testing from struts behavior allows you to verify global server-side performance (except, of course, to generate JSP pages). In order to isolate and remove performance problems as quickly as possible and integrate them into the build process to help avoid performance rollback, it is a good idea to perform some first-level performance tests at the unit-Test level.

Here are the basic principles I use to perform first-level struts performance testing:

• Test a multiple-condition search query with as many combinations as possible (to check that these indexes have been correctly defined).

• Test a large-capacity query (a query that returns a large number of results) to check the response times and the results page (if used).

• Test individual and duplicate queries (to check buffering performance, if a buffering strategy is used).

There are open source libraries that can be used to help with performance testing, such as the Junitperf maintained by Mike Clark. However, it may be somewhat complicated to integrate them into the strutstestcase. In many cases, a simple timer can be used to achieve this function. Here's a simple and effective way to achieve first-level performance testing:

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)
}


   Vii. Conclusion

In general, unit testing is an essential part of sensitive programming, especially based on test development. Strutstestcase provides us with an easy and effective way to unit test struts behavior, otherwise it is quite difficult to use JUnit for unit testing.

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.