Testing Web Services
Ensuring functionality, security, and interoperability
By: Adam Kolawa
Feb. 5, 2004 12:00 AM
As more enterprises move toward an e-business strategy, the communication and integration of disparate, heterogeneous applications and systems is key. Businesses must be able to securely connect and communicate with customers and trading partners alike.
Using Web services, different businesses and customers can communicate by exchanging information through platform-independent protocols such as SOAP, XML, and HTTP.
However, the flexibility of Web services can prove to be a double-edged sword. While Web services allow businesses to connect to partners and customers, this same flexibility and connectivity provide increased opportunities for errors. Web services are complex systems that attempt to marry software, hardware, new code, legacy code, existing systems, systems in development, and who-knows-what on the client side. There are countless opportunities for things to go wrong - a slight mistake in any component or interface will cause problems that ripple throughout the system (see Figure 1).
Therefore testing, which is important for any software application, is even more crucial for Web services. As companies and consumers rely more on Web services, the importance of quality and reliability will continue to increase, thereby increasing the importance of Web services testing. This article explains the general testing practices required to ensure complete Web service functionality, interoperability, and security.
Server Functional Testing
The simplest possible functional test involves sending a request and checking whether the server returns a response or an error message. The response can be analyzed either by inspection or by running the response through a tool or script that verifies conformance to a specification. The analysis can be as simple as performing a text comparison with the expected response, or as complex as extracting specific information from an XML document and performing application-specific checks. For example, if you have a Web service that handles bank transactions, you can perform a server functional test by sending a valid request (such as a transfer of money) to the server. You can then verify whether a response or an error message is returned from the server.
However, because of the complex nature of Web services, testing a server's functionality may be far from simple. With most Web services it is impossible to anticipate exactly what types of requests clients will send. Traffic may occur with extreme highs and lows, with users accessing the service using a variety of clients, connections, and platforms. With so many differing clients accessing a single Web service, the server is bound to encounter unexpected requests either as a result of mistakes (such as a bad WSDL) or from attempts to breach service security (hackers sometimes trick applications into behaving unexpectedly by sending it invalid inputs).
An effective way to prevent errors caused by unexpected inputs is to perform what some refer to as "monkey testing" - throwing the proverbial wrench into the Web services works by sending the service requests with illegal and/or unexpected parameters, then verifying the response with assertions, custom code, or other tool-specific verification methods. For example, how will the server react if a customer attempts to transfer more money than is available? Will it return a proper message to the client? Will it allow the transaction? Or will the server just crash and die?
By checking for the conditions and inputs that are not expected, you enable more thorough tests for what cannot be foreseen. By performing such testing at the unit and application level, you can quickly and easily identify and correct any weaknesses before security breaches can occur. Therefore, it is important to verify whether the server can handle a wide range of request types and parameters. In order to test the server functionality of a Web ser-vice, you must be able to emulate many of the types of clients that might access the server, and verify that the server will behave as expected in relation to any type of client request.
Load testing typically involves exercising your application with virtual users and measuring performance statistics to verify whether the application supports the anticipated traffic load as well as possible traffic surges, growth, and so on. To ensure that your virtual users' experiences effectively predict your actual users' experiences, you want your virtual users to simulate realistic scenarios. For example, the test could check functionality and response time under different degrees of load increases (sudden surges versus gradual ramp-ups) or different combinations of valid and invalid requests. If the load tests reveal unacceptable performance or function-ality under load, the next step is to diagnose and repair the source of the bottleneck.
When problems surface under a reasonable load, they typically indicate fundamental design problems such as algorithmic problems, inefficient database-application interaction, and so on - not infrastructure issues that can be resolved by upgrading hardware or fine-tuning system configuration. As a result, it is recommended that you begin load testing as early in the development process as possible. Ideally, you want to begin performing load testing on a staging server as soon as you can exercise any segment of the application. This way you can expose and resolve problems before they become more deeply embedded in the application and fixing them requires increased time and effort.
The best way to test a particular client depends on the nature of the application. If the client accesses a server that can accept "test" requests without any harmful side effects, it can directly access the live server during testing. However, you may need to test client functionality by emulating server-supplied responses. Emulating the server is especially useful when the server is still being implemented, has bugs, or should not be accessed during testing. For example, if you have a live system that performs credit card processing, you will not be able to access the server without disrupting ongoing business transactions.
No matter what type of server a client accesses, the same general principle applies: the client sends a request, the server responds, then client success or failure is determined by recording and verifying the request and/or by verifying the server response. The same techniques and tools used to verify server functionality can be used for this purpose. However, server bugs could also be misleading: if the server is not operating correctly, correct client requests might result in incorrect responses, and incorrect requests might result in apparently correct responses. You can ensure that server functionality problems are not confusing your results by first verifying the request as well as the response, and then testing the simplest possible server implementations (server stubs) instead of - or in addition to - testing actual, complex servers.
After verifying that the client sends acceptable requests and can receive responses, you should shift your attention to testing exceptional cases. For example, test that the client behaves properly when the server goes offline by sending the response to an invalid URL. Or use server stubs to simulate the server sending the client invalid data.
Ensuring Web Service Interoperability and Security
Ideally, interoperability would be verified by checking that a service adheres to a comprehensive, universally implemented set of standards. With the recent announcement of Basic Profile 1.0 by the Web Services Interoperability (WS-I) organization, developers now have a set of standards to follow. Basic Profile 1.0 (BP 1.0) consists of implementation guidelines that define how core Web services specifications should be used together to develop interoperable Web services.
By restricting Web service development to technologies specified in WS-I Basic Profile 1.0, developers can increase the odds that their systems will interoperate with others' systems. In addition to BP 1.0, WS-I has also developed a set of test tools that automatically check conformance to BP 1.0. In the event of nonconformance, developers can pinpoint exactly what needs to be changed to ensure compliance to BP 1.0, and ultimately to ensure interoperability.
In addition to interoperability, WS-I has influence in Web services security as well with its WS-Security specification. The aim of this specification is to define the SOAP security headers and how they should be used. Developers should configure SOAP headers according to the following WS-Security specifications:
By integrating server functional testing, load testing, and client testing throughout the full Web services development life cycle, you can ensure that a Web service server works well with the possible types and volumes of client requests, and that a Web service client correctly accesses and retrieves whatever data a service has to offer. By following specifications such as Basic Profile 1.0, and WS-Security, you can be sure that your Web service is interoperable and secure.
Reader Feedback: Page 1 of 1
SOA World Latest Stories
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
SYS-CON Featured Whitepapers
Most Read This Week