Dr. Dobb's Journal - November 2008 - (Page 58) Best Practices Special UNIT TESTING WEB SERVICES continued from page 56 applications by making the tests interact with a live instance of the service, as in Figure 2. The pseudocode in Listing One is from the test class MyServiceTest, showing how the test method testGetDoc() connects to the service, calls the service method getDoc(), and validates the results. The method setUp() creates the test’s service connection, and tearDown() closes it. When developing web services using TDD, the typical pattern is to first create a test for each new service behavior, then implement the service interface functionality that enables the test to pass. So, as with conventional objects, the organization of the test class tends to parallel that of the production class, with test methods that correspond to each service method or behavior. Figure 3 shows how service methods in MyService are validated by corresponding test methods in MyServiceTest. Once the service interface has a test fixture, developing additional tests to validate the service is easy, and developers become accustomed to adding unit tests for every new behavior or bug fix associated with the service, just as for any other object. For example, we found that a service method called getImage() that returned a binary image data array had a serious bug, because if the service treated the data as a string, it could contain XML characters such as “ ” that resulted in malformed SOAP messages. To fix this, we modified the WSDL declaration of getImage() to repre- sent the data as a base64-encoded array, as in Listing Two. The test method testGetImage() validates that getImage() succeeds in returning image data that exhibited the malformed message bug prior to the fix (Listing Three). It also validates that the data array has the expected size after being base64-encoded by the service, communicated as a WS message, and decoded by the client interface. In addition to verifying the service methods’ results for normal use cases, the tests should also validate error-handling characteristics; for example, are the expected exceptions or error codes generated by the service and caught by the client? The test method testInvalidLogin() validates that the service throws an expected login exception (Listing Four). This is not as trivial a test as it seems at first, since the service exception is also a WS message that is serialized and deserialized at the service and client endpoints. Service tests can validate behaviors that are difficult to test manually. The test method testTimeout() shows validation of a service connection timeout, a behavior that can be tested manually only by waiting for the normal session timeout to expire, or by altering and redeploying the service configuration to set a short timeout period, either of which are tedious (Listing Five). Another service behavior that is a pain to test manually is multiple client connections. The test method testMultipleConnections() validates that different clients have different service-side state by creating two client con- Listing Seven public class MyServiceTest extends TestCase { public void testGetDocTime() { long startTime = System.currentTimeMillis(); String doc = service.getDoc(); long endTime = System.currentTimeMillis(); assertTrue( endTime-startTime < 100 ); } } nections to the service, performing an operation on one, and verifying that the second client does not see the data added by the first (Listing Six). Creating tests that exercise the web service not only enables unit testing of service methods, but also facilitates higher level testing, such as performance testing. A common performance criterion is to validate that a service method completes in less than a specified amount of time. This would be difficult to validate manually without instrumenting the code and performing user actions that fire service calls. The test method testGetDocTime() shows how to implement such a performance test (Listing Seven). Similarly, using the test framework to create stress tests of the service is simple. The test method testLargeDoc() validates that an arbitrarily large document can be sent to and retrieved from the service without alteration (Listing Eight). Another useful type of stress test is to create many client connections in separate threads, each asynchronously calling service methods, to validate the scalability of the service and application. Using such testing techniques, web services can be automatically and repeatedly validated to provide a much higher level of quality than what is possible through ad hoc manual testing. Once the web service interface has full test coverage, the underlying application can be rapidly iterated with confidence that the WS messaging layer will work as expected. Given the increasing focus on and complexity of distributed, service-oriented architectures and applications, web service development and testing practices such as those described here will become increasingly indispensable. Acknowledgments This article resulted in part from Grid and web service development work at Tech-X Corporation, including the project “TxFlow: Data Skimming Grid Portal,” led by Dr. David Alexander and funded by DOE contract DEFG02-03ER83799, and the project “GRIDL: Grid-Enabled Interactive Data Language for Astronomical Data,” led by Dr. Svetlana Shasharina and funded by NASA contract NNX09CA21P. DDJ Listing Eight public class MyServiceTest extends TestCase { public void testLargeDoc() { StringBuffer doc = new StringBuffer(1000000); // 1 MB string for (int i = 0; i<1000000; i++) doc.append("X"); service.putDoc( doc.toString() ); String d = service.getDoc(); assertEquals( doc.toString(), d ); } } 58 Dr. Dobb’s Journal l www.ddj.com l November 2008 http://www.ddj.com
Table of Contents Feed for the Digital Edition of Dr. Dobb's Journal - November 2008 Dr. Dobb's Journal - November 2008 Contents Friday Night Fish Fry Alia Vox Developer Diaries Developer's Notebook Saving Open Source Conversations iPhone Building Your Own Web Server Green Telnet What's New In Boost Threads? Testing Service Oriented Architectures Test Case Generation, UML, and Eclipse Unit Testing Web Services C3 Programming The Agile Edge Swaine's Flames Effective Concurrency Dr. Dobb's Journal - November 2008 Dr. Dobb's Journal - November 2008 - (Page BB1) Dr. Dobb's Journal - November 2008 - (Page BB2) Dr. Dobb's Journal - November 2008 - Dr. Dobb's Journal - November 2008 (Page Cover1) Dr. Dobb's Journal - November 2008 - Dr. Dobb's Journal - November 2008 (Page Cover2) Dr. Dobb's Journal - November 2008 - Dr. Dobb's Journal - November 2008 (Page 1) Dr. Dobb's Journal - November 2008 - Dr. Dobb's Journal - November 2008 (Page 2) Dr. Dobb's Journal - November 2008 - Dr. Dobb's Journal - November 2008 (Page 3) Dr. Dobb's Journal - November 2008 - Contents (Page 4) Dr. Dobb's Journal - November 2008 - Contents (Page 5) Dr. Dobb's Journal - November 2008 - Friday Night Fish Fry (Page 6) Dr. Dobb's Journal - November 2008 - Friday Night Fish Fry (Page 7) Dr. Dobb's Journal - November 2008 - Friday Night Fish Fry (Page 8) Dr. Dobb's Journal - November 2008 - Friday Night Fish Fry (Page 9) Dr. Dobb's Journal - November 2008 - Alia Vox (Page 10) Dr. Dobb's Journal - November 2008 - Alia Vox (Page 11) Dr. Dobb's Journal - November 2008 - Developer Diaries (Page 12) Dr. Dobb's Journal - November 2008 - Developer Diaries (Page 13) Dr. Dobb's Journal - November 2008 - Developer's Notebook (Page 14) Dr. Dobb's Journal - November 2008 - Developer's Notebook (Page 15) Dr. Dobb's Journal - November 2008 - Saving Open Source (Page 16) Dr. Dobb's Journal - November 2008 - Saving Open Source (Page 17) Dr. Dobb's Journal - November 2008 - Saving Open Source (Page 18) Dr. Dobb's Journal - November 2008 - Saving Open Source (Page 19) Dr. Dobb's Journal - November 2008 - Conversations (Page 20) Dr. Dobb's Journal - November 2008 - Conversations (Page 21) Dr. Dobb's Journal - November 2008 - iPhone (Page 22) Dr. Dobb's Journal - November 2008 - iPhone (Page 23) Dr. Dobb's Journal - November 2008 - iPhone (Page 24) Dr. Dobb's Journal - November 2008 - iPhone (Page 25) Dr. Dobb's Journal - November 2008 - iPhone (Page 26) Dr. Dobb's Journal - November 2008 - iPhone (Page 27) Dr. Dobb's Journal - November 2008 - Building Your Own Web Server (Page 28) Dr. Dobb's Journal - November 2008 - Building Your Own Web Server (Page 29) Dr. Dobb's Journal - November 2008 - Building Your Own Web Server (Page 30) Dr. Dobb's Journal - November 2008 - Building Your Own Web Server (Page 31) Dr. Dobb's Journal - November 2008 - Building Your Own Web Server (Page 32) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 33) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 34) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 35) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 36) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 37) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 38) Dr. Dobb's Journal - November 2008 - Green Telnet (Page 39) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 40) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 41) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 42) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 43) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 44) Dr. Dobb's Journal - November 2008 - What's New In Boost Threads? (Page 45) Dr. Dobb's Journal - November 2008 - Testing Service Oriented Architectures (Page 46) Dr. Dobb's Journal - November 2008 - Testing Service Oriented Architectures (Page 47) Dr. Dobb's Journal - November 2008 - Testing Service Oriented Architectures (Page 48) Dr. Dobb's Journal - November 2008 - Test Case Generation, UML, and Eclipse (Page 49) Dr. Dobb's Journal - November 2008 - Test Case Generation, UML, and Eclipse (Page 50) Dr. Dobb's Journal - November 2008 - Test Case Generation, UML, and Eclipse (Page 51) Dr. Dobb's Journal - November 2008 - Test Case Generation, UML, and Eclipse (Page 52) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 53) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 54) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 55) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 56) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 57) Dr. Dobb's Journal - November 2008 - Unit Testing Web Services (Page 58) Dr. Dobb's Journal - November 2008 - C3 Programming (Page 59) Dr. Dobb's Journal - November 2008 - C3 Programming (Page 60) Dr. Dobb's Journal - November 2008 - C3 Programming (Page 61) Dr. Dobb's Journal - November 2008 - C3 Programming (Page 62) Dr. Dobb's Journal - November 2008 - C3 Programming (Page 63) Dr. Dobb's Journal - November 2008 - The Agile Edge (Page 64) Dr. Dobb's Journal - November 2008 - The Agile Edge (Page 65) Dr. Dobb's Journal - November 2008 - The Agile Edge (Page 66) Dr. Dobb's Journal - November 2008 - The Agile Edge (Page 67) Dr. Dobb's Journal - November 2008 - Effective Concurrency (Page 68) Dr. Dobb's Journal - November 2008 - Effective Concurrency (Page 69) Dr. Dobb's Journal - November 2008 - Effective Concurrency (Page 70) Dr. Dobb's Journal - November 2008 - Effective Concurrency (Page 71) Dr. Dobb's Journal - November 2008 - Swaine's Flames (Page 72) Dr. Dobb's Journal - November 2008 - Swaine's Flames (Page Cover3) Dr. Dobb's Journal - November 2008 - Swaine's Flames (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.