0% found this document useful (0 votes)
301 views

QALoad - Tips & Troubleshooting Guide

The document provides tips for script variablization and troubleshooting errors in QALoad performance test scripts. It discusses best practices like: 1) Variablizing constant data by substituting values from a datapool instead of using literal values to simulate multiple users. 2) Dynamically retrieving values like session IDs from the capture file and setting them as variables. 3) Avoiding pointers in scripts to prevent memory issues. 4) Understanding the difference between {variable} and {*variable} when substituting values. 5) Using {!} to persist variable values for further use in the script.

Uploaded by

Mohd Intekhab
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
301 views

QALoad - Tips & Troubleshooting Guide

The document provides tips for script variablization and troubleshooting errors in QALoad performance test scripts. It discusses best practices like: 1) Variablizing constant data by substituting values from a datapool instead of using literal values to simulate multiple users. 2) Dynamically retrieving values like session IDs from the capture file and setting them as variables. 3) Avoiding pointers in scripts to prevent memory issues. 4) Understanding the difference between {variable} and {*variable} when substituting values. 5) Using {!} to persist variable values for further use in the script.

Uploaded by

Mohd Intekhab
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 11

QALoad Tips & Troubleshooting

March 20, 2009


Deepa Maheshwari

Internal Use Only 1


Scope of the Document
This document throws light on some of the important aspects of script variablization
and troubleshooting errors encountered in creation and execution of the performance
test scripts using QALoad. The examples taken are from the Performance Lab
Testing of LSS 4.0.

Important Aspects:

1) You could have some constant data embedded in the script that you have entered
in the application’s input fields while recording (for example, User Id). If you run a
load test using this script, the script uses the same data for each transaction. To run
a realistic test, you can modify the script to use variable data from a data pool file.
By varying the data input over the course of a test, the behavior more realistically
emulates the behavior of multiple users.
For example, we can “variablize” the UserId for login:
DO_SetValue("txtUserID", "cmadmin")

Select and highlight “cmadmin”, Right-click; Active Data, Datapool substitution,


Add..

Select the type of the datapool is it local or central?

Give an ID to the datapool, follow the C naming convention for that. (in this case it
is
DivLastNamePool)
Locate your datapool. By default all datapools reside at:
..\Program Files\Compuware\QALoad\Datapools\

Select the Rewind at End of File option only if you can use data more than once like
for Search scripts.
Click OK.
The datapool is displayed, select the column of the data you are variablizing

Internal Use Only 2


In this case, it is the first column. Click OK.
The code would then look like this:
DO_SetValue("txtUserID", GET_DATA_FIELD(DivLastNamePool, 1));

Repeat this process for all literal values.

2) Script would have some variables whose values will be set dynamically with
every instance of validation. i.e. the session Id.

In order to get any value dynamically in the script, look into the capture file for the
first occurrence of that value. See how the value can be uniquely determined. From
the capture file, you can determine the request and the reply after which you can get
that value. In the script, search for this request and after the reply of the request, try
to get the value of the variable.

For example,
Looking for the sessionId in the capture file, it first appears as
function pageSetup(sEnv){setTimeout("window.focus()",20);initHelp();}\r\n
</script>\r\n\t</HEAD>\r\n\t<body id="body1" onLoad="pageSetup();" scroll="no"
path="LitigationAdvisorStart.htm?s=3945EB68-E35B-40DD-A2AE-

Internal Use Only 3


EF62BC086BBA&amp;env=28" style="BACKGROUND-COLOR:#4F5E85"
onfocus="handlefocus()" text="#000000" aLink="#000000" link="#000000"
vLink="#000000">

now finding the same location in the script,


Note: looking for the point in the script where ‘s’ is first defined or used can help.

Retrieve the value of s:


DO_SetValue("s", DO_GetUniqueString("s=", "&"));

3) As far as possible try avoiding any code to our scripts especially pointers, since
QA Load used to have problems while trying to clean memory and freeing pointers.
For example we require a valiable ‘s’ to have session Id value. Now there are two
ways to achieve it:
A) Using Pointers
char *sLitAdv;
sLitAdv = NULL;
sLitAdv = DO_GetUniqueString("SessionId=", " ");
DO_SetValue("s", sLitAdv);

