Wednesday, October 30, 2013

HTTP Performance testing made simple (II)



    In blog HTTP Performance testing made simple , we mainly talked about how to generate HTTP request dynamically.  While it is important, it is only half the story,  the other half is:  how to process the HTTP response sent by server.  This is what we will focus on in this blog.

   The simplest means of processing HTTP response is by regular expression.  For example, when you send a HTTP request to query all the shoes in a online store, you can use regular expression to grab the number of pages (of shoes) in the reply.
action(http, "http://www.example.com/search?product=shoes"); 
//the above action will save http replyBody in variable http.replyBody
contains(http.replyBody,  /there are (\d+) pages/); 
pages = g1;  
    Note that "g1" is the global variable that holds first grabbed number. We need to save it to a local variable so we don't lose the value when another instance does the regular expression match.
    What do you do with the (grabbed) number of pages? You can emulate a user clicking through the pages by having a simple loop.
while (id = 2; id <= pages; id ++) {  
    action(http,"http://www.example.com/product=shoes&page=${id}"); 
    sleep(3000);
}  
    Did you notice the loop starts from page 2?  That's because the search reply page typically contains page 1.

    How do we handle json message in HTTP reply?  Some of us may try to use regular expression.  While that may work in some cases, it's error-prone, cumbersome and not very easy for typical users.
Let's suppose HTTP reply contains the following:
 {"type": "contractor", "id": 1234, "name": "Jsmith" }  
    How do we extract "id"?   You just call fromJson() function and now it's easy to access any fields, including "id".
reply = fromJson(http.replyBody);  
id = reply.id;  
if (reply.type == "contractor") {
    action(http,"http://www.example.com/searchContractor/${id}");  
} else {
    action(http, "http://www.example.com/searchOthers/${id}");  
}

     What if the json structure is a little complex like the following and you want to extract some fields?
 { "store":   
 {"book": [{ "category": "reference","author": "Nigel Rees","title": "Sayings of the Century","price": 8.95},  
 { "category": "fiction","author": "Evelyn Waugh","title": "Sword of Honour","price": 12.99},  
 { "category": "fiction","author": "Herman Melville","title": "Moby Dick","isbn": "0-553-21311-3","price": 8.99},  
 { "category": "fiction","author": "J. R. R. Tolkien","title": "The Lord of the Rings","isbn": "0-395-19395-8","price": 22.99}],  
 "bicycle": {"color": "red","price": 19.95}} }  
    Luckily we can use json path.  Here is an example to show how to extract the author of the first book.
a = fromJson(str, '$.store.book[0]');  
author = a.author;  
action(http,"http://www.example.com/search?product=books&author=${author}"); 
    If you need to get the price of the second book, just make a little change
a = fromJson(str, '$.store.book[1]');   
price = a.price;  

    Sometimes server reply is in xml format, so can we deal with that?  On some platform, it's a non-trivial task to deal with xml messages. It's very easy with netgend javascript script.
 //suppose http reply is a xml message.
 <employee>  
 <id>1</id>  
 <firstName>John</firstName>  
 <lastName>Smith</lastName>  
 </employee>  

 //now let's grab a field in the xml message.
 reply = fromXml(http.replyBody)  
 firstName = reply.employee.firstName.value
 //now the variable "firstName" will contain "John" 

    As we mentioned in one of the earlier blogs, HTTP has gotten more complex, so there will be more interesting scenarios coming and we will handle it.

No comments:

Post a Comment