Thursday, December 29, 2011

Simple LoadRunner Method to Post XML to Web Service

Here is a very simple method for posting XML to a web service from loadrunner using http protocol. This method is somewhat simpler than using the web service protocol.

XML Request In-Line
In this scenario:
  • url is saved to a parameter
  • xml request is saved to a parameter
  • http headers are defined
  • response validation is defined
  • request is sent

Here is the script:

Action()
{
    char *request_xml;


    // save web service url to param
    char *URL = "http://www.webservicex.com/globalweather.asmx";
    lr_save_string(URL, "URL_Param");


// save xml request to param
request_xml=
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
 "<soap:Body>"
  "<GetWeather xmlns=\"http://www.webserviceX.NET\">"
"<CityName>Seattle</CityName>"
"<CountryName>United States</CountryName>"
  "</GetWeather>"
 "</soap:Body>"
"</soap:Envelope>";


lr_save_string(request_xml, "REQUEST_XML_PARAM");
  
// add http headers
web_add_header("Content-Type", "text/xml; charset=utf-8");
        web_add_header("Host", "www.webservicex.com");
web_add_header("SOAPAction", "http://www.webserviceX.NET/GetWeather");


        // validate response
web_reg_find("Text=SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States", LAST);


// send request
lr_start_transaction("post_xml");


web_custom_request("post_to_http_jms_provider",
 "URL={URL_Param}",
 "Method=POST",
 "TargetFrame=",
 "Resource=0",
 "Referer=",
 "Mode=HTTP",
 "Body={REQUEST_XML_PARAM}",
 LAST); 


lr_end_transaction("post_xml", LR_AUTO);
}


Sample Output
Here is the sample output:

Virtual User Script started
Starting action vuser_init.
Web Turbo Replay of LoadRunner 9.10.0 for WIN2003; WebReplay85 build 5896   [MsgId: MMSG-27143]
Run Mode: HTML   [MsgId: MMSG-26000]
Run-Time Settings file: "E:\bin\PerformanceCenter\scripts\POST_XML_TEST\\default.cfg"   [MsgId: MMSG-27141]
Ending action vuser_init.
Running Vuser...
Starting iteration 1.
Starting action Action.
Action.c(7): Notify: Saving Parameter "URL_Param = http://www.webservicex.com/globalweather.asmx"
Action.c(21): Notify: Saving Parameter "REQUEST_XML_PARAM = <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Seattle</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(24): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(24): web_add_header("Content-Type") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(25): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(25): web_add_header("Host") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(26): web_add_header("SOAPAction") was successful   [MsgId: MMSG-26392]
Action.c(29): Registering web_reg_find was successful   [MsgId: MMSG-26390]
Action.c(32): Notify: Transaction "post_xml" started.
Action.c(34): Notify: Parameter Substitution: parameter "URL_Param" =  "http://www.webservicex.com/globalweather.asmx"
Action.c(34): Notify: Parameter Substitution: parameter "REQUEST_XML_PARAM" =  "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Seattle</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(34): t=244ms: 277-byte response headers for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(34):     HTTP/1.1 200 OK\r\n
Action.c(34):     Cache-Control: private, max-age=0\r\n
Action.c(34):     Content-Type: text/xml; charset=utf-8\r\n
Action.c(34):     Content-Encoding: gzip\r\n
Action.c(34):     Vary: Accept-Encoding\r\n
Action.c(34):     Server: Microsoft-IIS/7.0\r\n
Action.c(34):     X-AspNet-Version: 4.0.30319\r\n
Action.c(34):     X-Powered-By: ASP.NET\r\n
Action.c(34):     Date: Thu, 29 Dec 2011 22:34:56 GMT\r\n
Action.c(34):     Content-Length: 728\r\n
Action.c(34):     \r\n
Action.c(34): t=264ms: 728-byte ENCODED response body received for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(34): t=265ms: 1103-byte DECODED response body for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(34):     <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.or
Action.c(34):     g/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
Action.c(34):     www.w3.org/2001/XMLSchema"><soap:Body><GetWeatherResponse xmlns="http://www.webserviceX.NE
Action.c(34):     T"><GetWeatherResult>&lt;?xml version="1.0" encoding="utf-16"?&gt;\r\n
Action.c(34):     &lt;CurrentWeather&gt;\r\n
Action.c(34):       &lt;Location&gt;SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States (KSEA) 47-27N 
Action.c(34):     122-19W 136M&lt;/Location&gt;\r\n
Action.c(34):       &lt;Time&gt;Dec 29, 2011 - 04:53 PM EST / 2011.12.29 2153 UTC&lt;/Time&gt;\r\n
Action.c(34):       &lt;Wind&gt; from the SE (140 degrees) at 9 MPH (8 KT):0&lt;/Wind&gt;\r\n
Action.c(34):       &lt;Visibility&gt; 10 mile(s):0&lt;/Visibility&gt;\r\n
Action.c(34):       &lt;SkyConditions&gt; overcast&lt;/SkyConditions&gt;\r\n
Action.c(34):       &lt;Temperature&gt; 46.0 F (7.8 C)&lt;/Temperature&gt;\r\n
Action.c(34):       &lt;DewPoint&gt; 39.9 F (4.4 C)&lt;/DewPoint&gt;\r\n
Action.c(34):       &lt;RelativeHumidity&gt; 79%&lt;/RelativeHumidity&gt;\r\n
Action.c(34):       &lt;Pressure&gt; 29.93 in. Hg (1013 hPa)&lt;/Pressure&gt;\r\n
Action.c(34):       &lt;Status&gt;Success&lt;/Status&gt;\r\n
Action.c(34):     &lt;/CurrentWeather&gt;</GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope
Action.c(34):     >
Action.c(34): Registered web_reg_find successful for "Text=SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States" (count=1)   [MsgId: MMSG-26364]
Action.c(34): web_custom_request("post_to_http_jms_provider") was successful, 728 body bytes, 277 header bytes   [MsgId: MMSG-26386]
Action.c(44): Notify: Transaction "post_xml" ended with "Pass" status (Duration: 0.1738 Wasted Time: 0.0000).
Ending action Action.
Ending iteration 1.
Ending Vuser...
Starting action vuser_end.
Ending action vuser_end.
Vuser Terminated.