B) Avoiding pointers
DO_SetValue("s", DO_GetUniqueString("SessionId=", " "));

Prefer option B over option A whenever possible. If user still decides to go with
option A then add these two lines of code in the end to free and avoid any memory
leaks

free(sLitAdv);
sLitAdv =NULL;

4) There is subtle difference in {variable} and {*variable}. The {variable}


Implies variable=variable while {*variable} implies the value of the variable.

Example:

DO_Http("POST http://20.15.36.\28/lssv2/_LaAsp/LitigationAdvisor.asp
HTTP/1.0\r\n"
"Accept: */*\r\n"
"Accept-Language: en-us\r\n"
"Referer: http://20.15.36.78/lssv2/_LaHtml/LitigationAdvisor.htm?
{s}\r\n"
"Content-Type: LaX_Data_Request\r\n"
"Content-Length: {*content-length}\r\n"

Internal Use Only 4


"Pragma: "
"no-cache\r\n\r\n{*LitAdv1}{*s}{*LitAdv2}"
);

In the above DO_Http () statement, the first instance of s will be replaced with s=
value of s. while the second instance of s will be replaced with the value of s.

5) Use {variable!} instead of {variable}. This would facilitate persisting the value of
the variable in the scope of the script for further use in the code and you would not
need to set it again anywhere in the script.

For example,
use {s!} in place of {s}. This would save the sessionId value in the 's' variable for
further use in the code.

6) Once session data is assigned to some variable, we can replace all the instances of
hard coded session data by variable holding session data.

Example: The following instruction holds the hard coded value of session id.

DO_Http ("GET http://20.15.36.28/lssv2/_LaHtml/LitigationAdvisorStart.htm?


s=D1ADB02C-AAD4-40F8-8EC0-D17062ADB174"
"HTTP/1.0\r\n"
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, "
"application/vnd.ms-excel, application/msword, */*\r\n"
"Accept-Language: en-us\r\n\r\n" );

It will be changed to: -

DO_Http ("GET http://20.15.36.28/lssv2/_LaHtml/LitigationAdvisorStart.htm?{s}"


"HTTP/1.0\r\n"
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, "
"application/vnd.ms-excel, application/msword, */*\r\n"
"Accept-Language: en-us\r\n\r\n"

7) Whenever you find any string that contains a variable value in it, you need to
replace it appropriately.
For example,
DO_SetValue("txtLoadMessage", "init%28%274E1C8313-EB67-4E71-A1BB-
B67DB81B0776%27%2C+%2728%27%2C+%271%27%2C%270%27%2C%27D
%27%2C%27US%27%29”);

Internal Use Only 5


Here we need to replace the sessionId.

Split this txtLoadMessage in two parts, first that occurs before the sessionId value
and the second that occurs after the sessionId value.
DO_SetValue("txtLoadMessage", "init%28%27");
//4E1C8313-EB67-4E71-A1BB-B67DB81B0776
DO_SetValue("txtLoadMessage_1", "%27%2C+%2728%27%2C+%271%27%2C
%270%27%2C%27D%27%2C%27US%27%29");
Now, wherever {txtLoadMessage} is being used, replace it with
{txtLoadMessage}{*s!}{*txtLoadMessage_1}.
Note: I have not put exclamation mark here with the txtLoadMessage_1 i.e. I have
not used {*txtLoadMessage!}, as I don't need this value further in the script after
this one usage.

8) The Pragma section of DO_Http () statement needs to be substituted


appropriately by using the variable substitution and then concatenation of those.

For Example:
Suppose we have A DO_SetValue () statement and corresponding DO_Http () as
below:

