Service Test
From Ajax Patterns
There's an archived version of this pattern available, taken from the Ajax Pattern book draft, showing roughly how it appeared before the page became publicly editable.
Evidence: 1/3
Tags: Automated Javascript Remoting UnitTest TDD Test WebService XMLHttpRequest
Contents |
Ajax/Javascript Programming and Usability in "Ajax Design Patterns" Book |
Goal Story
Dave is creating a trading appliction, and on the server there are services to provide quotes and accept orders. To help develop and test the web service, he builds a set of Service Tests. One test, for example, submits an order and checks the database registered it. These tests are automated and re-executed every time the project changes.
Problem
How can you test web services?
Solution
Build up automated tests of web services, using HTTP clients to interact with the server as the browser normally would. The browser-server interacton of an Ajax application is usually a sequence of XMLHttpRequest Calls. That's fortunate, because testing the service is usually as easy as simulating the browser - passing a certain request and checking the response. Sometimes, verification might also involve checking what happened on the server, e.g. a database state change or a message to an external system.
The test itself can be built in any language and testing framework you like, because it's completely decoupled from both the browser and the server. The only practical constraint is that you should be able to run it from a script, to allow for continuous integration. Many languages provide an HTTP client library, so it's easy to build a test pass requests to the server and make assertions against the response. Indeed, there are client frameworks like HTTPUnit specificially for the purposes of testing web applications. They're typically used for testing conventional appliations, where the response contains an entire page, but they work fine for the terse responses usually provided by web services.
A RESTful Service, in particular, should be straightforward to test because it will usually output Semantic Responses which are easily parsed and because there is no conversational state. A service that outputs an HTML Response will make tests a bit more fragile. Passing in 5+5 will always let you assert "10" as the Semantic Response), but not always "The answer is 10!!!" if an HTML Response is used.
Tool Support
Net::HTTP
Net::HTTP is an HTTP client library for Ruby, shipping with the standard distribution. It's used in the refactoring illustration below.
Jakarta HttpClient
Jakarta HTTPClient is a richly-featured HTTP client framework for Java.
PHP HttpClient
Simon Willison's HTTPClient is a basic HTTP client framework for PHP.
Refactoring Illustration
The Basic Ajax Pattern Reader uses some Simulation Services to get information from the server. A Service Test was first created against the Simulation Services, and once this passed, the test was used to drive the design of the real services. The Solution mentioned that the programming language of the HTTP client is completely independent of the server or browser languages, and that's not just theoretical, since some languages (e.g. Ruby, Perl) are particularly well-suited to string manipulation. To prove the point, the example here uses Ruby's Net::HTTP library. Following is a test of the service that fetches a pattern page from ajaxpatterns.org, and renders it into some summary HTML.
require "test/unit"
require "net/http"
class PatternServiceTest < Test::Unit::TestCase
def test_slider
sliderResponse = grabPattern("Slider");
regex = /^\s*<h1><a\ href=\".*?\">Slider<\/a><\/h1>\s*\
<span\ class=\"summary\">.+?<\/span>.+
/mx;
assert_match(regex, sliderResponse.body);
end
...
def grabPattern(patternName)
session = Net::HTTP.new('ajaxlocal', 80);
response = session.get("/run/reader/logging/realService/" +
"patternSummary.phtml?patternName=" + patternName);
assert_equal("200", response.code);
return response;
end
end
Related Patterns
Simulation Service
You can sometimes start creating a test against a Simulation Service, and gradually refactor it into a real service, while evolving the test as well.
Browser-Side Test
A Browser-Side Test is a good complement to a Service Test, since the former tests browser behaviour while the latter ensures the server will support the browser in the correct way.
Time your website with
WebWait - from the creator of AjaxPatterns.org
