Tech Ads
Back to Article List
Originally published February 2007 [ Publisher Link ]
Testing Web Services: Integrity and scalability in SOA
With the shift to develop software as reusable services, many paradigms in the software development cycle are being readdressed. Just as object orientated design requires a particular mindset to develop effectively, service-orientated architecture also brings its share of specific approaches. In the coming paragraphs, we will explore one of the many important facets to developing services: Testing.
Depending on the software management style in your organization, testing can often be a top priority or an overlooked process. The former approach, being in line with agile development techniques, stresses the need to incorporate testing thoroughly while business services are being written, while the latter takes the position of not testing until you have a 'ready to go' service.
While there are proponents which confirm that investing from the outset in testing and adopting agile principals far outweigh the benefits of leaving testing until the final development phases, we will leave the discussion of when to introduce testing to your particular project's constraints and instead focus on the how.
Testing is by no means a simple subject, there are many types of tests which can be performed on software. Depending on the complexity and gamut of tests, even dedicated groups -- QA teams -- can be employed for this particular task, but for practical purposes, we will focus on two types of testing which are relatively easy to develop: Unit and stress testing.
Unit testing refers to the process of verifying a service's intended purpose through a series of predefined data sets, which are used to mimic real world usage and thus detect flaws in a timely manner. When making unit tests for your services, you can think of them as your safety net before releasing services into production since you will have the ability to run predetermined sets of data through you service's logic before real data flows through them.
Another benefit unit testing brings to development becomes more apparent when your services start to age. Since evolving services imply modifications to the underlying logic, these changes may cause breakage to specific usage scenarios the services were intended to fulfill. However, armed with an existing suite of unit tests you are guaranteed that continued compliance with these tests protects any dependent party using your services from any breakages that can occur in newer revisions.
The actual writing of unit tests depends heavily on the programming language or platform you are using for deploying services, but more than likely will be done through a special framework in order to facilitate the bootstrapping, validation and deployment of tests – or in other words, automating all the 'plumbing' that entails unit testing.
Among the most popular frameworks for performing unit tests are: JUnit for Java and the Unit Testing Framework for .NET, the last of which forms part of Visual Studio. Illustrating the depth of either framework or some other unit testing suite would go beyond the scope of this article, but listing 1.1 illustrates what a JUnit test for a Java backed services would look like.
Listing 1.1 Unit test written in JUnit for Java classes used as Web Services |
import junit.framework.*; public class PayrollTest extends TestCase { private Payroll basePayroll; private Employee accountingE; public PayrollTest(String type) { super(type); } protected void setUp() { // Initialize Payroll object basePayroll = new Payroll(); // Generate employee, assign to payroll accountingE = new Employee("John Smith", 5743.00); basePayroll.addEmployee(accountingE); } protected void tearDown() { // Reinitialize Payroll object basePayroll = null; } public void testAddEmployee() { Employee contractE = new Employee("Auditor", 2843.00); basePayroll.addEmployee(contractE); double totalPayroll = accountingE.getSalary() + contractE.getSalary(); assertEquals(totalPayroll, basePayroll.getTotal(), 0.0); assertEquals(2, basePayroll.countEmployees()); } public void testEmptyPayroll() { basePayroll.emptyPayroll(); assertTrue(basePayroll.emptyPayroll()); } public void testEliminateEmployee() throws EmployeeNotFound { basePayroll.eliminateEmployee(accountingE); assertEquals(0, basePayroll.countEmployees()); assertEquals(0.0, basePayroll.getTotal(), 0.0); } public static Test suite() { TestSuite suite = new TestSuite(PayrollTest.class); return suite; } public static void main(String args[]) { junit.textui.TestRunner.run(suite()); } } |
This test listing represents a unit test performed on two business logic classes that will eventually make up a Web service for determining Payroll data. Notice how an instance of both the Payroll and Employee classes are created, both of which are later manipulated inside the different testXXX() methods. Once manipulated, also notice the calls to the various JUnit methods named assertXXX().
The parameters used to call the various assert methods form the predefined pieces of data passed along to the underlying service classes, which upon being evaluated are compared to the expected values, at which point in time the testing framework will raise an error or return a successful test execution.
While unit testing is used to verify the integrity of a service's logic, stress testing is used to determine the behavior a service will have under a particular user load, a process that can also help determine the adequacy of a service's supporting infrastructure – like hardware capacity, application server configuration and bandwidth availability, among other things.
One tool which can aid you in stress testing services is JMeter , an open source project developed by the Apache foundation. Although JMeter is Java based, it can generate SOAP and XMLRPC type requests, effectively functioning as a Web services client to stress test any server side deployment. Figure 1.1 illustrates a screen shot of this tool performing a load test on a SOAP/XML-RPC service.
Figure 1.1 : JMeter stress test for Web services
The process for creating the aforementioned stress test in JMeter would be the following :
1. On JMeter's main screen, place your mouse on the Test Plan icon and do a right click. From the pop-up menu select : Add – Thread Group. The Thread Group icon will be created.
2. Place yourself on the Thread Group icon, the left hand side pane will show various parameters. The parameter Number of threads represents the number of requests your stress test will emulate to your service, modify accordingly.
3. Next, while on Thread Group icon do a right click. From the pop-up menu select: Add – Sampler – SOAP/XML-RPC Request. The SOAP/XML-RPC request icon will be created.
4. Place yourself on the SOAP/XML-RPC request icon, the left hand side pane will show various parameters. Introduce the URL of your Web service, as well as the payload you wish to send on each request.
5. Next, while on the SOAP/XML-RPC request icon do a right click. From the pop-up menu select: Add – Listener – Monitor Results, and also Add – Listener – View Results in Table. Two new icons that will represent the stress tests results will be generated. NOTE: You can add more Listener's if you require, which is JMeter's terminology for representing stress test results.
6. Save your test, and select the Run-Start option from the top level menus to start your stress test.
7. Finally, move along the various Listener icons to observe the performance metrics obtained when stressing your Web service.
In much the same nature as unit testing frameworks, illustrating the many intricacies of JMeter – or any other stress tool for that matter – would go beyond the scope of this article, but JMeter offers comprehensive and freely available documentation on its various stress testing functionalities.
With this we conclude our look at unit and stress testing in the context of Web services, two of the many testing procedures you can use in you service-oriented designs in order to assure the integrity and scalability of your deployments.