DO_SetValue("<request><method>GetUserProfile</method><session>'4E1C8313"
"-EB67-4E71-A1BB-
67DB81B0776'</session><argNumber>2</argNumber><parm0>"
"<![CDATA[28]]></parm0><parm1><![CDATA[4E1C8313-EB67-4E71-A1BB-
B67
“DB81 B0776]]></parm1></request>"
"", ""
"<request><method>GetUserProfile</method><session>'4E1C8313-EB67 -4E71”
"-A1BB-B67DB81B0776'</session><argNumber>2</argNumber><parm0><!”
"[CDATA[28]]></parm0><parm1><![CDATA[4E1C8313-EB67-4E71-A1BB-
B67D”
“B81B0776]]></parm1></request>");

Http("POST http://20.15.36.28/lssv40/_LaAspx/LSS_data_accessor.aspx "


"HTTP/1.0\r\n"
"Accept: */*\r\n"
"Accept-Language: en-us\r\n"
"Referer: http://20.15.36.28/lssv40/_LaHtml/LegalSolutionsSuite.htm?
{s!}"
"&env=28\r\n"
"Content-Type: LaX_Data_Request\r\n"
"Content-Length: {*content-length}\r\n"

Internal Use Only 6


"Pragma: "
"no-cache\r\n\r\n
{*<request><method>GetUserProfile</method><session>'4E1C8313"
"-EB67-4E71-A1BB-
67DB81B0776'</session><argNumber>2</argNumber><parm0>"
"<![CDATA[28]]></parm0><parm1><![CDATA[4E1C8313-EB67-4E71-A1BB-
B67
“DB81 B0776]]></parm1></request>});

Since in the http request we are just using the value of the string variable, i.e. the
right argument in the DO_SetValue(..), we just need to variablize the right argument
only.

The above statements must be modified in the way described below:


First the DO_SetValue(..) statement should be broken into multiple statements so
that the variables are separated from static data.

DO_SetValue("litAdv1",
"<request><method>GetUserProfile</method><session>'");
//4E1C8313-EB67-4E71-A1BB-B67DB81B0776
DO_SetValue("litAdv2", "'</session><argNumber>2</argNumber><parm0>”
<![CDATA[28]]></parm0><parm1><![CDATA[");
//4E1C8313-EB67-4E71-A1BB-B67DB81B0776
DO_SetValue("litAdv3", "]]></parm1></request>");

DO_Http("POST http://20.15.36.28/lssv40/_LaAspx/LSS_data_accessor.aspx "


"HTTP/1.0\r\n"
"Accept: */*\r\n"
"Accept-Language: en-us\r\n"
"Referer: http://20.15.36.28/lssv40/_LaHtml/LegalSolutionsSuite.htm?
{s!}"
"&env=28\r\n"
"Content-Type: LaX_Data_Request\r\n"
"Content-Length: {*content-length}\r\n"
"Pragma: "
"no-cache\r\n\r\n{*litAdv1}{*s!}{*litAdv2}{*s!}{*litAdv3}"
);

9) The left argument of the Do_SetValue(..) function is treated as the variable


name. But this can only be used to replace string values with a variable. This cannot
be used for assigning the value of the variable to some other variable.
For example,

DO_SetValue("a", “XYZ”);

Internal Use Only 7


In this statement, ‘a’ has been assigned a value. We can replace the value of ‘a’ in
requests or strings by using {*a}. But, if we have to assign some other variable or
object a value of ‘a’ (i.e. ‘XYZ’), then we cannot use {*a}.

DO_SetValue("txtLoadDivId", {*a});
This is wrong.

Here we would need a pointer variable that has value "XYZ". The code would be:

char * a;
a=NULL;
This code would be at the start of the script.

DO_SetValue("a", “XYZ”);
Write this where you want to assign the value to ‘a’.

DO_SetValue("txtLoadDivId", a);
Write this where you have to assign some other variable a value of ‘a’.

Also, you need a pointer variable for printing values.


DO__printf("%s", a);

And after all uses of ‘a’, do remember to clear the memory assigned to the variable:

free(a);
a=NULL;

10) Variablizing the __VIEWSTATE_KEY or similar variables which include a


timestamp
Example:
DO_SetValue("__VIEWSTATE_KEY", ""
"VIEWSTATE_dotmjo55asrt4r45c4wh1e2u_%2Flssv40%2F_LaAspx
%2FInvoiceFilterSort.aspx%3Fe%3D28%26s%3D59FD85C2-590A-43BA-A78C-
1F0B0B3678A4%26component%3DANA_633694857471875000");

There are three instances that need to be variablized in the above


_VIEWSTATE_KEY and any where in the script:
1. ASP.NET_SessionId= “dotmjo55asrt4r45c4wh1e2u”
2. SessionId-s= “59FD85C2-590A-43BA-A78C-1F0B0B3678A”
3. This value: “633694857471875000” is based on the time of the request,
which would change for each different request and would need to be
varilablized.
The best way to variablize the _VIEWSTATE_KEY is to get it dynamically and this
is one way how you can do it:

Internal Use Only 8


Declare a pointer to char at the beginning of the script something like this:

char *viewSt = NULL;

Then put the below statement at the point where you are getting the viewstate_key
for the required page in the script. Cross check it with the capture file:

viewSt = DO_GetUniqueString("id=\"__VIEWSTATE_KEY\" value=\"", "\"") ;

and then replace the next statement with:


DO_SetValue("__VIEWSTATE_KEY", viewSt);

11) Sometimes you may need a value in the script that is saved as a hidden field on
your form (the web page traversed as per the ATD in the application).

For example, the value of ‘viewstate’ and ‘eventvalidation’ in the example below:

DO_GetFormValueByName(FORM(1), "hidden", "__VIEWSTATE", 1, &ptrVS);

DO_GetFormValueByName(FORM(1), "hidden", "__EVENTVALIDATION", 1,


&ptrEV);

ptrVS and ptrEV need to be declared as pointer variables. The location where the
viewstate and eventvalidation field values need to be retrieved can be determined by
looking at the capture file or looking at the built in comments on the script(if
available). Write this code after you get response of the page you are looking for.

12) If your script does not compile or validate successfully, then in the output
window of workbench you get the line which is throwing error. Double click that
error and you will be taken to that statement in the script.