XML Request From Parameter File
The xml request message can also be saved in a parameter file rather than being defined in-line.  In this scenario:
  • url is saved to a parameter
  • xml request is saved in a parameter file which is set to update row on "sequential", update value on "once".
  • http headers are defined
  • response validation is defined
  • request is sent

Here is the script:

Action()
{
    // save web service url to parameter
    char *URL = "http://www.webservicex.com/globalweather.asmx";
    lr_save_string(URL, "URL_Param");
  
    // add http headers
    web_add_header("Content-Type", "text/xml; charset=utf-8");
    web_add_header("Host", "www.webservicex.com");
    web_add_header("SOAPAction", "http://www.webserviceX.NET/GetWeather");


    // validate response
    web_reg_find("Text=SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States", LAST);


    // send request
    lr_start_transaction("post_xml");


    web_custom_request("post_xml",
 "URL={URL_Param}",
 "Method=POST",
 "TargetFrame=",
 "Resource=0",
 "Referer=",
 "Mode=HTTP",
 "Body={Request_From_File}",
 LAST); 


    lr_end_transaction("post_xml", LR_AUTO);
}



Parameter File
Here is the parameter file Requst.dat, with the xml defined on a single line, parameter properties of update row on "sequential", update value on "once":

Request
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Seattle</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>



Sample Output
Here is the sample output:

