|
www.VuScripting.info for LoadRunnerHere is a concise description of scripting commands used in LoadRunner for computer system performance testing | Topics this page:
|
|
The VuGen Script File Development Process
| Ways to Script
|
Script Recording & Generation Basics
The first step to creating a new script is to select single or multi-protocol. Before working with Java protocols, make sure you have the JDK in the PATH environment variable. Otherwise you'll get this message:
Error: Failed to get JRE version. Check that your PATH environment variable contains When selecting a Java protocol:
When you open a new script, the name of the script is, by default, noname1. The name of the next new script is automatically incremented to noname2, etc. The default Working Directory for v7 scripts is C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin\ However, I prefer to use a folder on a network share created for specific projects. This provides for automatic backup (if available) and allows sharing. But rather than starting from scratch, I prefer to open an existing script and "Save As" the new script name. This allows me to modify a script file that has features I know works. Sooner or later, you're going to wish you had a prior version of a script you're working on. To make sure you have a version to fall back to, zip up the script folder immediately after you get a script to work. I prefer recording into an action (such as one named "Recording") that I have deleted from the Runtime Settings' Logic section. After the default Action section is deleted, it still appears in the list at the top of the icon list, but is shown with a grayed out icon. New actions are inserted beneath it. I do this to avoid accidentally running recorded scripts before editing, which I've done too many times because new actions are automatically added to the Logic list in Runtime Settings.
Before recording, write down the manual actions. Give a unique identifier to each step.
Record several actions in sequence (rather recording one action, then stopping and starting with another action). This allows you to recognize sequence numbering (in applications such as PeopleSoft) that you need to correlate in your script. Immediately after recording, copy the "Generation Log" to a text file in a different folder than the script you are working on. The next time you record, it will be wiped out. You'll need the file to see exactly what went to and back from the server. Every time a change is made in a script, that script needs to be recompiled. |
Java
|
Script File InvocationVuGen, by default, is invoked when you double click a file with suffix ".usr". Inside that file, a Javascript script is specified by "Type=General-Js". To avoid recompilation, I use a batch file to invoke the Controller with a command-line variable and value combination, such as:
SET LR80=C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin cd %LR80% wlrun.exe -TestRun c:\Temp\Scenario1.lrs -port 8080 |
Script File Actions (Sections)
LoadRunner creates new scripts with three sections:
VuGen allows only a single Action section for scripts using the COM/DCOM and Java protocols.
If your script only needs to run one iteration, you still need an Action section because some commands are illegal or are ignored in other sections (vuser_init and vuser_end). VuGen allows scripts emulating web protocols to contain more than one action. So I create a new action for each screen and paste into it script lines copied from that action used to hold the result of recordings. If you want several different users to login during a run, do not put login actions in vuser_init, but in an action scection. VuGen adds references to various ".h" header files depending on the protocols selected for the script: |
#ifndef _GLOBALS_H #define _GLOBALS_H //-------------------------- // Include Files #include "lrun.h" #include "web_api.h" #include "lrw_custom_body.h" // recorded for web_custom_request functions. //-------------------------- // Global Variables #endif // _GLOBALS_H For the COM/DCOM protocol (making calls to COM API functions and interface methods)
|
C Script FormatLoadRunner recognizes syntax defined for the ANSI C programming language with NO Microsoft extensions. The minimum for any action block is:#include as_web.h // from LoadRunner's include folder. Action1() { /* comment block */ // comment line return 0; }
|
|
C Script Compilation/librariesWhen VuGen compiles a script, it creates a file named "pre_cci.ci" which contains code from all actions and include files. This is why syntax errors refer to "not writing pre_cci.ci".The Controller compiles these .ci files into machine opcode. VuGen automatically creates within every script folder a lib folder which contains file combined_lib.c containing these lines referencing files in LoadRunner's /include folder:
#include "globals.h" from one of LoadRunner's template folders #include "vuser_init.c"
If you don't include the correct library when you use a function from that library, you will see message
| Yuriy Veytsman of IBM Lotus uses Use a LoadRunner workload as a model for a Rational LoadTest workload The lrun.h file defines several constants that you can use in your script:
LR_PASS and PASS = 0
|
C LibraryLoadRunner uses 1994 GNU C Pre-Processor options and the 1995 LCC-win32 Retargetable C Compiler/Linker from the Free Software Foundation via Chris Fraser of AT&T and Dave Hanson of Princeton.
Additional functions are defined in the ANSI C library External C functions which do not return integers need to be explicitly declared near the beginning of a script. For example, string functions such as string tokenizer:
extern char* strtok(char *token, const char *delimiter);
External C libraries are needed to emulate Javascript actions that are not directly apparant in the GET/PUT fields of outgoing requests. Examples of this include number generation routines and Infragistics NetAdvantage components. |
Javascript Issued from ClientsLoadRunner didn't recognize XML responses issued by Javascript on the client (41308) However v8.1 185MB FP4 offered with the "Web (Click and Script)" protocol for new scripts. AJAX presents a problem because more and more web apps (such as maps.google.com) make use of AJAX (Asychronous Javascript and XML) techniques and encryption. In many AJAX applications, AJAX requests and responses impose a greater load than initial HTML page requests typical of traditional non-AJAX web applications. The concern for LR scripters is that we need to understand what that javascript does, since client-side Javascript can transform data and issue requests -- logic that LoadRunner scripts may need to be duplicated if they are expected to emulate the same load. There are several approaches to emulate AJAX: One is to create a script file created as "Web (Click and Script)" protocol and recording C code. AJAX calls are recorded and sent out as custom requests. Two is to convert Javascript executed by the client into C code executed by LoadRunner. Three is to paste (captured static) client Javascript code into LoadRunner by making LoadRunner understand Javascript by creating a single-protocol script of category "Javascript Vuser". After you create the new file, notice the "global.js" action which defines these replay helpers: //var web = new ActiveXObject("LoadRunner.WebApi"); var objectHelper = new ActiveXObject("LoadRunnerVbs.ObjectFactory"); var recordsetHelper = new ActiveXObject("LoadRunnerVbs.RecordSetHelper"); The default is "LrApi", so if you are working over the web, comment that line out and uncomment the "WebApi" line. This "template solution" limits you to ONLY use Javascript (no C lines) and does not record code for you. This means that you have to first record into a script, then convert the recorded statements (web_url, etc.) into Javascript format. KB 9396 provides a side-by-side before/after conversion example, which I've indented to my style here: web.url("T01", "URL=http://www.mi.com/"); new Array( "TargetFrame=", "TargetBrowser=Mercury Technologies", "Resource=0", "RecContentType=text/html", "Snapshot=t1.inf", "Mode=HTML", "LAST" ) ); web.submit_data("T03","Action=http://www.mi.com", new Array("Method=POST", "TargetFrame=", "RecContentType=text/html", "Referer=hhttp://www.mi.com/?cmd=login", "Snapshot=t2.inf", "Mode=HTML"), new Array( new String("Name=username"), new String("value=userid"), new String("Name=password"), new String("value=pwd"), new String("Name=remember"), new String("value="), new String("Name=x"), new String("value=0"), new String("Name=y"), new String("value=0") ) ) ); Note the differences:
Unlike Java vuser scripts, there is not try/catch blocks with Javascript. |
Controlling Message Display
LoadRunner provides several functions to issue information during a run:
The "\n" escape character adds a line break on UNIX/Linux machines. The "\r" escape character adds a line break on Windows machines.
|
Log Message DisplayvuGen defaults to display at the "Standard log" level of detail.I find that I need to change this setting in the Runtime Settings Log dialog (shown at right) because I either different verbosity levels depending on the maturity of the script.
When a run starts with the Message Level set to Send messages only when an error occurs, this reminder message appears in the output:
To change this behavior, look at the Log tab in Run Time Settings. When a run starts with both "Always send messages" and "Advanced trace" checked, LoadRunner prints this at the top of the log.
|
Programming Log VerbosityTo mimick clicking in the Runtime Settings Log dialog (shown above), consider these lines to change the message level just-in-time within code:if (msg_level & LR_MSG_CLASS_JIT_LOG_ON_ERROR ){ lr_set_debug_message(LR_MSG_CLASS_JIT_LOG_ON_ERROR , LR_SWITCH_OFF); } sapgui_status_bar_get_type("rStatusBarType", LAST); sapgui_status_bar_get_text("paramStatusBarText"); if( stricmp( lr_eval_string("{rStatusBarType}"),"Error") == 0 ){ lr_end_transaction("..._Save",LR_FAIL); }else{ // "Success" lr_end_transaction("..._Save",LR_AUTO); } lr_output_message(">>> %s=%s" ,lr_eval_string("{rStatusBarType}") ,lr_eval_string("{paramStatusBarText}") ); if (msg_level & LR_MSG_CLASS_JIT_LOG_ON_ERROR ){ lr_set_debug_message(LR_MSG_CLASS_JIT_LOG_ON_ERROR , LR_SWITCH_ON); } Lines containing LR_MSG_CLASS_JIT_LOG_ON_ERROR toggle between "Always send messages" and "Send messages only when an error occurs". My LoadRunner Framework concapsulates these lines into functions wi_startPrinting() and wi_stopPrinting(). The ampersand in "if( msg_level & LR_MSG_CLASS_JIT_LOG_ON_ERROR" is a bit-wise operator to determine if a bit value is within the variable msg_level. Loadrunner provides only one function to set the various log verbosity settings by storing all message level selections together within the various bits within a single byte. The various bits are described in this table below.
LR_SWITCH_OFF is a constant for value zero. LR_SWITCH_ON is value 1. "Enable logging" is assumed to have been checked when the message level has either the 1 or 16 bit set on. "30" is the same as this script:
The | operator between constants is a logical OR which combines the binary value of constants associated with LR_MSG_CLASS_EXTENDED_LOG. Internally, specifying all extended log subtypes would result in a value of 30 ( 16 + 4 + 2 + 8 ), as described in this table rationalizing the GUI Run-time Settings dialog box hierarchy of radio buttons and optional check boxes controlling output, to the binary bits within its "message level" variable. |
Web User Actions
Examples of non-HTML-generated resources are .gif and .jpg images. The List of Resource Attributes is only inserted when the recording option for these resources is set at "Record within the current script step". This is the default setting. If you checked "a script containing explicit URLs only" in Tools > Internet Procotol > Recording, you will invoke URL-based script recording of only web_url or web_submit_data functions, not web_link or web_image functions or Non-HTML elements which include applets, XML, ActiveX elements, or javascript. Before taking action to advance to the next page (such as clicking a link or icon), pause recording, go to the application to copy the title of the screen, then paste that text into a comment. After recording, this will be later used in naming the transaction. After each page appears, pause recording, go to the application to copy the text used to determine whether the expected page appears. then paste that text into a comment. After recording, this will be later used in text verification checkpoint script statements. Information about what happened during recording is stored in file RecordingLog.txt Deleting this file will not affect the script's replay.
| There is no "lr_get_scenario_id()" built-in LoadRunner function for the C language corresponding to the "lr.get_scenario_id()" function for Java. The Scenario ID is not available either as a type of parameter like VuserID, Iteration, etc. |
Scripting Language Rules
web_reg_find("Text/ic=Welcome",LAST); The list of parameters within parentheses contain LAST to designate the last parameter. This is convenient because the sample above omits an attribute that designates whether "found" or "notfound" is the expected result. The default is "found", so I usually omit it. Another text flag is "/BIN" to specify binary data character set. For example, to look for "Adams": web_reg_find("Text/BIN=\\x00A\\x00d\\x00a\\x00m\\x00s",LAST); Note the two backslashes, which is an escape character representation for a single backslash within quotes. If only one backslash is used by mistake, LR will think it is a null terminator. This sample script to support UTF-16 encoding intializes a "UTF8Server" boolean variable used to determine the two ways to save what is captured to the same "newquoteuid" parameter. For example, because LoadRunner captures UTF16 "Red" in ASCII as "R\x00e\x00d\x00", rather than registering, it needs to be captured into a buffer:
lr_eval_string_ext("{newquoteuid_temp}", strlen("{newquoteuid_temp}") + 2, &Buf, &BufLen, 0, 0, -1); Strip out extra padding (x00) using the lr_save_var function on character array variable named NewBuf:
for (i=0; i if (Buf[i]!=0) NewBuf[NewBufLen++]=Buf[i]; lr_save_var(NewBuf, NewBufLen-1, 0, "newquoteuid"); Note lr_save_var requires four attributes (and doesn't use LAST):
LoadRunner 7.8 does not support regular expressions, but has its own (limited) wildcard functionality:
web_reg_save_param("pSer","LB/DIG=Serial XXX-###-ZZZZ","RB=\r\n", LAST ); There are three ways to use the caret sign (^) as a wildcard:
To convert a string to upper case:
|
Verification Checkpoints
These Web Vuser script functions are not recorded by VuGen but must either be manually program into the script, or use the VuGen user interface (Insert > New Step... > Web Checks) to generate the function code.
|
Capturing Data From Streams
LoadRunner may automatically create these statements if it detects SESSION ID being used in the URL. web_reg_save_param("pReturnedBuffer","LB/ic=<HTML>","RB=</HTML>", LAST );
lr_output_message stops display as soon as it encounters a null (binary "\\x00") character.
To look for binary data, use the text flag "/BIN". For example, to look for "Adams":
Note the two backslashes. If only one backslash is used by mistake, LR will think it is null terminator. These functions must be placed immediately before the web_url statement which creates the data being examined. To capture the last HTTP return code received
To capture the URL to which the user is redirected into a user parameter buffer named "pRedirect2URL" text
that is between the text "Location:" to the left and
special escape characters
for return/next line.
However, to capture all instances of redirection, add the "ORD=ALL" attribute:
If you are capturing a URL address with % coding, convert it
back to single special charactersby adding "convert=HTML_TO_TEXT".
To find the value of the last instance, we use the sprintf function (from within #include "as_web.h") to put in the new variable "last" the value within the instance of parameter pRedirect2URL. For example, if the pRedirect2URL_count is 5, pRedirect2URL_%s will become pRedirect2URL_5. char last[30]; ... sprintf(last, "{pRedirect2URL_%s}", lr_eval_string("{pRedirect2URL_count}")); lr_save_string( lr_eval_string(last) ,"pRedirect2URL_Last"); The lr_save_string function above creates a parameter variable named "pRedirect2URL_Last" and inserts into it the value of variable "last". The lr_eval_string function must be used for parameters accessed from within another function. Scripting for Microsoft ASP.NET VIEWSTATEBased on Mercury Knowledge Base article 24264, 18587, 26804, 15392, and other sources:
For LoadRunner 7.6 or 7.8, you will need to apply the trpfnc32.dll (43,780 bytes dated 7/16/2003 2:44 AM) in the
Windows ASP.NET web applications maintain state data by passing across Pagebacks a
hidden _VIEWSTATE field encoded in base64.
This number needs to be adjusted after examining a captured example.
68719476735 (2 ^36 -1) is the maximum length for web_set_max_html_param_len.
So if your data exceeds this boundary, create multiple correlation statements.
This area is repeated for each vuser. So the larger this parameter, the less vusers you are able to run.
SOAP, XML, and Web Services
If you're still on LR 7.8, to capture SOAP web services calls and to scan for WSDL 1.1 files, install the 7.8 Feature Pack 1 (which installs MSSOAP Toolkit 3.0) and buy a Mercury Web Services add-in license, which provides an XML viewer and SOAP listener that complies with WS-I basic profile 1.1. LoadRunner's WSDL parser creates web_service_call functions with a UI tool instead of recording. LRXML is an essential API of the protocol. I've had problems with soap_request function because its argument are passed through the XML parser. So I prefer using the web_custom_request function because it is not passed through the XML parser. Here is an example of a SOAP call to a Windows .NET web service using the ISO-8859-1 character set: web_remove_auto_header("Accept-Encoding", LAST); web_add_header("User-Agent", "NuSOAP/0.6.7 (1.75)"); web_add_header("Content-Type", "text/xml; charset=ISO-8859-1"); web_add_header("SOAPAction", "\"http://mmm.com/a\"" ); web_custom_request("Auth_request", "URL=http://x.com/y/z.asmx", "Method=POST", "TargetFrame=", "Resource=0", "Referer=", "Body=<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" "<SOAP-ENV:Envelope " "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" " "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" " "xmlns:si=\"http://soapinterop.org/xsd\" " "xmlns:nu=\"http://testuri.com\">" "<SOAP-ENV:Header>" "</SOAP-ENV:Header>" "<SOAP-ENV:Body>" ... "</SOAP-ENV:Body>" "</SOAP-ENV:Envelope>", LAST);"<SOAP-ENV:Envelope " can also be coded "<soap:Envelope ".
Note that quotes must be made into escape characters.
The code above should generate this HTTP header: POST /y/z.asmx HTTP/1.1\r\n Content-Type: text/xml; charset=ISO-8859-1\r\n Cache-Control: no-cache\r\n User-Agent: NuSOAP/0.6.7 (1.75)\r\n SOAPAction: "http://x.com/a"\r\n Accept: */*\r\n Connection: Keep-Alive\r\n Host: x.com\r\n Content-Length: 1820\r\n NOTE: SOAPACTION is unique to Microsoft, which assumes http://tempuri.org as the namespace. MSDN articles on messaging protocols Tracing COM/COM callsCOM/DCOM scripts can't use web_save_param.
|
RandomizersLR has a built-in C mathematical rand function and the % operator (called "modulus" or "mod") to automatically come up with a random value (an integer between 0 and RAND_MAX) iRand = rand() % 100; To obtain a unique number every time, call the seed randomizer function "srand" built-in function coding such as this:
Executing the line above more than once per second will yield the same number because the time function has a one second resolution because of a known bug. So instead use one of these two lines:
To execute a function only 30% of the time (30 out of 100 iterations): iRand = rand()%100; if( 30>=iRand ){ // web_url( ... } else { // not executed } This sample script that determines the range of the randome number from a count:
... search rand_selection = ( rand() % atoi(lr_eval_string("{search_param_count}")) + 1); The resulting new parameter (rand_selection) is used as the suffix to obtain the value found by the search:
|
Date/Time ManipulationDate and Time data can be handy to create unique data automatically.There are two ways to insert a date/time string into a form submit:
|
Fault Tolerance in Retry Logic
int iLoops; int iRegReturn; int iReturn; int iFileSize; // Retry 5 times: for( iLoops=0; 5<=iLoops; iLoops++ ){ iRegReturn = web_reg_find("Text/IC=<\\html>", "NOTFOUND=warning", "SaveCount=pCountA", LAST); iReturn = web_url("mercury", ... ; iFileSize = web_get_int_property( HTTP_INFO_DOWNLOAD_SIZE ); if( iRegReturn == LR_PASS && iReturn == LR_PASS && iFileSize > 0 && strcmp(lr_eval_string("{pCountA}"), "0") == 0) ) { lr_message("Step X successful."); // fall out to continue to next iLoop. }else{ lr_error_message("Step X failed!"); lr_vuser_status_message("Step X failed!"); lr_exit(LR_EXIT_ITERATION_AND_CONTINUE,LR_FAIL); } } |
Error Diagnosis and Recovery
load into the script folder a PEM formatted list of Certificate Authorities:
web_set_sockets_option("LOAD_VERIFY_FILE", "certFile.pem");
|
Logic Using Files
fp=fopen("file.txt",w); This Vu script function 1) opens the file named in the value of parameter named {XFileToOpen}, 2) read its contents into a buffer, then 3) turns the contents of that file into another parameter {XFileContents}: // Initialize parameters: long file_stream; char *filename = "c:\\url.txt"; // Name of file to read // the above to be replaced by parameter {XFileToOpen} char buffer[1000]; int count, total = 0; /* Some other action to obtain parameter {pFileToOpen} */ // Step 1) Open file named in the value of parameter named {pFileToOpen}: if ((file_stream = fopen( {pFileToOpen}, "r")) == NULL ) { lr_error_message("Cannot open %s", filename); return -1; } // Step 2) Read the file's contents into a file_stream: while( !feof( file_stream ) ) { /* Read 1000 bytes while maintaining a running count */ count = fread(buffer, sizeof(char), 1000, file_stream); fwrite( buffer, sizeof(char), 1000, file); fclose(file); lr_output_message("%3d read", count); if (ferror(file_stream)) { /* Check for file I/O errors */ lr_output_message("Error reading file %s", filename); break; } total += count; /* Add up actual bytes read */ } /* Display final total */ lr_output_message("Total number of bytes read = %d", total ); /* Close the file stream */ if( fclose( file_stream )) { lr_error_message("Error closing file %s", filename); } return 0; } // Step 3) Turn the contents of that file into // another parameter {pFileContents}: lr_save_string( "{pFileContents}", "pFileContents");
|
File Output Based on Environment Variables
char *tmpFilePath, logfile[512]; long fileOutHandle; // Retrieve (cast) the temporary directory path // from environment variable: if( tmpFilePath = (char *)getenv("TEMP")) lr_output_message( "Env. var. TEMP = %s", tmpFilePath ); else { lr_error_message("Env. var. TEMP is undefined."); return -1; } // Concatenate file path with file name: sprintf( logfile, "%s\\%s", tmpFilePath, "sample.txt"); // Open file for Writing: if (( fileOutHandle = fopen( logfile, "w")) == NULL ) { lr_error_message("Cannot open %s", logfile); return -1; } else { lr_output_message("Opened %s", logfile); } fprintf( fileOutHandle , "this is some file\n"); fclose( fileOutHandle );Before running the above, the default path can be altered by changing the environment variable: putenv("TEMP=D:\\Temp"); But note this setting is not persistent (does not appear in output from SET commands in DOS CLI). |
Multiple Parameter Values
However, you can take control of the access method using a custom function, lr_next_row from 1688-lr_next_row.zip but you'll also need to keep track of the current line of the parameter value accessed.
|
External Function Libraries
The Windows operating system kernel interprets OS level commands:
More information on this in the "Creating Virtual User Scripts" User's Guide, under the Appendixes section for 'Calling External Functions'
Calls to C librariesOne need for an external function library is to call functions and use constants not in the standard C library that comes with LoadRunner, such a the power or log functions from math.h :#include "math.h" // from LoadRunner's include folder. double pow(double x, double y); Action1(){ double x = 2.0, y = 3.0; lr_output_message ("%lf raised to the power of %lf = %lf\n", x, y, pow(x, y)); return 0; } Note that the variables x and y are defined as double, so they must be referenced with tag "%lf" within lr_output_message. Open SSL Certificate infoThis script prints info about the SSL certificate from a website by using the Open SSL API the MicSocket.dll which references the mic_socket.h header initialized within vuser_init:#include "as_web.h" #include "mic_socket.h" vuser_init() { int rc = lr_load_dll("MicSocket.dll"); if (rc == LR_FAIL) { lr_log_message("Failed to load MicSocket.dll."); } return rc; } Running the Action1.c script results in this output:
X509 Version : V3 Subject Name : /C=US/ST=Arizona/L=Scottsdale/O=Go Daddy Software Inc./OU=MIS Department/CN=www.godaddy.com Subject Hash : 864c5bf4 Issuer Name : /C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./OU=http://www.starfieldtech.com/repository/CN=Starfield Secure Certification Authority/Email=practices@starfieldtech.com Issuer Hash : b737b221 Serial Number : 30-00-9E Valid Not Before : 040507101403Z Valid Not After : 060309010348Z Is Valid : YES SSL Connection Cipher Information: Cipher Name : RC4-MD5 Cipher Description : RC4-MD5 SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=MD5 Cipher Version : TLSv1/SSLv3 Cipher Alg. Bits : 128 bits Actual Bits Used : 128 bits
| The CWebPage COM class by Eugene Khodakovsky includes a demo to call Javascript as COM objects. |
Software Correlation
If web_add_cookie commands are commented out, the application would send a new cookie during playback.
|
XML/SOAP
web_url("xQuotes.asm", "URL=http://www.xignite.com/xQuotes.asmx?op=GetQuote", "Resource=0", "RecContentType=text/html", "Referer=", "Snapshot=t1.inf", "Mode=HTML", EXTRARES, "Url=http://images.xignite.com/i/p.gif", "Referer=http://www.xignite.com/xQuotes.asmx?op=GetQuote", ENDITEM, LAST); web_reg_save_param("pXLMin", "LB=", "RB=", "Search=body", LAST); web_submit_form("GetQuote_2", "Snapshot=t3.inf", ITEMDATA, "Name=Symbol", "value=MERq", ENDITEM, "Name=xMethod", "value=GET", ENDITEM, "Name=xNewWindow", "value=on", ENDITEM, "Name=InvokeButton", "value=Invoke", ENDITEM, LAST); // lr_output_message(lr_eval_string("*** Query Result = {pXLMin}")); // Test if Extract string fragment from XML into a top-level parameter: lr_xml_find("XML={pXLMin}","value=Success", "Query=Outcome", LAST);// If found, this message appears -- "lr_xml_find" was successful, 1 match processed // If not found, this message appears -- Error: "lr_xml_find" execution failed When getting a string from XML into a mid-level parameter, use "SelectAll=" in case the structure changes in the future: int i, NumOfValues; // ... NumOfValues = lr_xml_get_values("Xml={pXLMin}", "Query=Quote/Percent_Change", "ValueParam=pPctChg","SelectAll=yes", LAST); for ( i = 0; i < NumOfValues; i++) { sprintf(buf, "Percent_Change value %d : {OutputParam_%d}", i+1, i+1); lr_output_message(lr_eval_string(buf)); }Each level in the XML hierarchy must be specified. In this sample, Percent_Change is within Quote. To extract a sub-set of XML at or below the level specified to a new parameter: lr_xml_extract("XML={pXLMin}", "XMLFragmentParam=pQuotesXML", "Query=Quote", LAST);Other LoadRunner XML Functions:
|
Output Loggingweb_get_int_property(HTTP_INFO_DOWNLOAD_SIZE) returns an integer that is 251 bytes larger than the number of bytes of the .htm/.html code file. |
Timing Time-outsOne of the most important reasons for performing test runs of scripts is to manage the behavior of transactions timing out, which are false negatives -- problems caused by the testing environment rather than the application under test. When recording scripts, I prefer to have wait times automatically inserted into the generated script. I then comment them and then add a consistent wait time (such as 0.5 seconds). This approach provides me a quick way to separate lines for different actions. Runtime Settings of Internet Preferences Options can be overridden by script functions:
To customize the ThinkTime parameter, use the lr_get_attribute_long or _double function to pull in the command line parameter into a script.
|
Remove Wasted Time
In on-line graphs in the LoadRunner Controller and in transaction response time graphs in LoadRunner Analysis, transaction elapsed response times have wasted time subtracted from the "Duration" time in Vuser logs. Activities are temporarily taken on and off LoadRunner's elapsed transaction time clock by using a separate timer to determine the waste time, then add that to the wasted time counter automatically maintained by LoadRunner: double dWastedTime; merc_timer_handle_t charWasteTimer; lr_start_transaction("Demo"); // some real work counted in elasped time here. charWasteTimer = lr_start_timer(); // actions to be considered wasted time // think time is never counted as wasted time dWastedTime = lr_end_timer( charWasteTimer ); // in # seconds lr_wasted_time(dWastedTime *= 1000 ); // add in milliseconds lr_end_transaction("Demo", LR_AUTO);An alternative is: lr_start_transaction("Demo1"); // ... actions before "wasted" lr_stop_transaction("Demo1"); // ... actions considered "wasted" lr_resume_transaction("Demo1"); // ... actions not "wasted" lr_end_transaction("Demo1", LR_AUTO);As of LR8.0, these are not available in Java. But ask to see if a patch has come out of QA containing:
lr.class in C:\Program Files\Mercury Interactive\Mercury LoadRunner\classes\lrapi Time can be obained with these functions:
|
Rendezvous PointsRendezvous Points are specified to ensure that all specified vusers begin a transaction at precisely the same time. The Controller automatically enables its Scenario > Rendezvous pull-down menu when its scans recognize in the scripts of all Vuser groups in the scenario a command such as: lr_rendezvous("rendezvous_1"); // Set rendezvous point. The Controller lists users and scripts having rendevous commands in its Rendezvous Information dialog box. Rendeveous commands are not recognized in Vuser_init and Vuser_end sections. The Controller releases Vusers based on the Policy dialog shown when the "Policy..." button is clicked. |
TimingsHere is sample code to obtain timings for 5,000 reptitions of ways to assign strings. When run, the timings are about the same, which means that there is no performance degradation from using loadrunner parameters over fixed length character string arrays. |
Cleaning Up FilesWhen VuGen runs, it creates a data folder with a lot of "cruft" files. When a script is saved as a new name by VuGen, only files it knows about are copied to the new folder: .usr, .c, .prm, and .dat files. This Windows batch file deletes extraneous files that are regenerated by VuGen during each compilation, so do not need to be kept: rem cd %1 del /q pre_cci.c del /q *.log del /q *.txt del /q *.ci del /q *.bak del /q *.class del /q *.sed del /q *.idx rem del /q *.dat del combined_*.c rd /q /s data pause You may also want to delete the default "result1" folder and other result folders you created. |
Type=Multi AdditionalTypes=WebJS ActiveTypes=WebJS GenerateTypes=WebJS RecordedProtocols=WebJS MajorVersion=8 MinorVersion=1 LastModifyVer=8.1.4.0
Related Topics:
Performance Testing
NT Perfmon / UNIX rstatd Counters
Mercury LoadRunner
Mercury Virtual Table Server (VTS)
Mercury WinRunner
Rational Robot
Free Training!
Tech Support
| Your first name: Your family name: Your location (city, country): Your Email address: |
Top of Page
Thank you! |