13) Sometimes in order to troubleshoot a problem, you may be required to review


the log files created dynamically for each run of the script.

Each virtual user for which you enabled “Logfile Generation” will have created a
file containing information about their performance. When a test finishes running,
all log files are saved in the following directory:

..\Program Files\Compuware\QALoad\LogFiles.

Log Files are named


<scriptname>_<middleware>_vu<AbsoluteVirtualUserNumber>.<ext>, where:

Internal Use Only 9


• <scriptname> is the name of the script the virtual user ran
• <middleware> is the name of your middleware application
• <AbsoluteVirtualUserNumber> is the identification number assigned to the
virtual user
• <.ext> ‘rip’.

<.ext> can be a ‘rip’, ‘cap’ or ‘trc’ file.


This file can be viewed to see the http: Post information. Also, you can extract
<HTML></HTML> data and place in a file with the extension .html this
information is helpful in discovering kind of error you are getting.

14) For every load test there is a set of files; these files need to match. The best way
to check is to look at the timestamp of the debug files to ensure they were created
around the same time. Also, ensure that you are playing back the correct C script.
For example, a capture and playback of 1 virtual user and 1 transaction will result in
the following files:
• .c
(with DO_LogfileWWW(TRUE); located at \ QALoad \Middlewares\www\scripts)
• .cap
(original; located at \ QALoad \Middlewares\www\captures)
player buffer file
(items in player window; choose Save from the File menu to save the buffer to any
location)
• www2031vu0000.rip
(www(port #)vu(vu#).rip file is generated ONLY if errors are encountered during
the script execution / validation. This is located at \QALoad\LogFiles)
• www2031vu0000.cap
(www(port #)vu(vu#).cap
keeps a log of each virtual user; located in \ QALoad \LogFiles)

15) It may happen that you are able to compile, validate and execute a script, but
errors are getting logged on the Event log of your Application server. It is
recommended that we try to investigate the cause of application errors as these
might negatively impact the performance. Check the Event log of the Application
server before finalizing a script.

16) While recording a script give each page time to load fully before going for next
click. This helps avoiding any conflict which may occur while running the tests
from QALoad conductor especially for multiple virtual users.

Internal Use Only 10


Internal Use Only 11

You might also like