Virtual User Script started
Starting action vuser_init.
Web Turbo Replay of LoadRunner 9.10.0 for WIN2003; WebReplay85 build 5896   [MsgId: MMSG-27143]
Run Mode: HTML   [MsgId: MMSG-26000]
Run-Time Settings file: "E:\bin\PerformanceCenter\scripts\POST_XML_FROM_FILE_TEST\\default.cfg"   [MsgId: MMSG-27141]
Ending action vuser_init.
Running Vuser...
Starting iteration 1.
Starting action Action.
Action.c(6): Notify: Saving Parameter "URL_Param = http://www.webservicex.com/globalweather.asmx"
Action.c(9): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(9): web_add_header("Content-Type") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(10): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(10): web_add_header("Host") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(11): web_add_header("SOAPAction") was successful   [MsgId: MMSG-26392]
Action.c(14): Registering web_reg_find was successful   [MsgId: MMSG-26390]
Action.c(17): Notify: Transaction "post_xml" started.
Action.c(19): Notify: Parameter Substitution: parameter "URL_Param" =  "http://www.webservicex.com/globalweather.asmx"
Action.c(19): Notify: Parameter Substitution: parameter "Request_From_File" =  "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Seattle</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(19): t=210ms: 277-byte response headers for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(19):     HTTP/1.1 200 OK\r\n
Action.c(19):     Cache-Control: private, max-age=0\r\n
Action.c(19):     Content-Type: text/xml; charset=utf-8\r\n
Action.c(19):     Content-Encoding: gzip\r\n
Action.c(19):     Vary: Accept-Encoding\r\n
Action.c(19):     Server: Microsoft-IIS/7.0\r\n
Action.c(19):     X-AspNet-Version: 4.0.30319\r\n
Action.c(19):     X-Powered-By: ASP.NET\r\n
Action.c(19):     Date: Thu, 29 Dec 2011 22:33:25 GMT\r\n
Action.c(19):     Content-Length: 728\r\n
Action.c(19):     \r\n
Action.c(19): t=246ms: 728-byte ENCODED response body received for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(19): t=247ms: 1103-byte DECODED response body for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=1)
Action.c(19):     <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.or
Action.c(19):     g/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
Action.c(19):     www.w3.org/2001/XMLSchema"><soap:Body><GetWeatherResponse xmlns="http://www.webserviceX.NE
Action.c(19):     T"><GetWeatherResult>&lt;?xml version="1.0" encoding="utf-16"?&gt;\r\n
Action.c(19):     &lt;CurrentWeather&gt;\r\n
Action.c(19):       &lt;Location&gt;SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States (KSEA) 47-27N 
Action.c(19):     122-19W 136M&lt;/Location&gt;\r\n
Action.c(19):       &lt;Time&gt;Dec 29, 2011 - 04:53 PM EST / 2011.12.29 2153 UTC&lt;/Time&gt;\r\n
Action.c(19):       &lt;Wind&gt; from the SE (140 degrees) at 9 MPH (8 KT):0&lt;/Wind&gt;\r\n
Action.c(19):       &lt;Visibility&gt; 10 mile(s):0&lt;/Visibility&gt;\r\n
Action.c(19):       &lt;SkyConditions&gt; overcast&lt;/SkyConditions&gt;\r\n
Action.c(19):       &lt;Temperature&gt; 46.0 F (7.8 C)&lt;/Temperature&gt;\r\n
Action.c(19):       &lt;DewPoint&gt; 39.9 F (4.4 C)&lt;/DewPoint&gt;\r\n
Action.c(19):       &lt;RelativeHumidity&gt; 79%&lt;/RelativeHumidity&gt;\r\n
Action.c(19):       &lt;Pressure&gt; 29.93 in. Hg (1013 hPa)&lt;/Pressure&gt;\r\n
Action.c(19):       &lt;Status&gt;Success&lt;/Status&gt;\r\n
Action.c(19):     &lt;/CurrentWeather&gt;</GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope
Action.c(19):     >
Action.c(19): Registered web_reg_find successful for "Text=SEATTLE-TACOMA INTERNATIONAL  AIRPORT , WA, United States" (count=1)   [MsgId: MMSG-26364]
Action.c(19): web_custom_request("post_xml") was successful, 728 body bytes, 277 header bytes   [MsgId: MMSG-26386]
Action.c(29): Notify: Transaction "post_xml" ended with "Pass" status (Duration: 0.1629 Wasted Time: 0.0000).
Ending action Action.
Ending iteration 1.
Ending Vuser...
Starting action vuser_end.
Ending action vuser_end.
Vuser Terminated.

Varying Parameters in the Request

It is also quite easy to vary the input parameters passed in the request message using the function lr_xml_set_values as follows.  In this case: 
  • the field "CityName" in the request xml is specified
  • a new value for CityName is specified
  • the resulting request xml is put in a parameter
  • the updated request is sent
 // vary parameters
lr_xml_set_values("XML=\{Request_From_File\}",
"Query=//CityName",
"Value=Spokane",
"ResultParam=XML_With_Substitution",
LAST);

// add http headers
web_add_header("Content-Type", "text/xml; charset=utf-8");
        web_add_header("Host", "www.webservicex.com");
web_add_header("SOAPAction", "http://www.webserviceX.NET/GetWeather");

// validate response
web_reg_find("Text=FELTS FIELD, WA, United States", LAST);

// send request
lr_start_transaction("post_xml");

web_custom_request("post_xml",
 "URL={URL_Param}",
 "Method=POST",
 "TargetFrame=",
 "Resource=0",
 "Referer=",
 "Mode=HTTP",
 "Body={XML_With_Substitution}",
 LAST); 

lr_end_transaction("post_xml", LR_AUTO);

The request variables can also be pulled from a parameter file as follows:
        // vary parameters
lr_xml_set_values("XML=\{Request_From_File\}",
"Query=//CityName",
"Value=\{CityNameParameter\}",
"ResultParam=XML_With_Substitution",
LAST);

Sample Output


