<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US"><title type="html">Josh Christie</title><subtitle type="html">Visual Studio Team System - Web and Load Testing</subtitle><id>http://blogs.msdn.com/joshch/atom.xml</id><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/default.aspx" /><link rel="self" type="application/atom+xml" href="http://blogs.msdn.com/joshch/atom.xml" /><generator uri="http://communityserver.org" version="2.1.61025.2">Community Server</generator><updated>2005-08-24T13:14:00Z</updated><entry><title>Better HTML parsing and validation with HtmlAgilityPack</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/12/10/better-html-parsing-and-validation-with-htmlagilitypack.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/12/10/better-html-parsing-and-validation-with-htmlagilitypack.aspx</id><published>2006-12-11T05:56:00Z</published><updated>2006-12-11T05:56:00Z</updated><content type="html">&lt;p&gt;Let's face it; sometimes the Microsoft.VisualStudio.TestTools.WebTesting.HtmlDocument class just doesn't cut it when you're writing custom extraction and validation code.&amp;nbsp; HtmlDocument was&amp;nbsp;originally designed as an internal class&amp;nbsp;to&amp;nbsp;very efficiently parse URLs for dependent requests (such as images) out of HTML response bodies.&amp;nbsp; Before VS 2005 RTM, we made&amp;nbsp;HtmlDocument part of the public WebTestFramework API, but&amp;nbsp;scheduling and resource constraints prevented us from adding more general purpose DOM features like InnerHtml, InnerText, and GetElementById.&amp;nbsp; You could always parse the HTML string yourself, but fortunately there's a better option: &lt;a href="http://www.codeplex.com/htmlagilitypack" class="" mce_href="http://www.codeplex.com/htmlagilitypack"&gt;HtmlAgilityPack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.codeplex.com/htmlagilitypack" class="" mce_href="http://www.codeplex.com/htmlagilitypack"&gt;HtmlAgilityPack&lt;/a&gt; is an open source project on CodePlex.&amp;nbsp; It provides standard DOM APIs and XPath navigation -- &lt;i&gt;even when the HTML is not well-formed!&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Here's a sample web test that uses the HtmlAgilityPack.HtmlDocument instead of the one in WebTestFramework.&amp;nbsp; It simply validates that Microsoft's home page lists Windows as the first item in the navigation sidebar.&amp;nbsp; Download HtmlAgilityPack and add a reference to it from your test project to try out this coded web test.&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System.Collections.Generic;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System.Text;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; Microsoft.VisualStudio.TestTools.WebTesting;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; HtmlAgilityPack;&lt;/font&gt;&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;class&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;WebTest1Coded&lt;/font&gt;&lt;font size="2"&gt; : &lt;/font&gt;&lt;font color="#008080" size="2"&gt;WebTest&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;public&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;override&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;IEnumerator&lt;/font&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008080" size="2"&gt;WebTestRequest&lt;/font&gt;&lt;font size="2"&gt;&amp;gt; GetRequestEnumerator()&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;font color="#008080" size="2"&gt;WebTestRequest&lt;/font&gt;&lt;font size="2"&gt; request1 = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;WebTestRequest&lt;/font&gt;&lt;font size="2"&gt;(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"http://www.microsoft.com/"&lt;/font&gt;&lt;font size="2"&gt;);&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;request1.ValidateResponse += &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#008080" size="2"&gt;EventHandler&lt;/font&gt;&lt;font size="2"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#008080" size="2"&gt;ValidationEventArgs&lt;/font&gt;&lt;font size="2"&gt;&amp;gt;(request1_ValidateResponse);&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;yield&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;return&lt;/font&gt;&lt;font size="2"&gt; request1;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; request1_ValidateResponse(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;object&lt;/font&gt;&lt;font size="2"&gt; sender, &lt;/font&gt;&lt;font color="#008080" size="2"&gt;ValidationEventArgs&lt;/font&gt;&lt;font size="2"&gt; e)&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;{&lt;/font&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;font color="#008000" size="2"&gt;//load the response body string as an HtmlAgilityPack.HtmlDocument&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font size="2"&gt;HtmlAgilityPack.&lt;/font&gt;&lt;font color="#008080" size="2"&gt;HtmlDocument&lt;/font&gt;&lt;font size="2"&gt; doc = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;new&lt;/font&gt;&lt;font size="2"&gt; HtmlAgilityPack.&lt;/font&gt;&lt;font color="#008080" size="2"&gt;HtmlDocument&lt;/font&gt;&lt;font size="2"&gt;();&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font size="2"&gt;doc.LoadHtml(e.Response.BodyString);&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#008000" size="2"&gt;//locate the "Nav" element&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#008080" size="2"&gt;HtmlNode&lt;/font&gt;&lt;font size="2"&gt; navNode = doc.GetElementbyId(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;"Nav"&lt;/font&gt;&lt;font size="2"&gt;);&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#008000" size="2"&gt;//pick the first &amp;lt;li&amp;gt; element&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font color="#008080" size="2"&gt;HtmlNode&lt;/font&gt;&lt;font size="2"&gt; firstNavItemNode = navNode.SelectSingleNode(&lt;/font&gt;&lt;font color="#800000" size="2"&gt;".//li"&lt;/font&gt;&lt;font size="2"&gt;);&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;font color="#008000" size="2"&gt;//validate the first list item in the Nav element says "Windows"&lt;/font&gt;&lt;/p&gt;&lt;font size="2"&gt;
&lt;/font&gt;&lt;p&gt;&lt;font size="2"&gt;e.IsValid = firstNavItemNode.InnerText == &lt;/font&gt;&lt;font color="#800000" size="2"&gt;"Windows"&lt;/font&gt;&lt;font size="2"&gt;;&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt;













