Testing web services with a standard Web Vuser

powerconnect for splunk

It is possible to test web services using the standard Web (HTTP/HTML) virtual user type instead of the Web Services vuser type. The main disadvantage of this is that you cannot generate your SOAP body from the WSDL file using the VuGen wizard. But if you know what your XML request should look like, then you shouldn't have any real problems.

Here are my tips:

  • Send your SOAP payload using lr_custom_request().
  • Add a SOAPAction HTTP header using web_add_header().
  • Remove unnecessary HTTP headers (that are generated automatically by VuGen) with web_remove_auto_header().
  • Don't forget to verify that you get a valid response. Use web_reg_find() for a simple check. For better verification of the SOAP response use lr_xml_find().
  • To extract values from the response body, use lr_xml_get_values(). Brush up on your XPath qeries beforehand though.
  • It may be necessary to HTML-encode some characters in your XML/SOAP message (e.g. convert "&" to "&"). Unfortunately VuGen does not provide this functionality (but HP could easily add it to the web_convert_param function), so you will have to either write (or find) a function to do it, or convert all the entries in your data table before running the script.

As an example, here is a simple script that makes use of a web service that will look up the source of a Shakespeare quote for you.

Action()
{
  // ContentCheck Rules for known error messages
  web_global_verification("Text=Speech not found", "ID=SpeechNotFound", LAST);

  lr_start_transaction ("Search For Shakespeare Quote");

  // By default, VuGen sends a user-agent header.
  // Let's remove this as an example of removing automatically generated headers.
  web_remove_auto_header("User-Agent", "ImplicitGen=No", LAST); 

  // Add a SOAPAction HTTP header
  web_add_header("SOAPAction", "http://xmlme.com/WebServices/GetSpeech");

  // Save entire body from the HTTP response for later checking with lr_xml_find.
  web_reg_save_param("ResponseBody",
    "LB=",
    "RB=",
    "Search=Body",
    "IgnoreRedirections=Yes",
    LAST);

  // Note that the text to search for would normally be replaced with a parameter,
  // and so would the  element of the below SOAP message.
  web_reg_find("Text=TWELFTH NIGHT", LAST);

  web_custom_request("Search Shakespeare", 
    "URL=http://www.xmlme.com/WSShakespeare.asmx", 
    "Method=POST", 
    "Resource=0", 
    "Referer=", 
    "Snapshot=t1.inf", 
    "Mode=URL", 
    "EncType=text/xml; charset=utf-8", 
    "Body=" // As it is SOAP, you are unlikely to have to use BodyBinary, unless your request has CDATA.
    ""
    ""
    ""
    ""
    "Be not afraid of greatness"
    ""
    ""
    "",
    LAST);

  // The response from the web service looks like this:
  /*
  
  
    
      
        
          <SPEECH>
          <PLAY>TWELFTH NIGHT</PLAY>
          <SPEAKER>MALVOLIO</SPEAKER>
          'Be not afraid of greatness:' 'twas well writ.</SPEECH>
        
      
    
  
  */

  // An example of extracting the a value from a SOAP reponse.
  // This saves the  element into {OutputParameter}.
  // The same syntax could be used with lr_xml_find to check the response.
  lr_xml_extract("XML={ResponseBody}", 
    "XMLFragmentParam=OutputParameter", 
    "Query=/soap:Envelope/soap:Body/GetSpeechResponse/GetSpeechResult", LAST);
  lr_output_message("Source of Shakespeare quote: %s", lr_eval_string("{OutputParameter}"));

  lr_end_transaction ("Search For Shakespeare Quote", LR_AUTO);

  return 0;
}

Tech tips from JDS