How I may help
LinkedIn Profile Email me!
Call me using Skype client on your machine

Reload this page www.VuScripting.info for LoadRunner

Here is a concise description of scripting commands used in LoadRunneranother page on this site for computer system performance testinganother page on this site

 

Topics this page:

  • Script Development
  • Script Recording
  • Script File Sections
  • Script Language Rules
  • Error Messages
  • Your comments???
  •  

    RSS XML feed for load testers RSS preview for load testers Site Map List all pages on this site 
    About this site About this site 
    Go to first topic Go to Bottom of this page


    The VuGen Script File Development Process

    1. Define the test project's objectives, environment, scripts, data, hardware, etc. The assumptions for the script should reference coding standards/conventions.
      Idea I code HTML to create a web page that I can link to in my status reports.
    2. Create a versioned folder to store the various assets associated with the application under test, such as .png/.gif image files of pictures that will be captured, html file saved from the recording, the full source html file from the recording, and the VuGen recording log.
    3. List (in a table) for each business processes the manual actions needed to walk though the actual application steps needed to 1) capture each screen image for documentation, 2) assign a unique transaction name to each screen, and 3) note the technical component (URL or method and function) handling each step.

      Idea So that transaction names are listed in the sequence of manual steps, I assign transaction names using zero-filled zeros (such as "09", etc.).

      View captured screen I capture the image of each screen into an MS-Word file or a separate .gif file referenced from an icon on a webpage.

      Idea As needed, I note for each screen/step its testability status (such as not available for use, script having errors, is being ignored, data parameterization, variations in values, etc.)

    4. Create a versioned folder.
      Idea I prefer not to use the default location, but to store all files associated with a script together in the same folder. Unfortunately, this means that if I switch between different tests, I have to remember to change the default settings every time.

      Idea When working with a new script, I select "Multi-protocol" rather than "Single protocol because the UI is better. I can sort actions only within the multi-protocol UI. Protocolsanother page on this site

    5. Use VuGen to generate a sequence of script code by Recording the application according to the sequence of screens and user steps specified in your business processes list. In the "Start Recording" dialog:

      • select application type "Win32 Application" to use the COM/DCOM protocol
      • select application type "Internet Application" to use the "Web(HTTP/HTML)" protocol.

    6. Edit the script based on the Ways to scripton this page list at right and following script language ruleson this page

      • Comment out cookie code (because they will be performed again when the script is run).

    7. Debug and Adjust script (for a single user) by running it within VuGen with Runtime Settings Logs set to display all messages:

      • Identify and fix script editing errors.
      • Determine timingson this page
      • Set initial Runtime Settings Scenariosanother page on this site

    8. Run in Controller using full test Runtime Settingson this page

     

    Ways to Script


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Script Recording & Generation Basics

      Idea When you open VuGen for the first time, click the box on the lower left corner so that you can select existing scripts.

      Reminder The first step to creating a new script is to select single or multi-protocol.

      • Some protocols may not be available in multi-protocol mode.
      • You can rearrange actions only within the multi-protocol GUI.

      Java 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 find javac.exe Java Compiler in Path and JDK installation folder in registry. [MsgId: MERR-22981]
        Error: Failed to get JRE version. Check that your PATH environment variable contains \bin directory. [MsgId: MERR-22986]

      When selecting a Java protocol:

      • You can only record if you select "RMI Java".
      • "Start Recording" icon/menu will be grayed out if you select "Java user".

      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.

      Idea 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.

      Idea 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.

      Idea 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.

      Idea 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.

      Idea Before recording, write down the manual actions. Give a unique identifier to each step.
      As you record, insert each identifier from your list after each action.

      Reminder 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.

      Idea 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.

      Reminder Every time a change is made in a script, that script needs to be recompiled.

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Java Java

      LoadRunner with Java

    1. Java appletsanother page on this site running on JRE (Java Runtime Environment) clients are
    2. usually invoked from within a predominantly web GUI application
    3. which also contains HTML.
    4. Normally, the classes are automatically downloaded within a jar file.
    5. With applets that are signed, VuGen need them to be
    6. unjarred into
    7. their separate class module files.

    8. VuGen recognizes "RMI-Java" or "CORBA-Java" calls that fit specifications defined in the
    9. user.hooks filter file in the LoadRunner folder.
    10. VuGen records those calls as Java code in Java programming code which is modified to add verification, etc.
    11. During recording, RMI serialization creates .dat files which can be added as actions in the Java VuGen script.

    12. Since VuGen cannot record multiple protocols along with Java (such as with Web HTML), the web (HTTP) traffic issued around the Java applet must
    13. first be recorded into a VuGen C language script setup to record web(HTML/HTTP) protocol communications
    14. into C programming script, then
    15. using the sed.exe utility
    16. convert generated C-language code into Java-language code.
    17. Note that the sed utility is controlled by sed specification files
    18. edited with a plain text editor program.

    19. Using VuGen, the Java code created with these two methods are manually merged using VuGen editor and
    20. compiled from within VuGen
    21. that the Controller passes
    22. (along with other script groups) to
    23. Load Generators (injectors) for playback to
    24. impose a load on servers under test.

    25. Java VuGen script compilation is done by VuGen using javac.exe
    26. from an installtion of the Java SDK.
    27. Un-jarred CORBA ORB classes are needed to satisfy compiler dependencies, even though they have been replaced by calls to custom classes. Thus, they are not needed
    28. by classes the VuGen and Controller use for replay.

    29. If the source code for the application (applet) under test contains security provisions such as protected classes and communications encrypted through Entrust private key files, the source would
    30. need to be modified (to make classes public and/or bypass the security)
    31. with a code editor
    32. and then recompiled
    33. into modified class files
    34. used instead of mainstream classes because the folder containing modified classes is listed in the CLASSPATH before (and thus retrieved before) the folder containing mainstream classes.
    35. So the version of the SDK used to compile the application should be what VuGen uses.

    36. Data (*.dat) files provide various data values during playback on both VuGen and on Load generators controlled by the LoadRunner Controller.
    37. java.policy file in C:\jdk1.3.1_15\jre\lib\security (opened with WordPad, not Notepad)


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Script File Invocation

      VuGen, 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".

      Idea To avoid recompilation, I use a batch file to invoke the Controller with a command-line variable and value combination, such as:

        REM LoadRun from LoadRunner 8.0 default installation location:
        SET LR80=C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin
        cd %LR80%
        wlrun.exe -TestRun c:\Temp\Scenario1.lrs -port 8080


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Script File Actions (Sections)

      The requests which agents on host machines issue to application servers are specified by a playback of actions created by the Vuser User Generator (VuGen.exe).

      LoadRunner creates new scripts with three sections:

      • vuser_initon this page for initializing a Vuser.
        Vusers are in "Init" status when executing this action.

      • Action action is repeated for multiple iterations.
        Vusers are in "Running" status when executing this action.

      • vuser_endon this page for Vuser logoff.
        Vusers are in "Exiting" status when executing this action.

      Reminder 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.

      Reminder 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 fileson this page depending on the protocolsanother page on this site selected for the script:

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen C .h Header Files

      For the Web(HTTP/HTML) protocol,

        globals.h is created to contain:

          #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)

      • File user.h containing functions to translation your Vuser script into low level COM/DCOM calls using

      • #include "lrc.h" header file which references

      • interface pointers and other variable declarations in file interfaces.h for each GUID generated by VuGen during recording.

      • globals.h

      • recordsets.h

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      C Script Format

      LoadRunner 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;
        }
        

     

     

    • I prefer to align /* above its corresponding */.

    • Comment blocks (text between /* and *\) cannot be nested.

    • return 0; is mandatory.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      C Script Compilation/libraries

      When 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 "lrun.h" to define functions for either UNIX or Windows.
        #include "globals.h" from one of LoadRunner's template folders

        #include "vuser_init.c"
        #include "Action.c"
        #include "vuser_end.c"

      Caution! If you don't include the correct library when you use a function from that library, you will see message

        Error -- Unresolved symbol

       

    Yuriy Veytsman of IBM Lotus uses this LoadRunner script to
    webpage article 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
    LR_FAIL and FAIL = 1
    LR_ABORT = 3
    LR_STOP = 3

     
    Go to Top of this page.
    Previous topic this page
    Next topic this page

      C Library

      LoadRunner uses A website external to this site 1994 GNU C Pre-Processor options and the A website external to this site 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 zip file 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.

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Java Syntax

      To drive Java, Corba-Java, or RMI-Java type Vusers, code Java syntax enclosed within try-catch exception blocks:

      try { 
          lrapi.web.save_header(lrapi.web.RESPONSE, "response header"); 
      	/* Other calls */ 
      } 
      catch (Exception e) {} 
      
      Java custom classes must be thread-safe because it runs as a scalable multi-threaded application.

     


     
    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Javascript Issued from Clients

      LoadRunner 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 lr = new ActiveXObject("LoadRunner.LrApi");
      //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:

      • "web.url" with a dot rather than "web_url" with an underline.
      • "lr.AUTO" with a dot rather than "LR_AUTO" with an underline.
      • "ITEMDATA" and "ENDITEM" in C language scripts are replaced with nested arrays.
      • There is no equivalent for "web_reg_find" with Javascript type scripts.
      • There is no equivalent for "NULL".

      Unlike Java vuser scripts, there is not try/catch blocks with Javascript.

     


     
    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen VUser_Init Section

      Here are examples of what goes into the Vuser_init section.

      OS User ID

      This displays the user's ID obtained from the operating system using the GetUserNameA function from the advapi32.dll

      	char	sUserID[1024]; // Maximum possible UserID length.
      	long	lUserIDSize = sizeof(sUserID)-1;
      	int 	rc;
      
      	rc=lr_load_dll("advapi32.dll");
      	if( rc != 0 ){
      		lr_error_message("lr_load_dll of advapi32.dll failed. Aborted for rc=%d",rc);
      		lr_abort(); 
      	}else{
      		GetUserNameA(sUserID, &lUserIDSize);
      		lr_message("UserID='%s'", sUserID);
      	}
      

      All variable declarations need be to all together at the top. Reminder A local C variable (such as int or char) created in the vuser_init section of the script (such as "int x") is not visible to other sections of the script. So create parameters that are global to all sections using the lr_save_string function. Example:

      char *itoa ( int value, char *str, int radix ); 
      vuser_init(){ 
      	int x = 10;
      	char buffer[10]; 
      	lr_save_string( itoa( x, buffer, 10) , "pX" ); 
      	lr_message ( "int x = %s", lr_eval_string("{pX}" )); 
      return 0;
      } 
      

      Set screen Additional Attributes in Run-Time Settings

      Version 8.0 ushered in a very valuable feature: the ability to specify attributes in run-time settings, which can have different values for each vuser group.

      The following code reads from Run-time Settings Additional attributes an argument named "usertype". then uses the Argument value to correspondingly set its global "thinktime1" variable.

      int thinktime1=0;
      vuser_init()
      {
        LPCSTR strUsertype; // Define *str.
        strUsertype = lr_get_attrib_string("usertype");
        if (strUsertype==NULL){
          lr_output_message("### Run-time Settings Additional Attribute usertype not specified. Cannot continue.");
          lr_abort();
        }else{
          lr_message("### Run-time Settings Additional Attribute usertype=\"%s\"", strUsertype );
          if( strcmp( strUsertype,"advanced") == 0 ){ thinktime1=2; }
          else
          if( strcmp( strUsertype,"intermediate") == 0 ){ thinktime1=4; }
          else
          if( strcmp( strUsertype,"basic") == 0 ){ thinktime1=8; }
          else{
            lr_error_message("### ERROR: Value not recognized. Aborting run." );
            lr_abort();
          }
        }
        return 0;
      }

      Set screen Time Structure Fix

      According to Knowledge Base article 34195, by default the millisecond part of the current time stamp is not updated unless the time struct used by ftime is redefined:

      typedef long time_t; 
      struct _timeb { 
         time_t time; 
         unsigned short millitm;
         short timezone; 
         short dstflag; 
      }; 
      struct _timeb t; 
      _tzset(); \\ Sets variables used by ftime 
      _ftime( &t ); 
      lr_message( "Plus milliseconds: %u", t.millitm ); 
      


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Controlling Message Display

      During a run, when a script fails a transaction and continues, how will you know which user failed?

        Idea After each transaction failure, issue a message which contains information uniquely identifying the user involved.

      LoadRunner provides several functions to issue information during a run:

      • // send a message to the output log prefixed with the action name and line number,
        lr_output_message("an output message");

        An example:

          Actions.c (4): an output message

      • // send a message to both the the Output window and the Vuser log:
        lr_message("*** a message"
          +"\r"+"A new line."
            );

          Idea Arranging the ");" in an additional line makes it easier to add or remove items in the command.
          Idea The "\n" escape characteranother page on this site adds a line break on UNIX/Linux machines.
          Idea The "\r" escape characteranother page on this site adds a line break on Windows machines.

      • // send a message to the output log without the action name and line number:
        lr_log_message("number\t"+ numvar +"\t");

          Idea The "\t" TAB escape characteranother page on this site around a number separates it into different columns for import into Excel or for double-click selection in Notepad.

      • // send a message only to the Controller Vuser status area (which appears only briefly when run in VuGen):
        lr_vuser_status_message("a vuser status message");

      • // send a highlighted red message -17999 to the LoadRunner Controller or Tuning Module Console's Output window:
        lr_error_message("an error message");

          Idea Issuing an lr_error_message causes the display of the log message stack automatically cleared at the beginning of each new action. If "Send messages only when an error occurs" is selected, messages are still being created in the "log message stack", but suppressed (not displayed) until an error is detected.

          The size of the buffer holding log output in case of an error is set in ...


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Log Message Display

      Reminder vuGen 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.

        Caution! Enabling more verbose "Extended Logs" may fill up hard drives and thus disrupt long-running jobs.

      When a run starts with the Message Level set to Send messages only when an error occurs, this reminder message appears in the output:

        Log messages will be sent only when an error occurs.
        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 thisanother page on this site at the top of the log.

        If you don't start the run with those settings, LoadRunner does not provide a programmatic function to print this information later in the script.

      Idea If you want trace information at the beginning of your run logs, but don't want all the other Advanced Trace information, start the run with those Runtime Settings, then programmatically turn logging off by using VuGen script functions (described below) to mimic the selection of radio buttons and check boxes.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Programming Log Verbosity

      Idea To 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.

      Runtime Settings GUI First parameter: lrun.h constants Second parameter
      Enable logging - 0 or LR_MSG_CLASS_DISABLE_LOG
      A. Send messages only when an error occurs 512 or LR_MSG_CLASS_JIT_LOG_ON_ERROR 1 or LR_SWITCH_ON
      B. Always send messages 0 or LR_SWITCH_OFF
          a. Standard log   1 or LR_MSG_CLASS_BRIEF_LOG 1 or LR_MSG_ON
          b. Extended log 16 or LR_MSG_CLASS_EXTENDED_LOG
              Parameter substitution   4 or LR_MSG_CLASS_PARAMETERS
              Data returned by server   2 or LR_MSG_CLASS_RESULT_DATA
              Advanced traceanother page on this site   8 or LR_MSG_CLASS_FULL_TRACE
      Words in ALL CAPS are named constants defined in header file lrun.h.

      LR_SWITCH_OFF is a constant for value zero. LR_SWITCH_ON is value 1.

      Reminder "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:

        lr_set_debug_message( LR_MSG_CLASS_EXTENDED_LOG | LR_MSG_CLASS_RESULT_DATA | LR_MSG_CLASS_PARAMETERS | LR_MSG_CLASS_FULL_TRACE, LR_MSG_ON );

        Reminder 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.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Messsage Text

      Standard log text includes:

        Virtual User Script started
        Starting action vuser_init.
        Web Turbo Replay of LoadRunner 8.1.0 for WIN2003; Web build 4862 [MsgId: MMSG-27143]
        Run-Time Settings file: "...\\default.cfg" [MsgId: MMSG-27141]
        Registering web_reg_save_param was successful [MsgId: MMSG-26390]
        web_get_int_property was successful [MsgId: MMSG-26392]
        ...
        Vuser Terminated.

      Extended log text also includes:

        web_set_max_html_param_len was successful [MsgId: MMSG-26392]
        Ending action vuser_init.
        Running Vuser...
        Starting iteration 1.
        Starting action Action_loop.

        Ending action Action_loop.
        Ending iteration 1.
        Ending Vuser...
        Starting action vuser_end.
        Ending action vuser_end.
        Vuser Terminated.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen C Programming Message Display

      Idea This C code programmatically gets the value of "message level" and saves it in a global parameter:

      char *itoa ( int value, char *str, int radix );
      vuser_init(){ 
      	int iMsg_level_in; 
      	int iMsg_level_prt = 26; // Sets.
      	char buffer[10]; 
      	iMsg_level_in=lr_get_debug_message();
      	// Save LR's current message level number into a parameter:
      	lr_save_string( itoa( iMsg_level_in, buffer, 10) , "pMsg_level" ); 
      	lr_message ( "*** msg_level is %s upon entry.", 
      		lr_eval_string("{pMsg_level}")); 
      	if (iMsg_level & LR_MSG_CLASS_BRIEF_LOG) 
      		lr_output_message("Current message level %d 
      			is Standard Log.", iMsg_level); 
      	if ((iMsg_level & LR_MSG_CLASS_RESULT_DATA) 
      		&& (iMsg_level & LR_MSG_CLASS_PARAMETERS)) 
      		lr_output_message("Current message level %d 
      			is Parameters and Result data.", iMsg_level); 
      


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Java Programming Message Display

      For Java:

      	int iMsg_level_in; 
      	int iMsg_level_prt = lr.MSG_CLASS_EXTENDED_LOG |
      		lr.MSG_CLASS_FULL_TRACE; 
      
      	// Get Run-time Settings Log setting:
      	iMsg_level_in = lr.get_debug_message(); 
      
      	// Print Runtime Settings log message level no matter what:
      	lr.set_debug_message( 530, lr.SWITCH_OFF); 
      	lr.set_debug_message( iMsg_level_prt, lr.SWITCH_ON); 
      
      		lr.output_message("*** Runtime Settings Log message level is set to "
      		+ lr.eval_string("")
      		+ Integer.toString(iMsg_level_in)); // Integer to string conversion!
      
      		// Check if message level is "Data Returned by Server" and "Parameter Substitution" 
      		if( iMsg_level_in == dataAndParams) 
      		lr.message("Current message level is result data and parameters."); 
      		// Check for no extended logging:
      		if( iMsg_level_in == lr.MSG_CLASS_BRIEF_LOG) 
      		lr.message("Current message level is Standard Log."); 
      
      	lr.set_debug_message( 530, lr.SWITCH_OFF); 
      	lr.set_debug_message( iMsg_level_in, lr.SWITCH_ON); 
      
      

        Reminder The & operator within the if statements above is a logical AND working on individual bits within the number.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Script Actions

      The source code within each step LR automatically puts into a separate .c file in the script folder.
      Each action also appears as a separate item (line) on the icon tree.

      Caution! Do not delete script sections. To avoid confusing the Controller, delete scripts you don't use from the Runtime Settings Run Logic section, then create new actions. However, actions not appearing in Run Logic are not available to the Controller.

      Conversely, parameters in actions deleted in the Controller still increment. This may result in this error message: -84800 "insufficient records for param '...' in table to provide the Vuser with unique data"

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Web User Actions

      In VuGen, the default mode of script generation is HTML-based — "a script describing user actions" that correspond directly to user actions:

      • web_url for a URL in the Address field on the internet browser.
      • web_link for clicking a text link between <a href= ...> and <a>
      • web_image for clicking an HTML <img href= link.
      • web_submit_form for pressing "submit" of a GET or PUT form obtained in the context of a previous operation — perhaps recorded by VuGen in HTML-based recording mode.
      • web_submit_data for pressing "submit" of a GET or PUT form without the context of a previous operation — perhaps recorded by VuGen in URL-based recording mode or in HTML-based recording mode with the "A script containing explicit URLs only" option checked.

      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.

      Idea 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.

      Idea 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.

       

    Reminder 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.

     
    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Extra Recorded Script Actions

      When recording a script, these lines are captured when the browser does not have the SSL root certificate installed. The message is "This certificate cannot be verified up to a trusted certification authority."

      web_url("authrootseq.txt",
        "URL=http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootseq.txt",
        "Resource=1",
        "RecContentType=text/plain",
        "Referer=",
        LAST);
      web_url("authrootstl.cab",
        "URL=http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab",
        "Resource=1",
        "RecContentType=application/octet-stream",
        "Referer=",
        LAST);

      When recording a script, these lines are captured when the browser encounters a Macromedia flash component on a webpage:

      web_url("version_en_win_ax.xml",
        "URL=http://fpdownload.macromedia.com/pub/flashplayer/update/current/xml/version_en_win_ax.xml",
        "Resource=0",
        "RecContentType=text/html",
        "Referer=",
        "Snapshot=t8.inf",
        "Mode=HTML",
        LAST);

      If you have the Google Toolbar installed, it sends out requests even though you're not asking for Google.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Scripting Language Rules

      With LoadRunner, capitalization matters, even in the values being examined. So the script above will not recognize the value "Welcome" flowing through because of capitalization. So, Steve Cheney suggests using the "ic" "ignore case" text flag:

      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 characteranother page on this site representation for a single backslash within quotes. If only one backslash is used by mistake, LR will think it is a null terminator.

      Mercury KnowledgeBase article This sample script to support UTF-16 encodinganother page on this site 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):

      1. param_value - The value to assign to a parameter.
      2. value_len - The length of the value in bytes.
      3. options - A parameter option, currently 0.
      4. param_name - The name of the parameter.

      LoadRunner 7.8 does not support regular expressionsanother page on this site, but has its own (limited) wildcard functionality:

        To allow for any number [0-9] within specific digit positions, use /DIG with a pound sign:

        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 Ignore Case and allow any character in a specific character position:

          web_reg_find("Text/ALNUMIC=^ercury", LAST);

        • To allow any Lower Case character [a-z] in a specific character position:

          web_reg_find("Text/ALNUMLC=^ercury", LAST);

        • To allow any Upper Case character [A-Z] in a specific character position:

          web_reg_find("Text/ALNUMUC=^ercury", LAST);

      To convert a string to upper case:

        strupr()


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Error Messages

      Please add other error messages to this list to help others.

      Could not resolve address of host ... [MsgId: MERR-27798]

      appears from a "404" DNS error if the network is not available or if the domain has not been registered.

      Contents unexpectedly not in cache. [MsgId: MERR-26549]

      This appears when a file is empty. Putting a space character in the blank file satisfied LoadRunner's error checking. BTW, an empty file was specified because IE issues its own error when an iframe is created without a file.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Transaction Timing Scripting

      Idea I prefer to name transactions by the action rather than the resulting page.

        lr_start_transaction("00.1 Invoke URL");
        ...
        lr_end_transaction("00.1 Invoke URL",LR_AUTO);
        ...
        lr_start_transaction("01.2 Top menu");
        ...
        lr_end_transaction("01.2 Top menu",LR_AUTO);

        lr_start_transaction("02.0 Updating");

          lr_start_sub_transaction("02.1 Update menu","02.0 Updating");
          web_url( ...
          lr_end_sub_transaction("02.1 Update menu",LR_AUTO);
          lr_start_sub_transaction("02.2 Update submit","02.0 Updating");
          web_submit_form( ...
          lr_end_sub_transaction("02.2 Update submit",LR_AUTO);
          lr_start_sub_transaction("02.3 Update OK","02.0 Updating");
          web_url( ...
          lr_end_sub_transaction("02.3 Update OK",LR_AUTO);


        lr_end_transaction("02.0 Updating",LR_AUTO);

      Idea I prefer to zero-fill transaction names in a hierarchy to ensure the Controller sorts the sequence correctly.

      Idea I suffix transaction names with key words to differentiate different types of user actions:

      • Contact Link = Click "Contact" link on Menu
      • Contact Icon = Click "Contact" Icon
      • Regis. Sub = Page Submit
      • OK = Pop-up dismiss with OK

      Transaction names can be variables, but unless they are compiled by VuGen as strings, they will not show up in the Controller interface. However, they will appear in analysis results files.

      LR automatically creates and determines the duration of transactions instances for web scripts, but C-Language scripts can use these functions:

      Use lr_start_transaction_instance function to explictly obtain the handle (a long data type) for a specific instance of a transaction name used in functions lr_user_data_point_instance or lr_user_data_point_instance_ex.

      Use the lr_start_sub_transaction function to manipulate think times and wasted times within a transaction.

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Error Prevention and Recovery

      Parameters are delimited by default with { and } curly braces, but < and > can be specified in ....

      LoadRunner substitutes #_UNREADABLE_# for characters it cannot read in a field. But the script will still replay fine because LoadRunner stores the actual contents of fields in .dat files within the directory for each Vuser.

      NTLM or Digest User Login Authentication

      web_set_user("X\\Y", "Z", "A.com:80");

        This logs user Y into domain X using password Z onto host A.com port 80. This is automatically inserted during VuGen recording only in response to Windows Basic authentication. When the web server demands the more secure NTLM or Digest authentication, manually insert this into the script. With NTML authentication, the user name must be preceded with a domain name and separated with a backslash.

      Reminder As with any use of slash within quotes, use double backslash or you'll see this message:

        warning: unrecognized character escape sequence

      A Unique IP address For Each Vuser

      [WB 12-x] If the hardware configuration under test balances load across a "farm" of several (web or database) servers, you can spoof (trick) how routers distribute work among those servers so that each Vuser uses a unique IP address instead of the same IP Address for its host machine. So, to use this "IP Spoofing" to emulate a more realistic pattern of IP addresses:
      1. On each Vuser host machine, use the IP Wizard "New Setting" dialog to enter the IP address of the web server and the IP addresses to assign Vusers in their stead. Individual addresses or -- in a closed network -- a range of addresses (from any IP class) can be specified.
      2. Reboot to refresh the server's Routing Table (done at startup).
      3. On the Controller's "Scenario" menu, select "Enable IP Spoofer".

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Verification Checkpoints

      The most common script to be manually added after recording of action steps is script to properly handle response delays -- ensure the visual cues of expected actions indeed occured (a confirming text or graphic appearing in response to an action). Such checks can use regular expressionsanother page on this site.

      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.

    • The most used verification function is web_reg_find. This registers a search for a text string for the very next Action function in the script, such as web_url. It scans the buffers as they arrive rather than after a page is received — a more efficient script with better performance than web_find.

      To determine perform actions based on the number of occurences:

      web_reg_find("Text=ABC", "SaveCount=abc_count", LAST);
      web_url("Step", "URL=...", LAST);
      if (strcmp(lr_eval_string("{abc_count}"), "0") == 0)
        lr_output_message("not found");
      else
        lr_output_message("{abc_count} found");

      Do this instead of the web_create_html_param_ex function deprecated since LR 6.5. It saves recurring dynamic information on an HTML page to a parameter.

    • If you want to save and display text found, use the web_reg_save_param command to extract text after finding text between tokens LB and RB (Left and Right Beacons) non-NULL terminated dynamic data from an HTML page to a parameter.

      char *str1,*str2;
      str1="desired text";
      // Register the left and right beacons sought:
      web_reg_save_param("param","LB/ic=xxx","RB=xxx");
      // Do the monitored deed:
      web_url("some url","URL=www.xxx.com",LAST);
      // Compare:
      str2=lr_eval_string("{param}");
      if(strcmp(str1,str2)==0) {
        lr_output_message("param found");
      }else{
        lr_output_message("Value found is %s",str2);
      }

      Do this instead of the web_create_html_param_ex function deprecated since LR 6.5. It saves recurring dynamic information on an HTML page to a parameter.

    • Within HTML-based scripts (not URL-based scripts), use web_image_check to verify the presence of a specified image inside an HTML page. Remember that this only works if Runtime Settings > Internet Protocol Preferences has "Enable Image and text check" checked.

    • Use web_global_verification to search for a text string in all subsequent requests.

    • Use web_reg_add_cookie to register a search for a text string and adds a cookie if the text is found.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Data Type Conversion

      Loadrunner scripters who not experienced in C programming will likely find techniques to convert between data types the most difficult aspect of Vu Scripting. Let me know if this clears things up for you.

    1. Output variables are in different positions for similar functions.

        The variable holding the output from an atoi (array to int) function call is the result from the function, like many other c functions:

          intResult=atoi( charY );

          This is a very cool feature of the C language to allow for nesting of functions.

        However, the reverse itoa (int to array) function's output is the second of three arguments:

          itoa( intX, charY, 10);

        • The first argument is the integer number to be converted from.
        • The second argument is where the output character array is going to be stored. Note that this must have been defined as a fixed array

            char charY[20];

          Maximum is 32064 (32K) or you'll get "too many variables" compile error.

          Your program will crash if the variable was defined with a variable length, as in:

            char *charY;

        • The last argument is NOT the size of the array, but the BASE of the number. Base 10 is the one you're most likely to use. Base 2 is binary, 8 is octal, 16 is hexadecimal.

    2. There are several functions to accomplish the same thing.

        Function itoa is not a standard ANSI C function but a part of the C stdlib.h. So Mercury (as explained in 11291) did not include them in the LibC that LoadRunner uses on UNIX machines. So use the standard function sprintf instead:

          sprintf( charY, "%d", intX );

    3. To convert a hex string (such as "FFFF"), use %X:

        int intNum;
        sscanf("ffff", "%X", &Num);
        lr_output_message("%d", intNum); // Print 65535, the integer value for ffff 
        

      Alternately, use the lrs_hex_string_to_int function to convert a hexadecimal string into an integer by specifying a pointer to a buffer containing the string you want to convert and the length of the string to convert. This function translates the string and assigns the value to the integer reference.

    4. The rules for extracting numbers from text.

      • If the first character isn't a number or a minus sign or if the string is empty, atoi returns 0. This means that "e24" is will return 0 (zero).
      • When atoi encounters a non-number character, it returns the number formed up until that point. This means that "-3.2" returns as -3.0. "123XXX345" returns as 123.

    5. LoadRunner vuScript parameters must be converted into C strings. There are two ways to turn a LoadRunner parameter into a C number:

      i = atoi( lr_eval_string("{pX}") );
      or
      sprintf( intX, "%d", lr_eval_string("{pX}") );

      Arithmetic with Parameters is convoluted

      Reminder LoadRunner does not provide funtions for doing math on parameters. So LoadRunner parameters must be 1) evaluated into a C integer for 2) C functions to manipulate it and return the result as a C string, then 3) saved again into a parameter so that the value can be passed to another script function.

      	char cBuf[10]; 
      	int i; 
      
      	// 1. Evaluate parameter into a C integer:
      	i = atoi( lr_eval_string("{pNum_in}") );
      
      	// 2. Do the math and output the result to a C string:
      	sprintf( cBuf, "%d", i+1); 
      
      	// 3. Save the string as a parameter to be passed on:
      	lr_save_string( cBuf, "pNum_out"); 
      
      	//Print out the parameter value after incrementing it.
      	lr_message("**** Parameter from %s to %s",
      		lr_eval_string("{pNum_in}")); 
      		lr_eval_string("{pNum_out}")); 
      

    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Manipulating Strings

      In the C language, strings are fixed in length because they are really a character array of individual characters. Such an array is read-only. Calls which change the length of a string would result in an error message such as:

      Error: "C interpreter runtime error - memory violation error during replay.

      However, string functions in the as_web.h library can be forced into read/write memory by "prototyping" declarations such as:

        char *strtok(char *, char *); // tokenizer prototype
        char *strstr(char *, char *); // substring prototype
        char *strdup(char *); // String duplication prototype
        float atof(); // alpha to return float datatype
        

        #include "as_web.h"
        char *strtok(char *, char *); // prototype function call.
        
        ActionX()
        {
        	char aBuffer[256]; // input string to be parsed.
          	char *cToken; // individual token from strtok.
        	char cSeparator[] = " "; // blank separator.
        	int i; // incrementer
        	char val[3][20]; // output array of strings.
        	char modified_val[20]; 
            
        	// Create a parameter named pDate:
        	lr_save_string("January 2, 2001", "pDate");
        
        	// Put parameter into a string buffer:
        	strcpy( aBuffer,lr_eval_string("{pDate}"));
        
        	// Show the buffer for debugging:
        	lr_output_message("%s\n",aBuffer);
        
        	// get first word (to the first blank):
         	cToken = strtok( aBuffer,cSeparator); 
        	i = 1;
        
        	if(!token) { // first token was not found:
        		lr_output_message("No tokens found in string!");
        		return( -1 );
        	} else {
        		while( cToken != NULL) { // tokens are not NULL:
         			lr_output_message("Token=%s", cToken);
        
        			// Stuff in another array:
        			strcpy( val[i], cToken ); 
        
        			// Get next token:
        			cToken = strtok( NULL, cSeparator); 
        			i++; // increment 
        		}
        		lr_output_message("Val #1 is: %s", val[1]);
        		lr_output_message("Val #2 is: %s", val[2]);
        		lr_output_message("Val #2 is: %s", val[3]);
        
        		strncpy( modified_val, val[2], 1 );
        		modified_val[2] = '\0';
        		while (modified_val[2] != NULL) {
        			lr_output_message("===>%s", modified_val);
        			modified_val[2] = strtok(NULL, " ");
        		}
        	}
        	return 0;
        }

      • strcat Concatenates two strings.
      • strchr Returns the pointer to the first occurrence of a character in a string.
      • strcmp Compares two strings to determine the alphabetic order.
      • strcpy Copies one string to another.
      • strdup Duplicates a string.
      • stricmp Performs a case-insensitive comparison of two strings.
      • strlen Returns the length of a string.
      • strlwr Converts a string to lower case.
      • strncat Concatenates n characters from one string to another.
      • strncmp Compares the first n characters of two strings.
      • strncpy Copies the first n characters of one string to another.
      • strnicmp Performs a case-insensitive comparison of n strings.
      • strrchr Finds the last occurrence of a character in a string.
      • strset Fills a string with a specific character.
      • strspn Returns the length of the leading characters in a string that are contained in a specified string.
      • strstr Returns the first occurrence of one string in another.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Capturing Data From Streams

      Various web applications have different techniques for maintaining and restoring the state of data values referenced by controls. These values would otherwise be lost, either because those values do not post with the form or because they are not in the page html. This usually involve the web application dynamically generating a unique value. LoadRunner scripts emulating such browser sessions need to capture these dynamically created values and use them in its emulating script.

      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 );

        Captures an entire HTML page by registering text between the two case-sensitive boundary "HTML" tokens. This is used instead of the web_create_html_param function deprecated since LR 6.5. It is no longer necessary to specify web_set_max_html_param_len("10000"); to set buffer size to make room for the HTML of an entire page.

      Caution! lr_output_message stops display as soon as it encounters a null (binary "\\x00") character.
      But log displays of parameters will display binary because it displays each character in binary view.

      To look for binary data, use the text flag "/BIN". For example, to look for "Adams":

        web_reg_find("Text/BIN=\\x00A\\x00d\\x00a\\x00m\\x00s",LAST);

        Note the two backslashes. If only one backslash is used by mistake, LR will think it is null terminator.

      Reminder 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

        HttpRetCode = web_get_int_property(HTTP_INFO_RETURN_CODE)

      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 charactersanother page on this site for return/next line.

        web_reg_save_param ("pRedirect2URL", "LB/ic=Location: ","RB=\r\n" ,LAST );
      This attribute is optional.
      However, to capture all instances of redirection, add the "ORD=ALL" attribute:
        web_reg_save_param("pRedirect2URL","LB/ic=HTTP/1.1 ", "RB= ", "Search=Headers" ,"ORD=ALL", LAST);

      • LoadRunner automatically creates one parameter per instance, named pRedirect2URL_1, pRedirect2URL_2, etc.
      • LoadRunner also automatically creates an count parameter containing the number of instances that are actually captured. For example, if the parameter name is pRedirect2URL, LoadRunner creates a separate parameter named pRedirect2URL_count containing the count of instances found.

      If you are capturing a URL address with % coding, convert it back to single special charactersby adding "convert=HTML_TO_TEXT".
      If you are capturing text that will be used as a URL address, convert special characters to % coding by adding "convert=HTML_TO_URL".

      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".

      Reminder The lr_eval_string function must be used for parameters accessed from within another function.

      Set screen Scripting for Microsoft ASP.NET VIEWSTATE

      Mercury KnowledgeBase article Based 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 \Patches\Trap_for_.net_patch folder to \bin directory for recording against Windows XP.

      Windows ASP.NET web applications maintain state data by passing across Pagebacks a hidden _VIEWSTATE field encoded in base64.

      1. set the maximum number of characters in the VIEWSTATE buffer

          web_set_max_html_param_len("16262");

          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.

      2. register with the process the need to save in a parameter the VIEWSTATE value when it is returned from the client.

          web_reg_save_param("MyViewState","LB=\"__VIEWSTATE\" value=\"","RB=\"","ORD=ALL",LAST);

      3. Substitute the captured value with the parameter name:

          "Name=__VIEWSTATE", "value={MyViewState}", ENDITEM,

      4. After running (with logging set to Advanced) in VuGen, verify its processing by looking in the output.txt log for messages that contains "saving parameter".

      Set screen SOAP, XML, and Web Services

       

      Microsoft, UserLand, and DevelopMentor created SOAP (Simple Object Access Protocol) from 1998 to the SOAP 1.1 W3C note 8, May 2000.

      "XML-based information which can be used for exchanging structured and typed information between peers in a decentralized, distributed environment." is the definition of SOAP V1.2 which reached W3C Recommendation 24 June 2003.

       

      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.
      For my customers I have a web page that scans a WSDL and creates LoadRunner web_custom_request function calls with 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

      Set screen Tracing COM/COM calls

      COM/DCOM scripts can't use web_save_param.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Parametizing Values

      Data values used in LoadRunner scripts can be parametized so that each script execution can use a different data value. A parameter replaces a literal value in the script. This is useful to obtain realistic results from caching or to generate requests which are dependent on the results from a prior action. Examples of this are dates, order numbers, etc.

      The source of the parameter's eventual value and other properties can be from a file or from a randomly generated seed. LR can obtain values from a parameter file on a sequential, random, or unique basis. A sequentially value can be pulled for "Each Iteration" through the script or each occurance within an iteration.

      [WB 9] VuGen monitors and stores HTTP data (such as ACTION or METHOD values) from the server into its Record Proxy cache. This allows the web_submit_form command to automatically obtain data from the context of the previous form. This is why the command is called context sensitive.

      Analog statements contain all data necessary for a complete FORM request. web_submit_data is recorded when there is a hidden field which the browser provides.

      However, you may not want VuGen to automatically create in context sensitive mode whenever it finds matching data because they take more overhead (CPU cycles) -- allowing less VUsers to be processed in the same amount of time -- and also when you want to specify hidden data fields.

      Data Files

      Idea Create new data files in a folder in a hierarchy above the current script rather than the default location
      -- the current script folder. This makes the data file accessible to later versions of the same script.

      Loadrunner assumes text data file names end with a .dat extension.
      To see files with .csv or other common file suffix, select "All files" in the pop-up.

      Although LR has no limits on the number of entries or size of a parameter file,

        Caution! Before LR runs a script, it loads all values in all parameter files into memory, so large parameter files defined for a script will take time to load before starting work.

        Caution! Although the Microsoft Windows OS has a maximum file size of 2GB, LoadRunner has been hard-coded to display only the first 99 rows of parameter data file values to be used by Vusers.

        Caution! Carriage returns are important. Blank lines will be used as a blank value. The cursor should rest under the last item. An error would result if the last item in the data file does not end with a carriage return.

     

      KB 19703


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Loopers

      If you set (in Tools > Recording Options) HTML Advanced setting of "A script containing explicit URLs only", your recording will generate web_submit_data() functions.

      With HTML GET requests, notice that ITEMDATA ... ENDITEM in the generated script

        "Action=http://www.google.com/search", 
        	...
        	ITEMDATA, 
        	"Name=hl", "Value=en", ENDITEM, 
        	"Name=q", "Value=loadrunner", ENDITEM, 
        	"Name=btnG", "Value=Google Search", ENDITEM, 
        
      in the Replay Log, Request header turn into fields added to the host name:

        GET http://www.google.com/search?hl=en&q=loadrunner&btnG=Google+Search? HTTP/1.1\r\n
        

      This means you can comment out the ITEMDATA ... ENDITEM lines and hard-code the URL parms with a & separating each name and a + replacing spaces:

        "Action=http://www.google.com/search?hl=en&q=loadrunner&btnG=Google+Search", 
        

      Use this technique to vary the number of URL parms with one LR parameter:

        "Action=http://www.google.com/search?{pURLparms}", 
        


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Randomizers

      LR 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:

        srand( time(NULL) );

        Caution! 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:

        1. Define a new parameter "ptIteration" as the "Iteration" and use it to:

             srand(time(NULL)+atoi(lr_eval_string("{ptIteration}"))); 

        2. Change the time structureon this page

      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 download from Mercury that determines the range of the randome number from a count:

        web_reg_save_param("search_param", "LB=<p><A HREF=", "RB=>", "ORD=All");
        ... 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:

        sprintf(my_new_parameter, "{search_param_%d}", rand_selection);


    Go to Top of this page.
    Previous topic this page
    Next topic this page

      Set screen Date/Time Manipulation

      Date 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:

      1. Insert a parameter using the VuGen GUI, under Vuser, Parameter List..., select New, Parameter type: Date/time

      2. Hard coding commands into the Vu script allows more flexibility, such as 7 days from today, after adding #Include "time.h" above the action name so you can reference literals DATE_NOW and ONE_DAY:

          lr_save_datetime("%m/%d/%Y", DATE_NOW + (ONE_DAY * 7), "pNextWeek_date");
          lr_output_message("%s", lr_eval_string("{pNextWeek_date}"));

        Put this code where the application determines its date. This may be at the beginning of the session or close to the code which uses the date value.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Fault Tolerance in Retry Logic

      The sample code uses several fault tolerance techniques:

      1. put requests within a loop so that they can be resubmitted if "Page downloads timeout" is received;

      2. Tell LoadRunner to continue execution despite errors:

         lr_continue_on_error(1);
        or, using defined constant:

         lr_continue_on_error( LRD_DB_ERROR_SEVERITY_WARNING );
      3. use web_reg_find to determine whether what is returned is as expected.

      4. code loadrunner function calls so that you can examine their return codes.
        Reminder
        web_reg_find returns 1 (constant LR_FAIL) if it failed.
        web_reg_find returns 0 (constant LR_PASS) if it was successful.

        lrc_save COM/DCOM functions return 0 for success, -1 for error (Microsoft rules).

        HRESULT is returned by functions that create an object or get an interface or cause execution of certain other standard COM calls. It is the HRESULT value returned by the corresponding COM functions as documented by Microsoft. It is not used in VuGen scripts. Instead, VuGen checks the result and enters a CHECK_HRES or DONT_CHECK_HRES flag according to whether or not the call succeeded when the script was recorded.

        Reminder To determine whether calls to Microsoft COM/DCOM functions succeeded, VuGen uses CHECK_HRES or DONT_CHECK_HRES flag rather than HRESULT.

      5. output different messages depending on the result.

      6. Tell LoadRunner to terminate upon error:

         lr_continue_on_error(0);
        or, using defined constant:

         lr_continue_on_error( LRD_DB_ERROR_SEVERITY_ERROR );

      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);
         } 
      } 
      

    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen If/Else Logic

      Idea I have found it helpful to be consistent in using != (not equal) versus == (equals). so that the exception condition is always first, then the normal condition after the else.

      if (lr_get_transaction_status() == LR_FAIL 
      ||  lr_get_trans_instance_status(parent_trans_handle) ) {
           // This needs to be done before lr_end_transaction.
      
           // web_url has failed the transaction. 
           // No point in continuing because future calls will probably fail too.
      
           lr_end_transaction("Flight", LR_FAIL);
           return;
      } else {
         
      }

      Scripts executed from within VuGen only once, for no group (group ID "None").
      Scripts executed from within the Controller will always have a group ID.
      This fact can be used within scripts to control whether certain code is executed by just the Controller or just the VuGen.

      if( !strcmp( "None", lr_eval_string( "{Group_Name_Param}" ))){
      	// ... code to be executed only by VuGen ...
      }
      To determine whether a result parameter contains a value, use the strcmp function to count the number of characters in the parameter:

        if( strcmp( lr_eval_string("{p}"), "") != 0){
            // Value is not null -- it has been populated!
        }
        else{
            // Value is null -- has zero characters!
        }
        


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Run Indentification - VuGen vs. Controller

      LoadRunner internal variables can be obtained in a script by inserting a parameter of the types shown in this screen:

      Vuser and group identifiers can also be obtained using LR functions.

      	int iVuser;
      	char * vuser_group;
      	// ...
      	lr_whoami(&iVuser, &vuser_group, NULL);
      	sprintf (msg, "**** vGroup: %s Vuser: %d", vuser_group, iVuser);
      	lr_output_message("**** %s", msg);
      	
      The variable vuser_group is a character string, so it's represented by %s.
      The variable vuser is an integer (int), so it's represented by %d.

      When this script is run within VuGen, the vuserID would contain a NULL value (-1) because VuGen always runs only a single user. Similarly, the Scenario is zero and the Group is "None" since they are not applicable to VuGen.

      When this script is run within the Controller, the VuGen, Group, and Scenario variables would be populated since multiple values are possible.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Exit Return -1

      The exit option describes the manner in which to exit: the Script Error Continuation constants:
      Value Constant Explanation
      0 LR_EXIT_VUSER Exit without any condition, and go directly to end action.
      1 LR_EXIT_ACTION_AND_CONTINUE Stop current action, and go to the next action.
      2 LR_EXIT_ITERATION_AND_CONTINUE Stop current iteration, and go to the next iteration.
      3 LR_EXIT_VUSER_AFTER_ITERATION Run until the end of the current iteration and then exit.
      4 LR_EXIT_VUSER_AFTER_ACTION Run until the end of the current action and then exit.

      The Error Continuation constants:
      Object Oriented Value Constant Explanation
      0 LR_ON_ERROR_NO_OPTIONS Exit without any condition, and go directly to end action.
      1 LR_ON_ERROR_CONTINUE Stop current action, and go to the next action.
      2 LR_ON_ERROR_SKIP_TO_NEXT_ACTION Stop current iteration, and go to the next iteration.
      3 LR_ON_ERROR_SKIP_TO_NEXT_ITERATION Run until the end of the current iteration and then exit.
      4 LR_ON_ERROR_END_VUSER Run until the end of the current action and then exit.
      5 LR_ON_ERROR_CALL_USER_DEFINED_HANDLER -

      The exit_status attribute of the exit command:
      Value Macro Explanation
      0 LR_PASS -
      1 LR_FAIL -
      2 LR_AUTO Abort by default.
      3 LR_STOP -


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Error Diagnosis and Recovery

      According to KB 31445, to prevent Error: "SSL State: error in SSLv3 write client certificate B"
      load into the script folder a PEM formatted list of Certificate Authoritiesanother page on this site:

        web_set_certificate_ex( "CertFilePath=certFile.pem", "CertFormat=PEM", ...LAST);

        web_set_sockets_option("LOAD_VERIFY_FILE", "certFile.pem");


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Logic Using Files

      To open files, LoadRunner does not get the pointer to the structure of FILE as many C programers would expect. Instead, LoadRunner uses:
        int fp;
        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"); 
      


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen File Output Based on Environment Variables

      This script gets a file path from Windows environment variable TEMP and writes a file to it:

       
      	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).


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Multiple Parameter Values

      Vugen provides 3 ways to change the value of a parameter by iteration:
      1. Sequential
      2. Random
      3. Unique

      However, you can take control of the access method using a custom function, lr_next_row from download 1688-lr_next_row.zip

      but you'll also need to keep track of the current line of the parameter value accessed.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen External Function Libraries

      Mercury KnowledgeBase article External OS functions can be called from a VuGen script.

      The Windows operating system kernel interprets OS level commands:

        lr_load_dll("c://kernel32.dll");

      More information on this in the "Creating Virtual User Scripts" User's Guide, under the Appendixes section for 'Calling External Functions'

      Calls to C libraries

      One 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.

      Set screen Open SSL Certificate info

      This script Download from Mercury 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:

        Server Certificate Information:
           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

     

    tool The CWebPage COM class by Eugene Khodakovsky includes a demo to call Javascript as COM objects.

    tool CliPP library on SourceForge uses the Boost library and a Javascript Parser written using the Spirit library to expose C++ classes and functions to Javascript.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Software Correlation

      After two scripts are recorded following identical user actions, use wdiff.exe to compare the two scripts to identify the differences in what was captured. Such dynamic differences include:

      • Session identifiers in URLs generated by middleware (such as BroadVision's BV_engine_id= parameter).
      • Values in HTML
      • Values in persistent client cookies
      • Differences in Think Time, which should be ignored.

      If web_add_cookie commands are commented out, the application would send a new cookie during playback.

     


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen XML/SOAP

      Add code to capture the XML reponse, then use lr_xml_get_values to extract values into a parameter.

      	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, Idea 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:
      • lr_xml_set_values Sets the values of XML elements found by a query
      • lr_xml_extract Extracts XML string fragments from an XML string
      • lr_xml_delete Deletes fragments from an XML string
      • lr_xml_replace Replaces fragments of an XML string
      • lr_xml_insert Inserts a new XML fragment into an XML string
      • lr_xml_transform Applies Extensible Stylesheet Language (XSL) Transformation to XML data


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Output Logging

      web_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.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Timing Time-outs

      One 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.

      Idea 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:

        Protocol Runtime Setting Default
        Value
        Max.
        Value
        Script override function
        For Web Scripts: DNS caching Yes -  
        Keep-alive HTTP connections Yes - web_disable_keep_alive ();
        web_enable_keep_alive ();
        HTTP-request connect timeout (sec) 120 1000 web_set_timeout( CONNECT, "120");
        HTTP-request receive timeout (sec) 120 1000 web_set_timeout( RECEIVE, "180");
        Step download timeout (sec) 120 32000 web_set_timeout( STEP, "240");
        For Winsocket: -     lrs_set_recv_timeout

      To customize the ThinkTime parameter, use the lr_get_attribute_long or _double function to pull in the command line parameter into a script.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Remove Wasted Time

      Time not directly related to the application under test, such as time spent on testing activities include transaction tracking data entry, logging, or analysis of test run statistics. Loadrunner considers such activities "wasted" time because they are not counted among transaction statistics in the VuGen log file, output.txt, or Vuser log files.

      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:

        lrapi.dll in C:\Program Files\Mercury Interactive\Mercury LoadRunner\bin
        lr.class in C:\Program Files\Mercury Interactive\Mercury LoadRunner\classes\lrapi

      Time can be obained with these functions:

      • lr_get_transaction_status Gets the current status of a transaction.
      • lr_get_transaction_duration Gets the duration of a transaction by its name.
      • lr_get_transaction_think_time Gets the think time of a transaction by its name.
      • lr_get_transaction_wasted_time Gets the wasted time of a transaction by its name.

      • lr_get_trans_instance_status Returns the current status of a transaction instance.
      • lr_get_trans_instance_duration Returns the duration of a transaction instance specified by its handle.
      • lr_get_trans_instance_think_time Gets the think time of a transaction instance specified by its handle.
      • lr_get_trans_instnce_wasted_time Gets the wasted time of a transaction instance by its handle.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Rendezvous Points

      Rendezvous Points are specified to ensure that all specified vusers begin a transaction at precisely the same time.

      The Controller automatically enables its screen captured 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 screen captured Rendezvous Information dialog box.

      Reminder Rendeveous commands are not recognized in Vuser_init and Vuser_end sections.

      The Controller releases Vusers based on the screen captured Policy dialog shown when the "Policy..." button is clicked.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Timings

      Here 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.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Set screen Cleaning Up Files

      When 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.


    Go to Top of this page.
    Previous topic this page
    Next topic this page

    Portions ©Copyright 1996-2011 Wilson Mar. All rights reserved. | Privacy Policy |

    Related Topics:
    another page on this site Performance Testing 
    another page on this site NT Perfmon / UNIX rstatd Counters 
    another page on this site Mercury LoadRunner 
    another page on this site Mercury Virtual Table Server (VTS) 
    another page on this site Mercury WinRunner 
    another page on this site Rational Robot 
    another page on this site Free Training! 
    another page on this site Tech Support 


    How I may help

    Send a message with your email client program


    Your rating of this page:
    Low High




    Your first name:

    Your family name:

    Your location (city, country):

    Your Email address: 



      Top of Page Go to top of page

    Thank you!