Monday, November 4, 2013

Extracting fields from server responses


    In performance testing, we frequently have to process server responses.  One part of the processing  is extracting fields from the response messages and saving them to parameter(s) to be used later.
 
    In Loadrunner, the most common way of extraction is by using boundary method:  you provide the left-boundary of a field and a right-boundary.  It returns the value contained in-between. This could be a good choice when the response data is in free format, but if the response data has a structure, like a HTML form, Netgend scripting provides an easier and more intuitive way for data extraction.

   The first example here is based on an example from this blog (thanks for it!). We need to extract the value for "ID1" field from the following message:
 <form>  
 <input type="hidden" name="ID1" value="11111">  
 <input type="hidden" name="ID2" value="22222">  
 ... (more lines) ...  
 </form>  
    Of course, one can extract the value in this case as
 Left-boundary: ID1\" value=\"  
 Right-boundary: "  
 
    In netgend javascript script, we can do it as
 a = getFormField(str);  
 #now variable a.ID1.value will contain the value "11111".
    Much cleaner, right?

    In case you really want to use boundary method, netgend javascript supports it for feature compatibility :-)
 a = substring(str, "ID1\" value=\"", "\"");  
 println(a[0]);  
    Note that in netgend javascript, boundary can potentially be dynamically changed, while in the case of Loadrunner, it's static (fixed in test creation time).
 left  = ... ; #may be extracted from previous server response   
 right = ... ; #may be extracted from previous server response   
 a = substring(str, left, right);   
 println(a[0]);   

    The second example involves CAPTCHA. We as a human being,  can "see" the characters better than a machine/program.   However, there are some web sites that use a much weaker format:   In their registration forms, there is a question like  "what is sum of 14 + 9:  [      ]":
This may deter some casual hackers, but it will not deter sophisticated hackers from registering lots of accounts.

    Suppose we need to test this,  we can use the boundary method mentioned earlier, but it will be very tedious:  we will extract both numbers into their parameters, do the arithmetic operation on the two parameters and write it back to a parameter.

    In netgend javascript script, it's very trivial:
 contains(http.replyBody,  /what is sum of (\d+)\s+\+\s+(\d+)/);  
 answer = g1 + g2;  
 //now you can send POST data like "...userAnswer=${answer}"  
     Note that in the above, the two variables "g1", "g2" will contain the two numbers. We just add them up and assign the sum to the variable "answer".  In case you wonder,  the values in "g1", "g2" are strings,  can you add them as if they are numbers?   The answer is yes! If they are really numbers,  like "14" and "9" in our case, you can performance the arithmetic operation.

     Of course, we are not hackers :-)  We are the proud performance testing engineers!

    What if we need extract some values from a response that looks like xml? More precisely, suppose we have a response that looks like the following, how do we extract name of the first employee in the response?

 <employees>  
 <employee>  
      <id>1001</id>  
       <name>John Smith</name>  
 </employee>  
 <employee>  
      <id>1002</id>  
       <name>Jane Dole</name>  
 </employee>  
 </employees>  

    You may be tempted to use regular expression, it may work, but it may get you the wrong answer (for instance, get you the name of the second employee).   Here is a much simpler solution.
 a = fromXml(str);  
 //now a.employees.employee[0].name.value will contain the value "John Smith" 
    Here the compound variable "a.employees.employee[1].name.value" come from the xml structure, reader can quickly see the easy mapping here.

   Different test scenarios may require extraction of data differently. Based on the above examples, we can tell they are not going to be too hard for netgend javascript :-)


No comments:

Post a Comment