Action.c(32): Notify: Parameter Substitution: parameter "Request_From_File" =  "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Seattle</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(32): Notify: Saving Parameter "XML_With_Substitution = <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Spokane</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(32): "lr_xml_set_values" succeeded, 1 match processed
Action.c(39): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(39): web_add_header("Content-Type") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(40): Warning -26593: The header being added may cause unpredictable results when applied to all ensuing URLs. It is added anyway   [MsgId: MWAR-26593]
Action.c(40): web_add_header("Host") highest severity level was "warning"   [MsgId: MMSG-26391]
Action.c(41): web_add_header("SOAPAction") was successful   [MsgId: MMSG-26392]
Action.c(44): Notify: Transaction "post_xml" started.
Action.c(46): Notify: Parameter Substitution: parameter "URL_Param" =  "http://www.webservicex.com/globalweather.asmx"
Action.c(46): Notify: Parameter Substitution: parameter "XML_With_Substitution" =  "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soap:Body><GetWeather xmlns="http://www.webserviceX.NET"><CityName>Spokane</CityName><CountryName>United States</CountryName></GetWeather></soap:Body></soap:Envelope>"
Action.c(46): t=556ms: 277-byte response headers for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=2)
Action.c(46):     HTTP/1.1 200 OK\r\n
Action.c(46):     Cache-Control: private, max-age=0\r\n
Action.c(46):     Content-Type: text/xml; charset=utf-8\r\n
Action.c(46):     Content-Encoding: gzip\r\n
Action.c(46):     Vary: Accept-Encoding\r\n
Action.c(46):     Server: Microsoft-IIS/7.0\r\n
Action.c(46):     X-AspNet-Version: 4.0.30319\r\n
Action.c(46):     X-Powered-By: ASP.NET\r\n
Action.c(46):     Date: Thu, 29 Dec 2011 22:53:27 GMT\r\n
Action.c(46):     Content-Length: 706\r\n
Action.c(46):     \r\n
Action.c(46): t=578ms: 706-byte ENCODED response body received for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=2)
Action.c(46): t=579ms: 1081-byte DECODED response body for "http://www.webservicex.com/globalweather.asmx" (RelFrameId=1, Internal ID=2)
Action.c(46):     <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.or
Action.c(46):     g/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://
Action.c(46):     www.w3.org/2001/XMLSchema"><soap:Body><GetWeatherResponse xmlns="http://www.webserviceX.NE
Action.c(46):     T"><GetWeatherResult>&lt;?xml version="1.0" encoding="utf-16"?&gt;\r\n
Action.c(46):     &lt;CurrentWeather&gt;\r\n
Action.c(46):       &lt;Location&gt;FELTS FIELD, WA, United States (KSFF) 47-41N 117-19W 609M&lt;/Location&g
Action.c(46):     t;\r\n
Action.c(46):       &lt;Time&gt;Dec 29, 2011 - 04:53 PM EST / 2011.12.29 2153 UTC&lt;/Time&gt;\r\n
Action.c(46):       &lt;Wind&gt; from the SSW (210 degrees) at 9 MPH (8 KT):0&lt;/Wind&gt;\r\n
Action.c(46):       &lt;Visibility&gt; 10 mile(s):0&lt;/Visibility&gt;\r\n
Action.c(46):       &lt;SkyConditions&gt; mostly clear&lt;/SkyConditions&gt;\r\n
Action.c(46):       &lt;Temperature&gt; 43.0 F (6.1 C)&lt;/Temperature&gt;\r\n
Action.c(46):       &lt;DewPoint&gt; 33.1 F (0.6 C)&lt;/DewPoint&gt;\r\n
Action.c(46):       &lt;RelativeHumidity&gt; 67%&lt;/RelativeHumidity&gt;\r\n
Action.c(46):       &lt;Pressure&gt; 29.99 in. Hg (1015 hPa)&lt;/Pressure&gt;\r\n
Action.c(46):       &lt;Status&gt;Success&lt;/Status&gt;\r\n
Action.c(46):     &lt;/CurrentWeather&gt;</GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope
Action.c(46):     >
Action.c(46): web_custom_request("post_xml") was successful, 706 body bytes, 277 header bytes   [MsgId: MMSG-26386]
Action.c(56): Notify: Transaction "post_xml" ended with "Pass" status (Duration: 0.2966).
Ending action Action.
Ending iteration 1.
Ending Vuser...
Starting action vuser_end.
Ending action vuser_end.
Vuser Terminated.



Saving Parameters From XML Response
The XML response can be saved in a parameter "Response" as follows:

    // save response
    web_reg_save_param("Response", "LB=", "RB=", "Search=Body", LAST);


With the response, fields from the xml can be extracted as follows to later be used in the next xml request.  In this case field "FieldInResponseXml" is saved to parameter "ResponseFieldParam":
   lr_xml_get_values("XML=\{Response\}",
     "ValueParam=ResponseFieldParam",
     "Query=//FieldInResponseXml",
     LAST);

The parameter {ResponseFieldParam} can then be used to construct the next xml request.




2 comments: