Monday, January 27, 2014

The power of simplicity


    In an earlier blog, we talked about the story for the nickname "ghetto coder".  Today I saw an interesting test scenario in google group that reminded me of it yet again (lost track of how many times I was reminded).  In this test scenario, we need to emulate multiple clients,  each client does multiple transactions with a server, each time the server sends a response (HTML) with a dropdown list (a.k.a. "select" tag with options),   the item names are the same, but the item values may change.   Here are the code snippets of 3 HTML responses.   In the emulation, we need to consistently select a user, say "Smith" when interacting with the server.

 1st iteration   
 <option value="456983">Jack</option> ------>456983[Dynamic value changes every time]   
 <option value="456984">Adam</option>   
 <option value="456985">John</option>   
 <option value="456987">Smith</option>   
 2nd iteration   
 <option value="456974">Jack</option>   
 <option value="456975">Smith</option>   
 <option value="456976">John</option>   
 <option value="456977">Adam</option>   
 3rd iteration   
 <option value="456654">Smith</option>   
 <option value="456655">John</option>   
 <option value="456656">Adam</option>   
 <option value="456657">Jack</option>   
   

    Here is one of the proposed solutions in the discussion thread. Note that the values of items are extracted by a left boundary and a right boundary and also note how hard it is to go through the list of item values:
 web_reg_save_param ("IDValues", "LB= value=\"", "RB=\"", "Ord=All", LAST);   
 // get number of matches   
 nCount = atoi(lr_eval_string("{IDValue_count}"));   
 for (i = 1; i <= nCount; i++) {   
   // create full name of a current parameter   
   sprintf(szParamName, "{IDValue_%d}", i);   
   // output a value of current parameter   
   lr_output_message("Value of %s: %s",szParamName,   
 lr_eval_string(szParamName));   
 }   

    In addition to being not so "simple", it's may not even work in some scenarios:    what if there are other tags (like "<input>") in the html file that also has the "value" attribute? what if there are attributes whose values are not surrounded by double quote (like value=1234)?  We have seen it in some real world sites like walmart.

    In contrast, the script on NetGend is much simpler.
 function VUSER() {  
      action(http, "http://www.example.com");  
      mapping = mapFormOptions(http.replyBody, "Jack");  
      println(mapping.Jack);  //will have the value of Jack
      println(mapping.Smith); //will have the value of Smith
      exit(0);  
 }  
    Here we use the function "mapFormOptions" to grab the options, which is covered in the previous blog.  This function will grab the "select" node which has an item name that matches the second parameter ("Jack" in this case). This function returns a mapping from item names to item values.  With the mapping, it's easy to find the value of any item.

   It's pretty easy too if you need to iterate over all the items:
 items = keys(mapping);  
 for (i=0; i<length(items); i++) {  
    item = items[i];  
    value = mapping.$item;  
    action(http,"http://www.example.com/view/${value}");  
 }  
     What's new here is the function "keys()" which takes a mapping as input and returns the list of keys ("item names" in our case).  In the above code we sequentially go over all the values,  in real world test scenario, you may need to randomly choose an item and stick to it during the course of interactions with the server.   The implementation is left to the reader as an exercise.

    By being simple, the code is also more resistant to the variation that will  likely come in the future, so the cost of maintaining the script is greatly reduced.

No comments:

Post a Comment