&lt;p&gt;&lt;font size="2"&gt;}&lt;/font&gt;&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;br&gt;Updated: Fixed XPath query thanks to Oleg's comment.&amp;nbsp; Also fixed indention of the code.&lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1260631" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Check and modify the status of extraction or validation rules</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/11/16/check-and-modify-the-status-of-extraction-or-validation-rules.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/11/16/check-and-modify-the-status-of-extraction-or-validation-rules.aspx</id><published>2006-11-17T07:01:00Z</published><updated>2006-11-17T07:01:00Z</updated><content type="html">&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;The following came up on our internal discussion list today.&amp;nbsp; A user wanted to run an extraction rule and execute some different requests based on whether&amp;nbsp;the rule&amp;nbsp;succeeded or not.&amp;nbsp; The problem is that a failed extraction rule normally causes the&amp;nbsp;web test&amp;nbsp;to fail.&amp;nbsp; Fortunately, there's an easy way to check the success status of the rule, use that value later,&amp;nbsp;and&amp;nbsp;prevent&amp;nbsp;the rule&amp;nbsp;from failing the web test.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;Let's say you have coded web test like the following:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerator&lt;/SPAN&gt;&lt;/FONT&gt;&amp;lt;&lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt;&amp;gt; GetRequestEnumerator()&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt; request1 = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt;(&lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"http://vsnc/"&lt;/SPAN&gt;&lt;/FONT&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request1.RecordedResponseUrl = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"http://vsnc/"&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractText&lt;/SPAN&gt;&lt;/FONT&gt; extractionRule1 = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractText&lt;/SPAN&gt;&lt;/FONT&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.StartsWith = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Logged in as "&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.EndsWith = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"."&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.IgnoreCase = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.UseRegularExpression = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.Required = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.Index = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.HtmlDecode = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.ContextParameterName = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Name"&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; request1.ExtractValues += &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;EventHandler&lt;/SPAN&gt;&lt;/FONT&gt;&amp;lt;&lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractionEventArgs&lt;/SPAN&gt;&lt;/FONT&gt;&amp;gt;(extractionRule1.Extract);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;yield&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;&lt;/FONT&gt; request1;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;Instead of hooking up the extraction rule directly to the ExtractValues event, you can prevent the web test from failing by using a custom event handler.&amp;nbsp; Your event handler can check and even modify values on the ExtractionEventArgs as shown below:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" color=blue size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" color=blue size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;public&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;override&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;IEnumerator&lt;/SPAN&gt;&lt;/FONT&gt;&amp;lt;&lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt;&amp;gt; GetRequestEnumerator()&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt; request1 = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;WebTestRequest&lt;/SPAN&gt;&lt;/FONT&gt;(&lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"http://vsnc/"&lt;/SPAN&gt;&lt;/FONT&gt;);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request1.RecordedResponseUrl = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"http://vsnc/"&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request1.ExtractValues += &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;EventHandler&lt;/SPAN&gt;&lt;/FONT&gt;&amp;lt;&lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractionEventArgs&lt;/SPAN&gt;&lt;/FONT&gt;&amp;gt;(request1_ExtractValues);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;yield&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;return&lt;/SPAN&gt;&lt;/FONT&gt; request1;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;&lt;/FONT&gt; ((&lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;bool&lt;/SPAN&gt;&lt;/FONT&gt;)&lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;&lt;/FONT&gt;.Context[&lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"LogInNameFound"&lt;/SPAN&gt;&lt;/FONT&gt;] == &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//do something, issue different requests, etc.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;}&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" color=blue size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: blue; FONT-FAMILY: 'Courier New'"&gt;void&lt;/SPAN&gt;&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt; request1_ExtractValues(&lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;object&lt;/SPAN&gt;&lt;/FONT&gt; sender, &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractionEventArgs&lt;/SPAN&gt;&lt;/FONT&gt; e)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;{&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractText&lt;/SPAN&gt;&lt;/FONT&gt; extractionRule1 = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;new&lt;/SPAN&gt;&lt;/FONT&gt; &lt;FONT color=#2b91af&gt;&lt;SPAN style="COLOR: #2b91af"&gt;ExtractText&lt;/SPAN&gt;&lt;/FONT&gt;();&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.StartsWith = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Logged in as "&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.EndsWith = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"."&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.IgnoreCase = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.UseRegularExpression = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.Required = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.Index = 0;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.HtmlDecode = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.ContextParameterName = &lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"Name"&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//call the extraction rule directly&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; extractionRule1.Extract(sender, e);&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//here's where I want to check or modify the&amp;nbsp;success status of the rule&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" color=green size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; COLOR: green; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt;&lt;/FONT&gt; (e.Success)&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//set a context parameter for use later in the web test&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;&lt;/FONT&gt;.Context[&lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"LogInNameFound"&lt;/SPAN&gt;&lt;/FONT&gt;] = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;else&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//set a context parameter to indicate this rule failed&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;this&lt;/SPAN&gt;&lt;/FONT&gt;.Context[&lt;FONT color=#a31515&gt;&lt;SPAN style="COLOR: #a31515"&gt;"LogInNameFound"&lt;/SPAN&gt;&lt;/FONT&gt;] = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;false&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;FONT color=green&gt;&lt;SPAN style="COLOR: green"&gt;//force the rule to pass&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Success = &lt;FONT color=blue&gt;&lt;SPAN style="COLOR: blue"&gt;true&lt;/SPAN&gt;&lt;/FONT&gt;;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;}&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;FONT face="Courier New" size=2&gt;&lt;SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'"&gt;As you can see, inserting your own event handler can give you more control over the execution of extraction&amp;nbsp;and validation rules.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=1091783" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Can I call a web test from a web test?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/07/07/659422.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/07/07/659422.aspx</id><published>2006-07-07T22:01:00Z</published><updated>2006-07-07T22:01:00Z</updated><content type="html">&lt;P&gt;I've seen this question come up several times recently, so I'm going to try to provide the full answer here.&amp;nbsp; Let me start by saying that we have some significant changes in the pipeline that will make calling a web test from another web test a fully supported feature in a future release.&amp;nbsp; Until then, I do not recommend it due to the gotchas listed below.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The web test engine will not load data sources in the called web test.&amp;nbsp; A possible workaround is to use custom databinding such as reading values directly from a database using ADO.NET.&lt;/LI&gt;
&lt;LI&gt;The WebTestContexts in the caller and callee web tests are not unified.&amp;nbsp; This can make it difficult to share values between the tests such as the current username or session ID.&amp;nbsp; This can also make it very difficult to use extraction rules since the rules will extract values into the caller's WebTestContext, but the callee will try to read the values out of its own WebTestContext.&lt;/LI&gt;
&lt;LI&gt;WebTestPlugins and PreWebTest/PostWebTest&amp;nbsp;event handlers&amp;nbsp;will not be called.&lt;/LI&gt;
&lt;LI&gt;WebTestRequestPlugins will not be called.&amp;nbsp; &lt;STRONG&gt;Note&lt;/STRONG&gt;:&amp;nbsp;WebTestRequest-level events such as PreRequest, ValidateResponse, ExtractValues, and PostRequest will still work.&lt;/LI&gt;
&lt;LI&gt;CreateTransaction() and EndTransaction() will have no effect.&lt;/LI&gt;
&lt;LI&gt;MoveDataTableCursor() will have no effect.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;That's quite a list of gotchas, but calling a web test from another web test can still be done if&amp;nbsp;you're not depending on databinding, transactions, the context, or plugins.&lt;/P&gt;
&lt;P&gt;If you still want to call a web test from a web test, the code should look like this:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public override IEnumerator&amp;lt;WebTestRequest&amp;gt; GetRequestEnumerator()&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebTestRequest request1 = new WebTestRequest("http://localhost/&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return request1;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebTest2Coded webTest2Coded = new WebTest2Coded();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; IEnumerator&amp;lt;WebTestRequest&amp;gt; webTest2Enumerator = webTest2Coded.GetRequestEnumerator();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (webTest2Enumerator.MoveNext())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return webTest2Enumerator.Current;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebTestRequest request2 = new WebTestRequest("http://localhost/&lt;/FONT&gt;&lt;FONT face="Courier New" size=2&gt;");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return request2;&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Again, &lt;STRONG&gt;I do not recommend calling web tests from other web tests in VS 2005&lt;/STRONG&gt;.&amp;nbsp; It would be best to wait for the next release when it will be a fully supported feature.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=659422" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>So you want to replay an IIS web server log?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/07/03/655518.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/07/03/655518.aspx</id><published>2006-07-03T22:46:00Z</published><updated>2006-07-03T22:46:00Z</updated><content type="html">&lt;P&gt;A&amp;nbsp;few months ago,&amp;nbsp;a group in Microsoft wanted to be able to play back a large IIS log as a Visual Studio web test.&amp;nbsp; They started off with a converter that converted the IIS log into a gigantic coded web test.&amp;nbsp; The 118MB .cs file that resulted was a bit ridiculous and didn't perform very well at design time or run time.&lt;/P&gt;
&lt;P&gt;I took a different approach by reading the IIS log from within&amp;nbsp;the web test.&amp;nbsp; It depends on the&amp;nbsp;the handy &lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;displaylang=en"&gt;LogReader 2.2 download&lt;/A&gt;&amp;nbsp;to handle all the log parsing and keep the code short and simple.&lt;/P&gt;
&lt;P&gt;Here's a sample WebTest that plays back an IIS log:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;public class IISLogCodedWebTest : WebTest&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IISLogCodedWebTest()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.PreAuthenticate = true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override IEnumerator&amp;lt;WebTestRequest&amp;gt; GetRequestEnumerator()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IISLogReader reader = new IISLogReader(@"d:\download\ex060209.log");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (WebTestRequest request in reader.GetRequests())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return request;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The code for the IISLogReader class used above is below:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;using System;&lt;BR&gt;using System.Collections.Generic;&lt;BR&gt;using System.Text;&lt;BR&gt;using MSUtil;&lt;BR&gt;using LogQuery = MSUtil.LogQueryClassClass;&lt;BR&gt;using IISLogInputFormat = MSUtil.COMIISW3CInputContextClassClass;&lt;BR&gt;using LogRecordSet = MSUtil.ILogRecordset;&lt;BR&gt;using Microsoft.VisualStudio.TestTools.WebTesting;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;namespace IISLogToWebTest&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class IISLogReader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string _iisLogPath;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IISLogReader(string iisLogPath)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _iisLogPath = iisLogPath;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;WebTestRequest&amp;gt; GetRequests()&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogQuery logQuery = new LogQuery();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; IISLogInputFormat iisInputFormat = new IISLogInputFormat();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string query = @"SELECT s-ip, s-port, cs-method, cs-uri-stem, cs-uri-query FROM " + _iisLogPath;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; LogRecordSet recordSet = logQuery.Execute(query, iisInputFormat);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while (!recordSet.atEnd())&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ILogRecord record = recordSet.getRecord();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (record.getValueEx("cs-method").ToString() == "GET")&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string server = record.getValueEx("s-ip").ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string path = record.getValueEx("cs-uri-stem").ToString();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string querystring = record.getValueEx("cs-uri-query").ToString();&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder urlBuilder = new StringBuilder();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlBuilder.Append("http://");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlBuilder.Append(server);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlBuilder.Append(path);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!String.IsNullOrEmpty(querystring))&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlBuilder.Append("?");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; urlBuilder.Append(querystring);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; WebTestRequest request = new WebTestRequest(urlBuilder.ToString());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; yield return request;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordSet.moveNext();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordSet.close();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;Let me know if you find this useful or if you have any problems.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=655518" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Why can't I generate more load?</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/05/18/600955.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/05/18/600955.aspx</id><published>2006-05-18T16:30:00Z</published><updated>2006-05-18T16:30:00Z</updated><content type="html">&lt;P&gt;A&amp;nbsp;common question we get goes something like this: "I'm running a 100 user load test and getting X RPS (requests per second).&amp;nbsp; When I add 500 more users, I'm still getting X RPS.&amp;nbsp; What's wrong?"&lt;/P&gt;
&lt;P&gt;Here's a list of some things to check when you're not able to generate the load you expected:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Is your web server CPU/Memory/Network maxed out?&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Is your load generating machine’s (VS machine or agents) CPU/Memory/Network maxed out? &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Is your database server’s (if one exists) CPU/Memory/Disk/Network maxed out? &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Do you have ThinkTime turned on in your load test?&lt;/STRONG&gt;&amp;nbsp; This will limit the rate each “user” can submit requests.&amp;nbsp; For example, 5 seconds of ThinkTime per request will yield a maximum of 0.2 RPS per “user”.&amp;nbsp; Turn ThinkTime off for maximum load generation or use ThinkTime and increase the number of users for more realistic load generation.&amp;nbsp; The latter will generally require more memory.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Make sure the Proxy properties on your web tests are not set to “default”.&lt;/STRONG&gt;&amp;nbsp; This enables automatic proxy server detection which is VERY slow and will greatly reduce your maximum throughput. &lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Don’t forget a load testing tool is designed to find bottlenecks in your application.&lt;/STRONG&gt;&amp;nbsp; If you have pages with high response times due to a database or CPU bottleneck it will limit the number of requests each virtual user can issue per second.&amp;nbsp; Start out with a small amount of load and make sure response times stay reasonable as your ramp up the load.&amp;nbsp; Twenty users with ThinkTime shouldn’t see greater than 10 second response times, for example.&amp;nbsp; You can use the Response Time Goal property to set the maximum expected response time on each request.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;The problem generally comes down to something on this list.&amp;nbsp; Do you have any tips that need to be added to this list?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=600955" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>More load test bloggers</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/02/07/526604.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/02/07/526604.aspx</id><published>2006-02-07T17:21:00Z</published><updated>2006-02-07T17:21:00Z</updated><content type="html">&lt;p&gt;&lt;font color=#000000&gt;&lt;a HREF="/edglas/"&gt;Ed Glas&lt;/a&gt; and &lt;a HREF="/slumley/"&gt;Sean Lumley&lt;/a&gt; are now also blogging about the web/load testing tools in Visual Studio&amp;nbsp;Team System.&amp;nbsp; Ed has several good posts up already.&lt;/font&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=526604" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Bill Barnett, load test blogger</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2006/01/26/517833.aspx" /><id>http://blogs.msdn.com/joshch/archive/2006/01/26/517833.aspx</id><published>2006-01-26T17:08:00Z</published><updated>2006-01-26T17:08:00Z</updated><content type="html">&lt;a href="http://blogs.msdn.com/billbar/"&gt;Bill Barnett&lt;/A&gt;, another member of the "Ocracoke" team (VS Team System's Web and Loading tools), is now blogging.&amp;nbsp; Take a look at the &lt;a href="http://blogs.msdn.com/billbar/articles/517081.aspx"&gt;Advanced Load Testing Features&lt;/A&gt; article he posted.&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=517833" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Web Test Authoring and Debugging Techniques</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/12/22/506717.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/12/22/506717.aspx</id><published>2005-12-22T17:05:00Z</published><updated>2005-12-22T17:05:00Z</updated><content type="html">&lt;P&gt;My whitepaper titled &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/WTAuthDebug.asp"&gt;Web Test Authoring and Debugging Techniques&lt;/A&gt; is now live on MSDN!&amp;nbsp; It covers some best practices for creating web tests as well a lot of things to look for when things don't go the way you expected.&lt;/P&gt;
&lt;P&gt;Please let me know what you think or if you have any questions.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=506717" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Custom ExtractionRule to extract form fields by index</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/11/17/494164.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/11/17/494164.aspx</id><published>2005-11-18T01:04:00Z</published><updated>2005-11-18T01:04:00Z</updated><content type="html">&lt;P&gt;*This is the third post in a series about&amp;nbsp;web test extensibility points.&amp;nbsp;&amp;nbsp;The first post&amp;nbsp;was about&amp;nbsp;&lt;a href="http://blogs.msdn.com/joshch/archive/2005/08/24/455726.aspx"&gt;&lt;FONT color=#0000ff&gt;extending web tests using custom IHttpBody classes&lt;/FONT&gt;&lt;/A&gt;&amp;nbsp;and the second post was about &lt;A id=_ctl0__ctl0__ctl0__ctl0_RecentPosts__ctl0_postlist__ctl0_EntryItems__ctl1_PostTitle href="/joshch/archive/2005/11/02/488398.aspx"&gt;a custom ValidationRule to catch redirects to error pages&lt;/A&gt;.*&lt;/P&gt;
&lt;P&gt;The ExtractHiddenFields rule that is present in most web tests works by extracting every hidden field on a page into the web test context.&amp;nbsp; The naming convention used for these hidden fields is $HIDDENx.y where x is the context parameter name on ExtractHiddenFields&amp;nbsp;(usually '1') and y is the hidden field name.&amp;nbsp;&amp;nbsp;This convention works well for most web pages, but it&amp;nbsp;can't distinguish between multiple hidden fields with the same name, like&amp;nbsp;a page with multiple forms might have.&amp;nbsp;&amp;nbsp;Fortunately, this scenario can be supported with&amp;nbsp;the following&amp;nbsp;custom extracton rule and some minor modifications to the web test.&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;using System;&lt;BR&gt;using System.Collections;&lt;BR&gt;using System.ComponentModel;&lt;BR&gt;using Microsoft.VisualStudio.TestTools.WebTesting;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;namespace OcracokeSamples {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class ExtractFormFieldWithIndex : ExtractionRule {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string _name;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private int _index = 1;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Description("The name of the form field to extract.")]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string Name {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _name; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _name = value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Description("The index of the form field.&amp;nbsp; For example, specifying '2' would " + &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "extract the value of the second form field with the given name.")]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int Index {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _index; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _index = value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string RuleName {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return "Extract Form Field with Index"; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string RuleDescription {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return "Extracts a form field from a page based on the order it appears.&amp;nbsp; " +&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Useful when a page contains multiple forms with fields of the same name.";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void Extract(object sender, ExtractionEventArgs e) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //if the response is not HTML, display an error&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!e.Response.IsHtml) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Success = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Message = "The response did not contain HTML.";&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string formFieldValue = null;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int currentIndex = 0;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //examine each input tag&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (HtmlTag tag in e.Response.HtmlDocument.GetFilteredHtmlTags("input")) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (String.Equals(tag.GetAttributeValueAsString("name"), _name, StringComparison.OrdinalIgnoreCase)) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; currentIndex++;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (currentIndex == _index) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formFieldValue = tag.GetAttributeValueAsString("value");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //if the form field was found, but had no value property, set the value to empty string&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (formFieldValue == null) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; formFieldValue = String.Empty;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; break;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (formFieldValue != null) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.WebTest.Context.Add(this.ContextParameterName, formFieldValue);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Success = true;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Success = false;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Message = String.Format("Form field named '{0}' with index '{1}' was not found.", _name, _index);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;If you read my earlier post about &lt;a href="http://blogs.msdn.com/joshch/archive/2005/11/02/488398.aspx"&gt;creating a custom validation rule&lt;/A&gt;, you'll reconize that creating a custom extraction rule is nearly identical.&amp;nbsp; You simply create a class that derives from ExtractionRule and implement your extraction logic in the Extract method.&amp;nbsp; The ExtractionEventArgs parameter to the Extract method provides access to the WebTestResponse containing&amp;nbsp;all the response data received from the server.&amp;nbsp; Setting e.Success reports whether the rule passed or failed and e.Message allows you to provide an error message that will be displayed in the web test result viewer or the load test monitor.&lt;/P&gt;
&lt;P&gt;To use a&amp;nbsp;custom extraction rule in a web test, you must first let your test project know it exists.&amp;nbsp; If the rule class is included in the test project, just build the project and the rule will show up in the Add Extraction Rule dialog.&amp;nbsp; If, however,&amp;nbsp;the rule is part of a separate class library project and potentially shared by multiple test projects, just build that class library project and add a reference to it in your test project(s).&amp;nbsp; Now when you right-click&amp;nbsp;a request and select Add Extraction Rule, you should see your rule in the Add Extraction Rule dialog shown below.&lt;/P&gt;
&lt;P&gt;&lt;IMG height=430 alt="Add Extraction Rule dialog" src="http://jchristie.members.winisp.net/BlogImages/ExtractFormFieldWithIndexAddRuleDialog.gif" width=549&gt;&lt;/P&gt;
&lt;P&gt;To use&amp;nbsp;this&amp;nbsp;extraction rule, you&amp;nbsp;enter a form field name and specify&amp;nbsp;an index to determine which occurrence of that form field you want to extract (1 for the first, 2 for the second, etc.).&amp;nbsp; Once you specify a context parameter&amp;nbsp;name for the form field you're extracting and add this extraction rule to a request, you'll just need to update the&amp;nbsp;parameter that corresponds to this form field.&amp;nbsp; Instead of $HIDDENx.y,&amp;nbsp;bind the parameter's value to this new context parameter.&lt;/P&gt;
&lt;P&gt;That's it.&amp;nbsp; Any questions about implementing custom extraction rules or using this sample rule?&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=494164" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>VSTS Dev &amp; Test Tools MSDN Public Chat - Wed 10/19 @ 1pm EDT</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/11/16/493384.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/11/16/493384.aspx</id><published>2005-11-16T17:51:00Z</published><updated>2005-11-16T17:51:00Z</updated><content type="html">&lt;p&gt;Team System MSDN Public Chat&lt;/p&gt;
Visual Studio Team Edition for Software Developer &amp;amp; Visual Studio Team Edition for Software Testers&lt;br /&gt;
When: Wednesday, November 16th @ 10am PST&lt;br /&gt;
What: Join us to discuss the Profiler, Test Tools (Unit, Generic, Manual), Web &amp;amp; Load Testing, and Code Analysis (FxCop &amp;amp; PREFast). We have questions for you, will answer questions from you, and will chat about the exciting new technology.&lt;br /&gt;
Where: &lt;A href="http://msdn.microsoft.com/chats"&gt;http://msdn.microsoft.com/chats&lt;/A&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=493384" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>A custom ValidationRule to catch redirects to error pages</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/11/02/488398.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/11/02/488398.aspx</id><published>2005-11-02T21:17:00Z</published><updated>2005-11-02T21:17:00Z</updated><content type="html">&lt;P&gt;*This is the second post in a series about&amp;nbsp;web test extensibility points.&amp;nbsp;&amp;nbsp;The first post&amp;nbsp;was about&amp;nbsp;&lt;a href="http://blogs.msdn.com/joshch/archive/2005/08/24/455726.aspx"&gt;extending web tests using custom IHttpBody classes&lt;/A&gt;.*&lt;/P&gt;
&lt;P&gt;It is a common practice for a&amp;nbsp;web application to trap errors and redirect the user to a "We're sorry, an error has occurred..." page.&amp;nbsp; Unfortunately, these error&amp;nbsp;pages often return a "200 OK" status code instead of an error code in the 400 or 500 range.&amp;nbsp; This&amp;nbsp;behavior is definitely something to watch out for when creating and running web load tests since it could allow web application errors to go unnoticed.&lt;/P&gt;
&lt;P&gt;Here is a sample validation rule called ValidateResponseUrl&amp;nbsp;that checks response URLs to catch redirects to error pages:&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;using System;&lt;BR&gt;using System.Collections.Generic;&lt;BR&gt;using System.ComponentModel;&lt;BR&gt;using System.Text;&lt;BR&gt;using Microsoft.VisualStudio.TestTools.WebTesting;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;namespace OcracokeSamples {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class ValidateResponseUrl : ValidationRule {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private string _urlStringToFind = String.Empty;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private bool _failIfFound = true;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Description("If true, validation fails if the specified string is found in the response URL.&amp;nbsp; If false, validation fails if the specified string is not found in the response URL.")]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool FailIfFound {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _failIfFound; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _failIfFound = value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [Description("The string to search for in the response URL.&amp;nbsp; For example, enter 'Error.aspx' if you want to make sure the server does not redirect to that error page.")]&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public string UrlStringToFind {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _urlStringToFind; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set { _urlStringToFind = value; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string RuleName {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return "Validate Response URL"; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override string RuleDescription {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return "Verifies the response URL.&amp;nbsp; This rule can be used to make sure a redirect to an error page does not occur, for example."; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public override void Validate(object sender, ValidationEventArgs e) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //make sure the string to find has a value&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (String.IsNullOrEmpty(_urlStringToFind)) {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException("The UrlStringToFind property cannot be null or empty string.");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool found = e.Response.ResponseUri.OriginalString.IndexOf(_urlStringToFind, StringComparison.OrdinalIgnoreCase) != -1;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string foundMessage = found ? "was" : "was not";&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //set the result message that will appear in the web test viewer details tab and the load test error table&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.Message = String.Format("The string '{0}' {1} found in the response URL.", _urlStringToFind, foundMessage);&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; //set whether the validation passed or failed&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; e.IsValid = found != _failIfFound;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;As you can see, it doesn't take much code to implement&amp;nbsp;this very useful validation rule.&amp;nbsp; I just added a new class to my test project, made it inherit from ValidationRule, and implemented the RuleName and Validate members.&amp;nbsp;&amp;nbsp;The RuleDescription property&amp;nbsp;and the&amp;nbsp;[Description] attributes make custom validation rules easier to use by providing help text that shows up in the Add Validation Rule dialog (shown below)&amp;nbsp;and the&amp;nbsp;Properties window, but they are completely optional.&lt;/P&gt;
&lt;P&gt;Looking at the Validate method,&amp;nbsp;you&amp;nbsp;might be scratching your head wondering how WebTestResponse.ResponseUri&amp;nbsp;can be different than&amp;nbsp;WebTestRequest.Url.&amp;nbsp;&amp;nbsp;The answer is&amp;nbsp;that when a request's FollowRedirects property is set to True, validation and extraction&amp;nbsp;rules are automatically moved from the original request to the subsequent redirect request.&lt;/P&gt;
&lt;P&gt;To use a&amp;nbsp;custom validation rule in a web test, you must first let your test project know it exists.&amp;nbsp; If the rule class is included in the test project, just build the project and the rule will show up in the Add Validation Rule dialog.&amp;nbsp; If, however,&amp;nbsp;the rule is part of a separate class library project and potentially shared by multiple test projects, just build that class library project and add a reference to it in your test project(s).&amp;nbsp; Now when you right-click&amp;nbsp;a request and select Add Validation Rule, you should see your rule in the Add Validation Rule dialog shown below.&lt;/P&gt;
&lt;P&gt;&lt;IMG height=430 alt="Add Validation Rule dialog" src="http://jchristie.members.winisp.net/BlogImages/ValidateResponseUrlAddRuleDialog.gif" width=549&gt;&lt;/P&gt;
&lt;P&gt;You can see in this case that I'm going to cause the&amp;nbsp;request to fail validation if&amp;nbsp;the server redirects to error.aspx.&amp;nbsp; If you have multiple error pages, you would set the FailIfFound property to False and enter the correct response URL in the UrlStringToFind property&amp;nbsp;so validation will fail if the string is not found in the response URL.&lt;/P&gt;
&lt;P&gt;Please let me know if you have any questions or comments about this validation rule or custom validation rules in general.&amp;nbsp; I'm also open to ideas for what the next web test extensibility point example should be.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=488398" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>VSTS RTM on MSDN</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/10/27/485765.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/10/27/485765.aspx</id><published>2005-10-27T20:49:00Z</published><updated>2005-10-27T20:49:00Z</updated><content type="html">&lt;P&gt;Who isn't excited about that string of acronyms?&amp;nbsp; I know I am.&lt;/P&gt;
&lt;P&gt;The final version of &lt;A href="http://lab.msdn.microsoft.com/teamsystem/"&gt;Visual Studio Team System&lt;/A&gt; is&amp;nbsp;now available for download by MSDN subscribers&amp;nbsp;in advance of the November 7th launch date.&amp;nbsp; If you get the Team Suite or &lt;A href="http://lab.msdn.microsoft.com/teamsystem/teamcenters/tester/"&gt;Team Edition for Software Testers&lt;/A&gt;&amp;nbsp;(also called Team Test), feel free to post questions and comments to our &lt;A href="http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=19"&gt;MSDN support forum&lt;/A&gt; or right here on my blog.&amp;nbsp; The development and test teams for web and load testing&amp;nbsp;are&amp;nbsp;focusing on writing MSDN content and doing community support at the moment, so this is a great time to get your questions answered.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=485765" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Web and Load Testing Webcast (TODAY!)</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/10/25/484640.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/10/25/484640.aspx</id><published>2005-10-25T18:07:00Z</published><updated>2005-10-25T18:07:00Z</updated><content type="html">&lt;P&gt;&lt;A href="http://msevents.microsoft.com/cui/WebCastEventDetails.aspx?EventID=1032283434&amp;amp;EventCategory=4&amp;amp;culture=en-US&amp;amp;CountryCode=US"&gt;MSDN Webcast: Load and Web Testing with Microsoft Visual Studio 2005 Team System (Level 200)&amp;nbsp;&lt;/A&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Start Time:&amp;nbsp;&amp;nbsp; Tuesday, October 25, 2005 1:00 PM (GMT-08:00) Pacific Time (US &amp;amp; Canada)&amp;nbsp; &lt;BR&gt;End Time:&amp;nbsp;&amp;nbsp; Tuesday, October 25, 2005 2:00 PM (GMT-08:00) Pacific Time (US &amp;amp; Canada)&amp;nbsp; &lt;BR&gt;&amp;nbsp;&lt;BR&gt;Products: Visual Studio. &lt;/P&gt;
&lt;P&gt;Recommended Audience: Developer. &lt;/P&gt;
&lt;P&gt;Language: English-American &lt;BR&gt;&amp;nbsp;&lt;BR&gt;Description: By using Microsoft Visual Studio 2005 Team System as a platform, you can better manage the software development life cycle. You have the flexibility to customize and extend this platform to meet organizational needs. In this webcast, gain a general understanding of the Web and load testing features in Visual Studio 2005.&lt;/P&gt;
&lt;P&gt;Presenter: Ed Glas, Group Manager, Microsoft Corporation&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=484640" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Meet up at ASP.NET Connections</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/10/07/478278.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/10/07/478278.aspx</id><published>2005-10-07T19:22:00Z</published><updated>2005-10-07T19:22:00Z</updated><content type="html">&lt;P&gt;I'll be in Las Vegas attending &lt;A href="http://www.devconnections.com/shows/aspfall2005/default.asp?s=65"&gt;ASP.Net Connections&lt;/A&gt; from November 7th through 10th.&amp;nbsp; I'm mainly going so I can learn more about&amp;nbsp;new and upcoming ASP.NET features that we want to make sure we cover in online samples and/or support in our next release.&amp;nbsp; I would also like to meet up with any and all VSTS web load testers (i.e. you) that are going to be there.&amp;nbsp; Leave a comment or send me an email if you're interesting in getting together with me and other web load testers to share feedback, learn more about web tests, swap tips and tricks, etc.&amp;nbsp; I look forward to seeing you there.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=478278" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry><entry><title>Creating custom IHttpBody classes for coded web tests</title><link rel="alternate" type="text/html" href="http://blogs.msdn.com/joshch/archive/2005/08/24/455726.aspx" /><id>http://blogs.msdn.com/joshch/archive/2005/08/24/455726.aspx</id><published>2005-08-24T20:14:00Z</published><updated>2005-08-24T20:14:00Z</updated><content type="html">&lt;P&gt;If you've recorded a web test and generated code, you've probably noticed the FormPostHttpBody class.&amp;nbsp; You might have even seen the StringHttpBody class if you&amp;nbsp;had web service requests in your web test.&amp;nbsp; These are the only two built-in classes for generating HTTP request bodies, so what do you do if you need to send requests containing something other than form parameters and strings?&amp;nbsp; You just implement your own IHttpBody class.&lt;/P&gt;
&lt;P&gt;I'm going to paste in a sample IHttpBody called BinaryHttpBody at the end of this post.&amp;nbsp; This class can be used in coded web tests to send requests with specific binary data in the request body.&amp;nbsp; You might use this if&amp;nbsp;you want to send binary data in a PUT request body,&amp;nbsp;for example.&amp;nbsp; Another use would be if you&amp;nbsp;wanted to load pre-generated request bodies from files on disk.&amp;nbsp;&amp;nbsp;As you can see, the constructor for BinaryHttpBody&amp;nbsp;accepts either a byte array or a Stream.&lt;/P&gt;
&lt;P&gt;To send&amp;nbsp;an array of bytes, you would use BinaryHttpBody like this:&lt;/P&gt;&lt;PRE&gt;WebTestRequest request1 = new WebTestRequest("http://localhost/test.aspx");
request1.Method = "POST";
BinaryHttpBody binaryBody = new BinaryHttpBody("application/octet-stream", 
        new byte[] { 0x01, 0x02, 0x03 });
request1.Body = binaryBody;
yield return request1;
&lt;/PRE&gt;
&lt;P&gt;The following code for BinaryHttpBody should be compatible with the July CTP and later.&lt;/P&gt;&lt;PRE&gt;using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Microsoft.VisualStudio.TestTools.WebTesting;

namespace TestProject1 {
    public class BinaryHttpBody : IHttpBody {
        private string _contentType;
        private Stream _stream;

        public BinaryHttpBody(string contentType, byte[] bytes)
            : this(contentType, new MemoryStream(bytes, false)) {

        }

        public BinaryHttpBody(string contentType, Stream stream) {
            _contentType = contentType;
            _stream = stream;
        }

        public BinaryHttpBody() {

        }

        public string ContentType {
            get { return _contentType; }
            set { _contentType = value; }
        }

        public Stream Stream {
            get { return _stream; }
            set { _stream = value; }
        }

        public void WriteHttpBody(WebTestRequest request, System.IO.Stream bodyStream) {
            if (_stream != null &amp;amp;&amp;amp; _stream.CanRead) {
                try {
                    byte[] buffer = new byte[8192];
                    int bytesRead;
                    while ((bytesRead = _stream.Read(buffer, 0, buffer.Length)) &amp;gt; 0) {
                        bodyStream.Write(buffer, 0, bytesRead);
                    }
                } finally {
                    _stream.Close();
                }
            }
        }

        public object Clone() {
            throw new NotImplementedException();
        }
    }
}
&lt;/PRE&gt;
&lt;P&gt;This is just one example of an extensibility point web tests provide. I plan to demonstrate custom validation and extraction rules next.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=455726" width="1" height="1"&gt;</content><author><name>JoshCh</name><uri>http://blogs.msdn.com/members/JoshCh.aspx</uri></author></entry></feed>