The first thing to understand about a failing web test is that the request which fails is not always the cause of the problem.  There is likely a previous request which is not behaving the same way it did during recording.  It is also likely that there are some dynamic variables, such as a session id, that are hard coded in your requests and you need to modify your requests to not hard code these values.  By dynamic, I mean the values are different for each iteration of the web test.

So how do you go about debugging these problems?  First look at the request which is failing and see what the error is.  There are really 2 common errors you will see and they have a similar root cause.

The first is when the automatic hidden field binding fails.  When this happens you will see something like: “RequestFailed: Context parameter '$HIDDEN1.__VIEWSTATE' not found in test context”.  This error message is indicating that the web test tried to extract a hidden field called VIEWSTATE from the previous response but was not able to extract it.  The current request tried to use the value, but since it was not there, you received this error.  So why is the previous request not flagged as an error?  The reason is that the previous request was probably redirected to an error page but still returned an http status of 200 OK.  So although it did not go to the same page as it did when recording, it was marked as success because of the 200 OK.  The built in Extract Hidden Fields rule does not know which fields it is extracting.  It just extracts all hidden fields on the page and puts them in the context.

The second error is a current request fails because it is using a hard coded dynamic variable.  In this case the request that failed really is the problem.  These 2 problems have the same root cause because the first error also happens when a request is submitted with a hardcoded dynamic variable, but instead of returning an error you are just redirected to an error page.

I will walk you through an example of the second error and how I would debug the problem.  My example site is a SQL Server Reporting services site.  These sites have a number of dynamic parameters which need to be correlated.

1)      I recorded my web test and now I am playing the web test back.  The first time I played the web test back it was successful.  However, when I come in the next morning and play back the test it fails with the 500 error you see below.  Why would it playback successful right after recording and fail the next morning?  The answer to this is that session variables typically stay alive for a certain amount of time.  It can be anywhere from 5 to 30 minutes or longer.  So even though your test has hardcoded values, it works during the playback right after the recording because the values are still active.  By the time you play it back the following morning, your session has timed out and the values are no longer valid and your requests will start to fail.

2)      So the next step is to open the web test in the web test editor and find the request causing the error.  This step differs slightly for the 2 types of errors I described above. 

a.       If you receive the “RequestFailed: Context parameter '$HIDDEN1.__VIEWSTATE' not found in test context” error, you need to figure out which request the hidden field was suppose to be extracted from.   That is actually your failed request.  Follow these steps for figuring this out.

                                                               i.      In the web test editor find the request that has the RequestFailed error in its response. 

                                                             ii.      Then look at the form post parameters for this request to see what the hidden fields are named.  For example $HIDDEN1.__VIEWSTATE.  The thing you need to find is the number value after $HIDDEN.  So in this case the number 1. 

                                                            iii.      Once you find this, go to the previous request in your test.  If it has an Extract Hidden Fields extraction rule and the extraction rule’s value for Context Parameter Name is 1, then you found the request which needs to be fixed.  If you did not find an extraction rule or the value for the context parameter name does not match the number after hidden, then go up to the previous request.  Continue this process until you find your match.  The value for Context Parameter Name can be found by clicking on the extraction rule and then looking at the property browser.

b.      If you receive a 500 status message, then you are probably on the correct request.

3)      The next step is a bit of an iterative process.  You need to figure out which of the variables for the failed request are dynamic.  If you are very familiar with the web application you are testing, this may be easy.  If not, you may need to investigate each parameter.  Here is what my request looks like in the web test editor.

There are 2 parameters that jump out at me right away.  The ExecutionID and ControlID parameters. These jump out at me because they have the look of session id type variables.  I am going to start with the ControlID parameter.  Do the following:

a.       Go back to the playback UI and click on the first request in your web test.  A lot of times, the session type variables will appear in the response of the first request.

b.      Then click on the response tab.

c.       Select the entire response and paste it an editor.(notepad,  VS, etc.)

d.      Search for the name of the parameter you think may be dynamic.  In my example this is the ControlID parameter.  If you found it, move on to the next step.  If not, click on the next request and go back to step b.

e.      Now look to see if the value of the parameter is different than the value in your web test.  If it is, then this is a dynamic parameter that needs to be correlated.  Here is an image of my response page.  As you can see the ControlID parameter is different than the one in my test.

f.        Since the values are different, we need to extract the new value and bind the extracted value to the hard coded parameter.  The first step is to figure out an extraction rule which can be used to pull the new value out.  You can usually use an extract text rule.  I am going to use an extract text rule with the following values: Context Parameter Name = ControlID, Ends With = &, HTMLDecode = True, Ignore Case = False, Index = 0, Required = True, Starts With = ControlID =, Use Regular Expression = false.

g.       Now the dynamic value will be extracted and added to the test context with a name of ControlID.  So we need to change the hard coded value in the failed request, to use this context parameter.  Go back to the failed request and click on the dynamic parameter.  In my example this is the ControlID parameter.

h.      Then bring up the property grid and click on the value property.  This needs to be changed to pull the ControlID value from the test context.  To have a value pulled from the context you use the following notation, {{ParameterName}}.  I named the parameter ControlID, so I would set this value to {{ControlID}}.

i.         You have correlated the dynamic value.  Play back the web test to verify this worked.

j.        When I play back my test, I see that the request still fails.  But let’s look to see if it is using the extracted ControlID.  First click on the request you added the extraction rule to.

k.       Then click on the details tab.  You should see information about the extraction rule and whether or not it was successful.  In our case it was successful.

l.         Then click on the context tab.  This view shows us what is in the web test context.  We should see a variable called ControlID.

m.    Next go to the request that we bound the ControlID context parameter to.

n.      Click on the request tab and look to see that the value for ControlID matches what is in the context.

 

 

o.      Since the request failed, it is back to step a with a new parameter.  This time I will look for ExecutionID.

p.      After running through these steps for ExecutionID, you can see that my test plays back successfully.

 

 

There are a few other things I find helpful when debugging web tests.

1)      The first is to visually compare the playback results with what happens during recording.  This can help us figure out if we end up on the same page after executing a request.  This can be really helpful for the first type of error I described above.  When you compare what you received in playback with what your browser has during recording, it will be obvious that the requests ended up on different pages.  This will indicated that a request has dynamic values which need to be correlated. 

To do this, create a new web test and submit the first request and compare the results with what playback has.  Keep moving on till you spot a problem.  Keep in mind that the playback browser does not execute JavaScript.  So if your page executes JavaScript while rendering, you may have slightly different results.  I like to create a new web test because the recorder bar breaks out the query string parameters and form post parameters and this makes it easier for comparisons.

 

2)      The second tool I like to use is fiddler, www.fiddlertool.com.  This is proxy recorder and will capture requests, responses, and headers during recording.  You can use this to compare with what the VS web test engine is submitting to see if they match.