<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>YuTong's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/yutong/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/yutong/feed.xml</link>
    <description>Web/Load Testing</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:28:42 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Web Test Recorder Plug-in: Extract Session ID from URI Path</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/web-test-recorder-plug-in-extract-session-id-from-uri-path</link>
      <pubDate>Thu, 22 Apr 2010 08:06:17 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/04/22/web-test-recorder-plug-in-extract-session-id-from-uri-path/</guid>
      <description><![CDATA[ASP.NET session state enables the Web applications to store and retrieve values for a user as the...]]></description>
      <content:encoded><![CDATA[<p>ASP.NET session state enables the Web applications to store and retrieve values for a user as the user navigates ASP.NET pages. By default, ASP.NET session state is enabled for all ASP.NET applications.  <p>Each Web session is identified by a unique identifier, i.e. SessionID. By default, <a href="https://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx">SessionID</a> value is stored in a cookie. However, the application can be configured to store <a href="https://msdn.microsoft.com/en-us/library/system.web.sessionstate.httpsessionstate.sessionid.aspx">SessionID</a> value in the URL for a "cookieless" session, i.e. you will have the following configured in your Web site’s app.config file.  <blockquote> <p>&lt;system.web&gt;<br>&nbsp; &lt;sessionState cookieless="true" /&gt; <br>&lt;/system.web&gt;</p></blockquote> <p>When the SessionID is passed in the URL, VSTS does not automatically promote the correlation after Web test recording or in a correlation run. This following post will describe the details on how to extract the SessionID and correlate the recorded Web test requests by implementing a Web test recorder plug-in.  <p>The following screenshots show the differences in the Web tests before and after enabling the SessionID recorder plug-in.</p> <table cellspacing="0" cellpadding="2" width="824" border="0"> <tbody> <tr> <td valign="top" width="324"><strong>Before enabling the SessionID recorder plug-in<br></strong></td> <td valign="top" width="498"><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; After enabling the SessionID recorder plug-in</strong></td></tr> <tr> <td valign="top" width="324"><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_14.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_14.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="195" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_thumb_6.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_thumb_6.png" width="467" border="0"></a> </td> <td valign="top" width="498">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_10.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_10.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="195" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_thumb_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/WebTestRecorderPluginExtractSessionIDfro_DA2C/image_thumb_4.png" width="395" border="0"></a></td></tr></tbody></table> <p><strong>Step 1</strong> – Create a C# class library  <p><strong>Step 2</strong> – Add a reference to Microsoft.VisualStudio.QualityTools.WebTestFramework.  <p><strong>Step 3</strong> - Write an extraction rule to extract the SessionID from a url.</p> <p><strong>[ExtractionRule.cs]</strong></p><pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> Microsoft.VisualStudio.TestTools.WebTesting;
<span class="kwrd">using</span> System.Globalization;
<span class="kwrd">using</span> System.Text.RegularExpressions;
<span class="kwrd">using</span> System.ComponentModel;

<span class="kwrd">namespace</span> SampleRecorderPlugin
{
    <span class="rem">//---------------------------------------------------------------------------------</span>
    <span class="rem">// This class creates a custom extraction rule named "Extract Session ID from Path"</span>
    <span class="rem">//---------------------------------------------------------------------------------</span>
    <span class="kwrd">public</span> <span class="kwrd">class</span> ExtractSessionIDFromPath : ExtractionRule
    {
        <span class="rem">/// Specify a name for use in the user interface.</span>
        <span class="rem">/// The user sees this name in the Add Extraction dialog box.</span>
        <span class="rem">//---------------------------------------------------------------------</span>
        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">string</span> RuleName
        {
            get { <span class="kwrd">return</span> <span class="str">"ExtractSessionIDFromPath"</span>; }
        }

        <span class="rem">/// Specify a description for use in the user interface.</span>
        <span class="rem">/// The user sees this description in the Add Extraction dialog box.</span>
        <span class="rem">//---------------------------------------------------------------------</span>
        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">string</span> RuleDescription
        {
            get { <span class="kwrd">return</span> <span class="str">"Extract Session ID from Path"</span>; }
        }

        <span class="kwrd">internal</span> <span class="kwrd">enum</span> SearchResult
        {
            Found,
            StartsWithNotFound,
            EndsWithNotFound,
        }

        <span class="kwrd">public</span> <span class="kwrd">string</span> StartsWith
        {
            get { <span class="kwrd">return</span> m_startsWith; }
            set { m_startsWith = <span class="kwrd">value</span>; }
        }

        <span class="kwrd">public</span> <span class="kwrd">string</span> EndsWith
        {
            get { <span class="kwrd">return</span> m_endsWith; }
            set { m_endsWith = <span class="kwrd">value</span>; }
        }

        [DefaultValue(<span class="kwrd">false</span>)]
        <span class="kwrd">public</span> <span class="kwrd">bool</span> IgnoreCase
        {
            get { <span class="kwrd">return</span> m_ignoreCase; }
            set { m_ignoreCase = <span class="kwrd">value</span>; }
        }

        [DefaultValue(<span class="kwrd">true</span>)]
        <span class="kwrd">public</span> <span class="kwrd">bool</span> IsRequired
        {
            get { <span class="kwrd">return</span> m_required; }
            set { m_required = <span class="kwrd">value</span>; }
        }

        <span class="kwrd">internal</span> <span class="kwrd">void</span> Initialize()
        {
            <span class="kwrd">string</span> startsWith = StartsWith;
            <span class="kwrd">string</span> endsWith = EndsWith;
            startsWith = Regex.Escape(StartsWith);
            endsWith = Regex.Escape(EndsWith);

            RegexOptions options = RegexOptions.Singleline;
            <span class="kwrd">if</span> (IgnoreCase)
            {
                options |= RegexOptions.IgnoreCase;
            }

            m_startsWithRegEx = <span class="kwrd">new</span> Regex(startsWith, options);
            m_endsWithRegEx = <span class="kwrd">new</span> Regex(endsWith, options);

            m_result = <span class="kwrd">null</span>;
        }

        <span class="rem">// Finds the match</span>
        <span class="kwrd">internal</span> SearchResult FindMatch(<span class="kwrd">string</span> url)
        {
            Match startMatch;
            Match endMatch;
            <span class="kwrd">int</span> startIndex = 0;
            <span class="kwrd">int</span> endIndex = 0;

            <span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrEmpty(StartsWith))
            {
                <span class="rem">// Find the start</span>
                startMatch = m_startsWithRegEx.Match(url, 0);
                <span class="kwrd">if</span> (!startMatch.Success)
                {
                    <span class="kwrd">return</span> SearchResult.StartsWithNotFound;
                }
                startIndex = startMatch.Index;
            }

            <span class="kwrd">if</span> (!<span class="kwrd">string</span>.IsNullOrEmpty(EndsWith))
            {
                <span class="rem">// Find the end</span>
                endMatch = m_endsWithRegEx.Match(url, startIndex);
                <span class="kwrd">if</span> (!endMatch.Success)
                {
                    <span class="kwrd">return</span> SearchResult.EndsWithNotFound;
                }
                endIndex = endMatch.Index + EndsWith.Length;
            }

            m_result = url.Substring(startIndex, endIndex - startIndex);
            <span class="kwrd">return</span> SearchResult.Found;
        }


        <span class="rem">// Searches for the SessionID in the path.</span>
        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Extract(<span class="kwrd">object</span> sender, ExtractionEventArgs e)
        {
            <span class="rem">// Finds the match</span>
            Initialize();
            SearchResult result = FindMatch(e.Request.Url);
            e.Success = !m_required || result == SearchResult.Found; ;

            <span class="kwrd">if</span> (result == SearchResult.Found)
            {
                e.WebTest.Context[<span class="kwrd">this</span>.ContextParameterName] = Result;
            }
            <span class="kwrd">else</span>
            {
                <span class="kwrd">if</span> (result == SearchResult.StartsWithNotFound)
                {
                    e.Message = String.Format(CultureInfo.CurrentCulture, <span class="str">"StartsWith not found"</span>);
                }
                <span class="kwrd">else</span>
                {
                    e.Message = String.Format(CultureInfo.CurrentCulture, <span class="str">"EndsWith not found"</span>);
                }
            }
        }

        <span class="rem">// Called in the Recorder Plug-in to retrieve the sessionID string</span>
        <span class="kwrd">public</span> <span class="kwrd">string</span> ExtractSessionID(<span class="kwrd">string</span> url)
        {
            Initialize();
            FindMatch(url);
            <span class="kwrd">return</span> Result;
        }
        <span class="rem">// ************************************************************************</span>
        <span class="rem">// ************************************************************************</span>

        <span class="kwrd">internal</span> <span class="kwrd">string</span> Result
        {
            get { <span class="kwrd">return</span> m_result; }
            set { m_result = <span class="kwrd">value</span>; }
        }

        <span class="rem">// ****************************************************************************</span>
        <span class="rem">// Private Members</span>
        <span class="rem">// ****************************************************************************</span>

        <span class="rem">// Properties for saving the tag and attribute information</span>
        <span class="kwrd">private</span> <span class="kwrd">string</span> m_startsWith;
        <span class="kwrd">private</span> <span class="kwrd">string</span> m_endsWith;
        <span class="kwrd">private</span> Regex m_startsWithRegEx;
        <span class="kwrd">private</span> Regex m_endsWithRegEx;

        <span class="kwrd">private</span> <span class="kwrd">bool</span> m_required = <span class="kwrd">true</span>;
        <span class="kwrd">private</span> <span class="kwrd">bool</span> m_ignoreCase = <span class="kwrd">true</span>;
        <span class="kwrd">private</span> <span class="kwrd">string</span> m_result;
    }
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>If you want to modify the extraction rule for your testing, the generic information to write a custom extraction rule can be found in this <a href="https://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&amp;l=EN-US&amp;k=k(MICROSOFT.VISUALSTUDIO.TESTTOOLS.WEBTESTING.EXTRACTIONRULE);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&amp;rd=true">MSDN page</a>.</p>
<p><strong>Step 4 – Write a Web test recorder plug-in</strong></p>
<p>This plug-in will extract the SessionID from a request url or the redirected page, add an extraction rule created in Step 2 to the request, save the SessionID in a Web test context parameter called “SessionID”, and correlate the SessionID in the recorded Web test requests.</p>
<p>[RecorderPlugin.cs]</p><pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> Microsoft.VisualStudio.TestTools.WebTesting;
<span class="kwrd">using</span> System.Globalization;
<span class="kwrd">using</span> System.Text.RegularExpressions;
<span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> System.Diagnostics;

<span class="kwrd">namespace</span> SampleRecorderPlugin
{
    [DisplayName(<span class="str">"WebTestRecorderPluginSessionIdInPath"</span>)]
    [Description(<span class="str">"Adds a recorder plug-in that retrieves session ID from url"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> RecorderPluginThatExtractsSessionIDInPath : WebTestRecorderPlugin
    {
        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> PostWebTestRecording(<span class="kwrd">object</span> sender, PostWebTestRecordingEventArgs e)
        {
            ExtractSessionIDFromPath extractionRule = <span class="kwrd">new</span> ExtractSessionIDFromPath();
            extractionRule.StartsWith = <span class="str">"/(S("</span>;
            extractionRule.EndsWith = <span class="str">"))/"</span>;
            extractionRule.IgnoreCase = <span class="kwrd">true</span>;

            <span class="kwrd">string</span> sessionID = <span class="kwrd">null</span>;
            <span class="kwrd">bool</span> foundSessionID = <span class="kwrd">false</span>;

            WebTestResultIteration recordedIteration = e.RecordedWebTestResult;
            <span class="kwrd">foreach</span> (WebTestResultUnit resultUnit <span class="kwrd">in</span> recordedIteration.Children)
            {
                WebTestResultPage pageResult = resultUnit <span class="kwrd">as</span> WebTestResultPage;
                <span class="kwrd">if</span> (pageResult != <span class="kwrd">null</span>)
                {
                    WebTestRequestResult finalRequestResult = pageResult.RequestResult;                  
                    <span class="kwrd">string</span> url = pageResult.RequestResult.Request.Url;
                    <span class="rem">// If there were redirects then need to get the last redirected requests</span>
                    <span class="kwrd">if</span> (pageResult.RedirectedPages.Count &gt; 0)
                    {
                        finalRequestResult = pageResult.RedirectedPages[pageResult.RedirectedPages.Count - 1].RequestResult;
                        url = finalRequestResult.Request.Url;
                    }

                    <span class="rem">// Check if there is an session ID in the url path</span>
                    sessionID = extractionRule.ExtractSessionID(url);
                    <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(sessionID))
                    {
                        <span class="kwrd">continue</span>;
                    }

                    <span class="rem">// Get the corresponding request in the Declarative Web test</span>
                    WebTestRequest requestInWebTest =
                            e.RecordedWebTest.GetItem(pageResult.DeclarativeWebTestItemId) <span class="kwrd">as</span> WebTestRequest;

                    <span class="rem">// Add an custom extraction rule to the current request</span>
                    <span class="kwrd">if</span> (requestInWebTest != <span class="kwrd">null</span>)
                    {
                        ExtractionRuleReference extractionRuleReference = <span class="kwrd">new</span> ExtractionRuleReference();
                        extractionRuleReference.Type = <span class="kwrd">typeof</span>(ExtractSessionIDFromPath);
                        extractionRuleReference.Properties.Add(<span class="kwrd">new</span> PluginOrRuleProperty(<span class="str">"StartsWith"</span>, <span class="str">@"/(S("</span>));
                        extractionRuleReference.Properties.Add(<span class="kwrd">new</span> PluginOrRuleProperty(<span class="str">"EndsWith"</span>, <span class="str">@"))/"</span>));
                        extractionRuleReference.Properties.Add(<span class="kwrd">new</span> PluginOrRuleProperty(<span class="str">"IgnoreCase"</span>, <span class="str">"false"</span>));
                        extractionRuleReference.Properties.Add(<span class="kwrd">new</span> PluginOrRuleProperty(<span class="str">"IsRequired"</span>, <span class="str">"true"</span>));
                        extractionRuleReference.ContextParameterName = <span class="str">"SessionID"</span>;
                        requestInWebTest.ExtractionRuleReferences.Add(extractionRuleReference);
                        e.RecordedWebTestModified = <span class="kwrd">true</span>;
                    }

                    foundSessionID = <span class="kwrd">true</span>;
                    <span class="kwrd">break</span>;
                }
            }

            <span class="rem">// replace the session ID with the context parameter</span>
            <span class="kwrd">if</span> (foundSessionID &amp;&amp; !<span class="kwrd">string</span>.IsNullOrEmpty(sessionID))
            {
                <span class="kwrd">for</span> (<span class="kwrd">int</span> i = 0; i &lt; e.RecordedWebTest.Items.Count; i++)
                {
                    <span class="rem">//get the item and see if it is a comment</span>
                    WebTestItem item = e.RecordedWebTest.Items[i];
                    
                    <span class="kwrd">if</span> (item <span class="kwrd">is</span> WebTestRequest)
                    {
                        ((WebTestRequest)item).Url = ((WebTestRequest)item).Url.Replace(sessionID, <span class="str">"{{SessionID}}"</span>);
                    }
                }
            }
        }
    }
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p><strong>Step 5</strong> – Drop the dll to %Program Files%\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\WebTestPlugins</p>
<p>In order to use the extraction rule created in Step 2, you will need to restart Visual Studio and add a reference to the class library to your test project. When you record a new Web test from Visual Studio, a dialog will be popped up and let you enable the RecorderPluginThatExtractsSessionIDInPath. Once the plug-in is enabled, the requests will be automatically correlated.</p>
<p>There is one more step. Since the request url is built dynamically during your run, the last step is to remove the default validation rule in the recorded Web test. Otherwise, the requests will fail due to validation errors. To do this, click on the “Response Time Goal” under Validation Rules, and press the Delete key.</p>]]></content:encoded>
    </item>
    <item>
      <title>Create a Simple Data Collector to Integrate Data into Load Test Analyzer (Tables View)</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/create-a-simple-data-collector-to-integrate-data-into-load-test-analyzer-tables-view</link>
      <pubDate>Thu, 08 Apr 2010 14:12:38 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/04/08/create-a-simple-data-collector-to-integrate-data-into-load-test-analyzer-tables-view/</guid>
      <description><![CDATA[With a custom data collector, you can collect various diagnostic performance information from your...]]></description>
      <content:encoded><![CDATA[<p>With a custom data collector, you can collect various diagnostic performance information from your Web applications. In my previous <a href="https://blogs.msdn.com/yutong/archive/2010/04/08/integrate-data-collector-data-into-load-test-analyzer-tables-view.aspx">post</a>, I have highlighted the key points of integrating custom collector data into Load Test Analyzer. The purpose of this post is to go through the procedure by using a simple collector.</p> <p>One of the questions some forum users asked is ‘Did Load Test insert item records into my table?’ To find out this, I add a load test containing a Web test that purchases orders from a online store (Web application) to my test project. I create a SimpleRowCountDataCollector to collect the counts of the Order table before and after the Load test run. Then I enable the data collector in a .testsettings file, run the Web test in a Load test, and check the row counts after the run completes.</p> <p>Since this sample data collector can be downloaded from <a title="https://teamtestplugins.codeplex.com/" href="https://teamtestplugins.codeplex.com/">https://teamtestplugins.codeplex.com/</a>, I will only outline the steps in this post. If you would like more detailed instructions, read this <a href="https://msdn.microsoft.com/en-us/library/dd286737(v=VS.100).aspx">page</a>.</p> <p><strong><font color="#000080" size="2">Step 1 – Create a Data Collector</font></strong></p> <p><strong>1. Create a new class library</strong></p> <p><strong>2. Add references to the following dlls</strong></p> <p>Microsoft.VisualStudio.QualityTools.ExecutionCommon</p> <p>Microsoft.VisualStudio.QualityTools.Common.dll</p> <p><strong>3. Add RowCountDataCollector.cs</strong></p> <p>Specify the URI and a friendly name for the collector</p><pre class="csharpcode">    [DataCollectorTypeUri(<span class="str">"datacollector://MyCompany/SimpleRowCountDataCollector/1.0"</span>)]
    [DataCollectorFriendlyName(<span class="str">"RowCountDataCollector"</span>, <span class="kwrd">false</span>)]
    [DataCollectorConfigurationEditor(<span class="str">"configurationeditor://Microsoft/GenericEditor/1.0"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> SimpleRowCountDataCollector : DataCollector</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>Below are the brief descriptions of the major functions.</p>
<blockquote>
<p><strong>3.1 Initialize() function</strong></p>
<p>This function does three thing</p>
<p>- Init data members </p>
<p>- Retrieve the collector configuration from the test settings file</p>
<p>- Register the TestCaseStart and TestCaseEnd events </p></blockquote><pre class="csharpcode"><span class="rem">       // Required method called by the testing framework</span>
        <span class="kwrd">public</span> <span class="kwrd">override</span> <span class="kwrd">void</span> Initialize(
            XmlElement configurationElement, 
            DataCollectionEvents events, 
            DataCollectionSink sink, 
            DataCollectionLogger logger, 
            DataCollectionEnvironmentContext environmentContext)
        {
            <span class="rem">// 1. Init members</span> 
            dataEvents = events; <span class="rem">// The test events</span>
            dataLogger = logger; <span class="rem">// The error and warning log</span>
            dataSink = sink;     <span class="rem">// Saves collected data</span>
            
            <span class="rem">// Configuration from the test settings</span>
            configurationSettings = configurationElement;

            <span class="rem">// 2. Read collector configurations from the test settings</span>
            CollectorConfigurationManager configManager = <span class="kwrd">new</span> CollectorConfigurationManager(configurationSettings);
            server = configManager[<span class="str">"server"</span>];
            <span class="kwrd">if</span> (<span class="kwrd">string</span>.IsNullOrEmpty(server))
            {
                server = Environment.MachineName;
            }

            database = configManager[<span class="str">"database"</span>];
            table = configManager[<span class="str">"table"</span>]; 

            <span class="rem">// 3. Register TestCaseStart and TestCaseEnd events for the data collector</span>
            dataEvents.TestCaseStart +=
                <span class="kwrd">new</span> EventHandler&lt;TestCaseStartEventArgs&gt;(OnTestCaseStart);

            dataEvents.TestCaseEnd +=
                <span class="kwrd">new</span> EventHandler&lt;TestCaseEndEventArgs&gt;(OnTestCaseEnd);
        }
</pre>
<blockquote>
<p><strong>3.2</strong> <strong>OnTestCaseStart Event Handler</strong> </p></blockquote>
<blockquote><pre class="csharpcode">This function get the order count from the Order table right before the load test is started. As I mentioned in the previous post, you can log warning or error messages in the code. The message will show up in the Load Test Errors Table.</pre></blockquote><pre class="csharpcode">        <span class="kwrd">public</span> <span class="kwrd">void</span> OnTestCaseStart(<span class="kwrd">object</span> sender, TestCaseEventArgs e)
        {
            // dataLogger.LogWarning(e.Context, <span class="str">"OnTestCaseStart. Time:"</span> + DateTime.Now.ToString());
            rowCountBeforeTestRun = SQLHelper.GetRowCount(server, database, table);
        }</pre>
<blockquote>
<p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>
<strong>3.3 OnTestCaseEnd Event Handler</strong> </p></blockquote>
<blockquote><pre class="csharpcode">This function get the order count from the Order table after the load test is completed, write the tabular data in XML format, and send the file back to client (VS).</pre></blockquote>
<blockquote></blockquote><pre class="csharpcode">       <span class="rem">// Write the counts to a table in XML format</span>
        <span class="kwrd">public</span> <span class="kwrd">void</span> OnTestCaseEnd(<span class="kwrd">object</span> sender, TestCaseEndEventArgs e)
        {
            <span class="rem">// Get the row count after run ends</span>
            rowCountAfterTestRun = SQLHelper.GetRowCount(server, database, table);

            <span class="rem">// create the table to be integrated into load test database</span>
            <span class="kwrd">string</span> filePath = Path.Combine(Path.GetTempPath(), <span class="str">"rowCounts.xml"</span>);
            RowCountXMLWriter.CreateDataTable();
            RowCountXMLWriter.AddDataRow(<span class="str">"BeforeTestStart"</span>, rowCountBeforeTestRun);
            RowCountXMLWriter.AddDataRow(<span class="str">"AfterTestEnd"</span>, rowCountAfterTestRun);
            RowCountXMLWriter.WriteRowCountsToXmlFile(filePath);

            <span class="rem">// Send the file back</span>
            dataSink.SendFileAsync(e.Context, filePath, <span class="kwrd">false</span>);
        }</pre><pre class="csharpcode">One important thing to keep in mind is that only files sent back in OnTestCaseStart and OnTestCaseEnd events can be added to Load Test Tables view in post run.</pre>
<p><strong>4. Add RowCountXMLWriter.cs file</strong></p>
<p>This class creates a DataTable, add rows to the table, and write out the data in XML format</p><pre class="csharpcode"><span class="kwrd">        static</span> DataTable m_dataTable;

        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> CreateDataTable()
        {
            m_dataTable = <span class="kwrd">new</span> DataTable();

            m_dataTable.Locale = CultureInfo.InvariantCulture;
            m_dataTable.Columns.Add(<span class="kwrd">new</span> DataColumn(<span class="str">"Description"</span>, <span class="kwrd">typeof</span>(<span class="kwrd">string</span>)));
            m_dataTable.Columns.Add(<span class="kwrd">new</span> DataColumn(<span class="str">"RowCount"</span>, <span class="kwrd">typeof</span>(Int32)));
        }

        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> AddDataRow(<span class="kwrd">string</span> description, <span class="kwrd">int</span> rowCount)
        {
            DataRow row = m_dataTable.NewRow();
            row[<span class="str">"Description"</span>] = description;
            row[<span class="str">"RowCount"</span>] = rowCount;
            m_dataTable.Rows.Add(row);
        }

        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> WriteRowCountsToXmlFile(<span class="kwrd">string</span> xmlFilePath)
        {
            DataSet dataSet = <span class="kwrd">new</span> DataSet();
            dataSet.Locale = CultureInfo.InvariantCulture;
            dataSet.Tables.Add(m_dataTable);

            <span class="kwrd">using</span> (System.IO.StreamWriter xmlStreamWriter = <span class="kwrd">new</span> System.IO.StreamWriter(xmlFilePath))
            {
                dataSet.WriteXml(xmlStreamWriter, XmlWriteMode.WriteSchema);
                xmlStreamWriter.Close();
            }

            dataSet.Dispose();
        }</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p><strong>5. Add ConfigurationManager.cs </strong></p>
<p>This class reads the data collector settings into a dictionary. Please note, it is written for the format described in Step 6, section &lt;<font color="#008080">DefaultConfiguration&gt;.<br></font><strong></strong></p>
<p><strong>6. Add an App.config file</strong></p>
<p>Note this data collector is configured to use a Generic XML editor. If you want to create your own UI editor, read this <a href="https://msdn.microsoft.com/en-us/library/dd286590(v=VS.100).aspx">MSDN page</a>.</p>
<p>[DataCollectorConfigurationEditor(<span class="str">"configurationeditor://Microsoft/GenericEditor/1.0"</span>)]<br><span class="kwrd">public</span> <span class="kwrd">class</span> SimpleRowCountDataCollector : DataCollector</p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p>[App.config]</p>
<p>&lt;?xml version="1.0" encoding="utf-8"?&gt;<br>&lt;configuration&gt;<br>&nbsp; &lt;configSection&gt;<br>&nbsp;&nbsp;&nbsp; &lt;section<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="DataCollectorConfiguration"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="Microsoft.VisualStudio.QualityTools.Execution.DataCollectorConfigurationSection,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Microsoft.visualStudio.QualityTools.ExecutionCommon,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Version=4.0.0.0, Culture=neutral,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PublicKeyToken=b03f5f7f11d50a3a" /&gt;<br>&nbsp; &lt;/configSection&gt;<br>&nbsp; &lt;DataCollectorConfiguration xmlns="<a href="https://microsoft.com/schemas/VisualStudio/TeamTest/2010&quot;">https://microsoft.com/schemas/VisualStudio/TeamTest/2010"</a>&gt;<br>&nbsp; &lt;DataCollector typeUri="datacollector://MyCompany/SimpleRowCountDataCollector/1.0"&gt;<br>&nbsp;&nbsp;&nbsp; <font color="#008080">&lt;DefaultConfiguration&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name="server" value="YourWebServer" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name="database" value="Store" /&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name="table" value="Order" /&gt;</font><br>&nbsp; <font color="#008080">&lt;/DefaultConfiguration&gt;</font><br>&nbsp; &lt;/DataCollector&gt;<br>&nbsp; &lt;/DataCollectorConfiguration&gt;<br>&lt;/configuration&gt;</p>
<p>This data collector config file allows you to specify three settings, Web server, database, and table name.</p>
<p><strong><font color="#000080" size="2">Step 2 – Install the Data Collector</font></strong></p>
<p>You need to drop a copy of the data collector on every machine you want to collect data. </p>
<p><strong>Setup Requirement: </strong>You must install Agent on these machines.</p>
<p><strong>Files to drop: </strong>RowCountDataCollector.dll, RowCountDataCollector.dll.config</p>
<p><strong>Drop location</strong>: %Program Files%\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\DataCollectors</p>
<p>An example of the setup</p>
<p>Machine1: VS2010 Ultimate, Controller, Agent</p>
<p>Machine2: Web Server, Agent, RowCountDataCollector.</p>
<p>For you to try out the sample collector, you can drop it on your local machine, configure it to point to a table in your local load test database (step 3), and then run the test(step 4).</p>
<p><strong><font color="#000080" size="2">Step 3 – Configure the Data Collector</font></strong></p>
<p>Open the Testsetting file used by your load test run. Click on Data and Diagnostics. Enable the RowCountDataCollector.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="363" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb.png" width="484" border="0"></a> </p>
<p>Click on Configure, it will launch the default editor for you to modify the settings. </p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_6.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_6.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="311" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb_2.png" width="478" border="0"></a> </p>
<p><strong><font color="#000080" size="2">Step 4 – Run your load test and view the data</font></strong></p>
<p>Run your load test view the before/after order counts in post run table.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_4.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="179" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/CreateaSimpleDataCollectortoIntegrateDat_C95E/image_thumb_1.png" width="482" border="0"></a> </p>
<p><strong><font color="#000080" size="2"></font></strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Integrate Data Collector Data into Load Test Analyzer (Tables View)</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/integrate-data-collector-data-into-load-test-analyzer-tables-view</link>
      <pubDate>Thu, 08 Apr 2010 13:54:35 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/04/08/integrate-data-collector-data-into-load-test-analyzer-tables-view/</guid>
      <description><![CDATA[With Microsoft Visual Studio 2010 Ultimate, you can write a custom Data Collector to collect...]]></description>
      <content:encoded><![CDATA[<p>With Microsoft Visual Studio 2010 Ultimate, you can write a custom <a href="https://msdn.microsoft.com/en-us/library/dd286737(v=VS.100).aspx">Data Collector</a> to collect diagnostic data on Agents or machines that are part of System Under Test. The data collected can be files, high-level summary statistics, or server activity logs from the database on a Web server. These data can be integrated into the Load Test Database and viewed in the Load Test Analyzer when test completes.&nbsp; Together with the information collected by a Load Test, they can be used to diagnose performance issues in your Web applications.</p> <p>Given a very simple example here, I collected the row count of my Order table in the Web server’s database before and after a load test run. As shown in the following screenshot, the counts were displayed in a table in post run.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="184" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb.png" width="500" border="0"></a> </p> <p>To implement this, only three major steps are involved. </p> <p>Step 1 – Create a data collector. </p> <p>Step 2 – Install the data collector. </p> <p>Step 3 – Enable/configure the custom data collector in the test project.</p> <p>I will go through the steps to create a sample data collector in a separate post. In this post, I will highlight the points closely related to Load test that you should know before getting started.</p> <p><strong>1. Supported Data Format – Tabular data in XML</strong></p> <p>In order to integrate your report into Load Test Analyzer, the data collector needs to write the report data to a table in XML format.</p> <p><strong>2. Supported data types in the XML table.</strong></p> <blockquote> <p>Bit  <p>Byte[]  <p>Int16, Int32, Int64  <p>double, float  <p>String  <p>DateTime</p></blockquote> <p><strong>3. Data collector basics</strong></p> <blockquote> <p><strong>3.1 Data Collector Events</strong></p> <p>Your data collector can register events in the following table to write log messages and send files back to the client (VS).</p> <table cellspacing="0" cellpadding="2" width="879" border="0"> <tbody> <tr> <td valign="top" width="144"><strong>Event</strong></td> <td valign="top" width="220"><strong>Description</strong></td> <td valign="top" width="513"><strong>Notes</strong></td></tr> <tr> <td valign="top" width="144"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.sessionstart(v=VS.100).aspx">SessionStart</a></td> <td valign="top" width="220">Start of your test run</td> <td valign="top" width="513">You test run may contain several test types, e.g. one Load test and five Unit test. This event will be fired once for the entire run.</td></tr> <tr> <td valign="top" width="144"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.sessionend(v=VS.100).aspx">SessionEnd</a></td> <td valign="top" width="220">End of your test run</td> <td valign="top" width="513">&nbsp;</td></tr> <tr> <td valign="top" width="144"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.testcasestart(v=VS.100).aspx">TestCaseStart</a></td> <td valign="top" width="220">Start of each test in the test run</td> <td valign="top" width="513">If you test run contains only one Load Test, this event will be fired once when the Load test is started.</td></tr> <tr> <td valign="top" width="144"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.testcaseend(v=VS.100).aspx">TestCaseEnd</a></td> <td valign="top" width="220">End of each test in the test run</td> <td valign="top" width="513">If you test run contains only one Load Test, this event will be fired once when the Load test is complete.</td></tr></tbody></table></blockquote> <blockquote> <p>Remember, ONLY log/data files sent back through the TestCaseStart and TestCaseEnd events can be integrated into the Load Test database.</p> <p>Log/data files sent back through the SessionStart and SessionEnd events are listed in the Run Results Summary window. Under section Collected Files.</p></blockquote> <blockquote> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_4.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="223" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb_1.png" width="332" border="0"></a> </p> <p><strong>3.2 Data Collector Events</strong> <strong>Logs</strong></p> <p>You can log warning/error messages in the following events</p> <table cellspacing="0" cellpadding="2" width="692" border="0"> <tbody> <tr> <td valign="top" width="182"><strong>Event </strong></td> <td valign="top" width="508"><strong>Description</strong></td></tr> <tr> <td valign="top" width="182"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.sessionstart(v=VS.100).aspx">SessionStart</a></td> <td valign="top" width="508">Log messages will be displayed in the Results Summary window</td></tr> <tr> <td valign="top" width="182"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.sessionend(v=VS.100).aspx">SessionEnd</a></td> <td valign="top" width="508">Log messages will be displayed in the Results Summary window</td></tr> <tr> <td valign="top" width="182"><a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.execution.datacollectionevents.testcasestart(v=VS.100).aspx">TestCaseStart</a></td> <td valign="top" width="508">Log messages will be displayed in the Errors table in Load Test Analyzer </td></tr></tbody></table> <p><strong>3.3 Data Collector configuration</strong> </p> <p>If any configuration is required for the collector, you need to create an App.config file. </p> <p>Data collector can be enabled through the Test Settings dialog as shown in the below screenshot. </p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_10.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_10.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="357" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/IntegrateDataCollectorDataintoLoadTestAn_8ADE/image_thumb_4.png" width="475" border="0"></a> </p> <p>Data collector can be configured if you click on the Configure button. Here you have two choices, you can create a <a href="https://msdn.microsoft.com/en-us/library/dd286590(v=VS.100).aspx">custom UI editor</a>, or you can use a generic XML editor and just do text editing. The later will be covered in <a href="https://blogs.msdn.com/yutong/archive/2010/04/08/create-a-simple-data-collector-to-integrate-data-into-load-test-analyzer-tables-view.aspx">Create a Simple Data Collector to Integrate Data into Load Test Analyzer</a>. </p></blockquote> <p>As I mentioned in the beginning, what I listed above is just a high-level summary for you to get started. After going through these briefly, you can try the sample collector in my <a href="https://blogs.msdn.com/yutong/archive/2010/04/08/create-a-simple-data-collector-to-integrate-data-into-load-test-analyzer-tables-view.aspx">post</a> and start to write your own. For more information on Custom Data Collectors, please read this <a href="https://msdn.microsoft.com/en-us/library/dd286727(v=VS.100).aspx">MSDN page</a> for details.</p> <p> <p><a href="file:///C:/Users/yutong/AppData/Local/Temp/1/WindowsLiveWriter1286139640/supfiles18F6C959/image13.png"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Load Test Plug-in – Simulate Repeated Peak Load Modeling</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/load-test-plug-in-simulate-repeated-peak-load-modeling</link>
      <pubDate>Fri, 02 Apr 2010 12:30:27 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/04/02/load-test-plug-in-simulate-repeated-peak-load-modeling/</guid>
      <description><![CDATA[In my previous posts, I have shown how to simulate repeated custom user load pattern groups. Here is...]]></description>
      <content:encoded><![CDATA[<p>In my previous <a href="https://blogs.msdn.com/yutong/archive/2010/03/15/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-2.aspx">posts</a>, I have shown how to simulate repeated custom user load pattern groups. Here is another plug-in sample to simulate the PeakLoad modeling, i.e. VallyLoad-StepUp-PeakLoad-StepDown. In this plug-in, all the configurations can be passed in through the Load Test Plug-in properties. As shown in the below screenshot, it simulates a peak load of 800 users every 3 minutes.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="301" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_thumb.png" width="524" border="0"></a> </p> <p><strong>Step 1 – </strong><strong>Create CustomLoadProfiles library </strong></p> <p>You can copy the code in this <a href="https://blogs.msdn.com/yutong/archive/2010/03/15/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-1.aspx">post</a> and build the class library. [The sample code can be downloaded from <a href="https://teamtestplugins.codeplex.com/">codeplex</a>.]</p> <p><strong>Step 2 – Add a reference to class library CustomLoadProfiles in the test project</strong></p> <p><strong>Step 3 – Add the PeakLoadModelingPlugin to the test project</strong></p> <p>[PeakLoadModelingPlugin<strong>.</strong>cs] [The sample code can be downloaded from <a href="https://teamtestplugins.codeplex.com/">codeplex</a>.]</p><pre class="csharpcode"><span class="kwrd">using</span> System;
<span class="kwrd">using</span> System.IO;
<span class="kwrd">using</span> System.Collections;
<span class="kwrd">using</span> System.Collections.Generic;
<span class="kwrd">using</span> System.ComponentModel;
<span class="kwrd">using</span> Microsoft.VisualStudio.TestTools.LoadTesting;
<span class="kwrd">using</span> CustomLoadProfiles;

<span class="kwrd">namespace</span> TestProject1
{
    [Description(<span class="str">"This plug-in simulates the Peak user load Pattern every 3 minutes"</span>)]
    <span class="kwrd">public</span> <span class="kwrd">class</span> PeakLoadModelingPlugin : ILoadTestPlugin
    {     
        <span class="kwrd">public</span> <span class="kwrd">void</span> Initialize(LoadTest loadTest)
        {
            m_loadTest = loadTest;
            m_profileManager = <span class="kwrd">new</span> LoadProfileManager();

            <span class="rem">// The heartbeat event will be fired every second, it can be used to adjust the user load</span>
            m_loadTest.Heartbeat += <span class="kwrd">new</span> EventHandler&lt;HeartbeatEventArgs&gt;(m_loadTest_Heartbeat);

            <span class="rem">// Create the custom load pattern based on the configurations passed through the plug-in properties</span>
            CreateLoadProfileGroups();
        }

        <span class="rem">// Create a custom user load profile group: Valley-StepUp-Peak-StepDown</span>
        <span class="kwrd">void</span> CreateLoadProfileGroups()
        {           
            <span class="rem">// Create the custom load pattern group</span>
            <span class="rem">// Calculate the duration</span>
            <span class="rem">// If the RepeatCount for the Peak Load pattern is not specified, check the PercentageOfDuration, and calculate</span>
            <span class="kwrd">int</span> patternDuration = 0;
            <span class="kwrd">if</span> (RepeatCount == 0)
            {
                <span class="kwrd">double</span> patternDurationInDouble = m_loadTest.RunSettings.RunDuration * PercentageOfDuration / 100;
                patternDuration = (Int32)Math.Ceiling(patternDurationInDouble);
            }
            <span class="kwrd">else</span>
            {
                patternDuration = (ValleyTime + RampUpTime + PeakTime + RampDownTime) * RepeatCount;
            }

            LoadProfileGroup profileGroup = <span class="kwrd">new</span> LoadProfileGroup(<span class="str">"Valley-StepUp-Peak-StepDown"</span>, patternDuration);

            <span class="rem">// Add the load profiles to a group</span>
            <span class="rem">// The step duration 5 seconds will be used to simulate the step up/down</span>
            <span class="kwrd">int</span> stepDuration = 5;

            <span class="rem">// 1. Simulate the ValleyLoad for a duration of ValleyTime</span>
            profileGroup.AddProfile(<span class="kwrd">new</span> ConstLoadWrapper(ValleyLoad, ValleyTime));

            <span class="rem">// 2. Simulate step up load - step up from ValleyLoad to PeakLoad in the RampUpTime window</span>
            <span class="kwrd">double</span> stepCount = Math.Round((<span class="kwrd">double</span>)(PeakLoad - ValleyLoad) * stepDuration / RampUpTime);
            profileGroup.AddProfile(<span class="kwrd">new</span> StepLoadWrapper(ValleyLoad, ValleyLoad, PeakLoad, (<span class="kwrd">int</span>)stepCount, stepDuration, 0, RampUpTime));

            <span class="rem">// 3. Simulate Peakload for PeakTime</span>
            profileGroup.AddProfile(<span class="kwrd">new</span> ConstLoadWrapper(PeakLoad, PeakTime));

            <span class="rem">// 4. Simulate step down load - step down from PeakLoad to ValleyLoad in the RampDownTime window</span>
            stepCount = Math.Round((<span class="kwrd">double</span>)(PeakLoad - ValleyLoad) * stepDuration / RampDownTime);
            CustomLoadWrapper profileWrapper = <span class="kwrd">new</span> CustomLoadWrapper(RampDownTime);
            profileWrapper.Profile = <span class="kwrd">new</span> LoadTestStepDownLoadProfile(PeakLoad, ValleyLoad, PeakLoad, (<span class="kwrd">int</span>)stepCount, stepDuration);
            profileGroup.AddProfile(profileWrapper);

            <span class="rem">// Add the profile group </span>
            m_profileManager.ProfileGroups.Add(profileGroup);

            <span class="rem">// Tell the profile manager that we want to simulate the custom pattern right after test run is started</span>
            m_profileManager.SetStartEndTimeForProfileGroups(0);
        }

        <span class="rem">// The following heartbeat event will be fired every second, it can be used to adjust the user load</span>
        <span class="kwrd">void</span> m_loadTest_Heartbeat(<span class="kwrd">object</span> sender, HeartbeatEventArgs e)
        {
            <span class="kwrd">if</span> (!e.IsWarmupComplete)
            {
                <span class="kwrd">return</span>;
            }

            <span class="rem">// Get the load profile to be applied for the event</span>
            LoadTestLoadProfile profile = m_profileManager.GetCurrentLoadProfile(e.ElapsedSeconds, m_loadTest.Scenarios[0].CurrentLoad);
            <span class="kwrd">if</span> (profile != <span class="kwrd">null</span>)
            {
                m_loadTest.Scenarios[0].LoadProfile = profile;
            }
        }

        <span class="preproc">#region</span> Load Profile Configurations
        [DefaultValue(20)]
        [Description(<span class="str">"The Valley Load"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> ValleyLoad
        {
            get { <span class="kwrd">return</span> m_valleyLoad; }
            set { m_valleyLoad = <span class="kwrd">value</span>; }
        }

        [DefaultValue(20)]
        [Description(<span class="str">"The Peak Load"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> PeakLoad
        {
            get { <span class="kwrd">return</span> m_peakLoad; }
            set { m_peakLoad = <span class="kwrd">value</span>; }
        }

        [DefaultValue(60)]
        [Description(<span class="str">"The amount of time that ValleyLoad will be simulated"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> ValleyTime
        {
            get { <span class="kwrd">return</span> m_valleyTime; }
            set { m_valleyTime = <span class="kwrd">value</span>; }
        }

        [DefaultValue(60)]
        [Description(<span class="str">"The amount of time that PeakLoad will be simulated"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> PeakTime
        {
            get { <span class="kwrd">return</span> m_peakTime; }
            set { m_peakTime = <span class="kwrd">value</span>; }
        }

        [DefaultValue(20)]
        [Description(<span class="str">"The amount of time to ramp up from ValleyLoad to PeakLoad"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> RampUpTime
        {
            get { <span class="kwrd">return</span> m_rampUpTime; }
            set { m_rampUpTime = <span class="kwrd">value</span>; }
        }

        [DefaultValue(20)]
        [Description(<span class="str">"The amount of time to step down from PeakLoad to ValleyLoad"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> RampDownTime
        {
            get { <span class="kwrd">return</span> m_rampDownTime; }
            set { m_rampDownTime = <span class="kwrd">value</span>; }
        }

        [DefaultValue(20)]
        [Description(<span class="str">"The number of times to repeat this pattern"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> RepeatCount
        {
            get { <span class="kwrd">return</span> m_repeatCount; }
            set { m_repeatCount = <span class="kwrd">value</span>; }
        }

        [DefaultValue(100)]
        [Description(<span class="str">"When the RepeatCount is 0. This property specifies the % of the duration that the pattern will be simulated. Default to entire duration"</span>)]
        <span class="kwrd">public</span> <span class="kwrd">int</span> PercentageOfDuration
        {
            get { <span class="kwrd">return</span> m_percentageOfDuration; }
            set { m_percentageOfDuration = <span class="kwrd">value</span>; }
        }

        <span class="preproc">#endregion</span>

        <span class="kwrd">private</span> LoadTest m_loadTest;
        <span class="kwrd">private</span> LoadProfileManager m_profileManager;

        <span class="kwrd">private</span> <span class="kwrd">int</span> m_valleyLoad;
        <span class="kwrd">private</span> <span class="kwrd">int</span> m_peakLoad;

        <span class="kwrd">private</span> <span class="kwrd">int</span> m_valleyTime;
        <span class="kwrd">private</span> <span class="kwrd">int</span> m_peakTime;
        <span class="kwrd">private</span> <span class="kwrd">int</span> m_rampUpTime;
        <span class="kwrd">private</span> <span class="kwrd">int</span> m_rampDownTime;

        <span class="kwrd">private</span> <span class="kwrd">int</span> m_repeatCount;
        <span class="kwrd">private</span> <span class="kwrd">int</span> m_percentageOfDuration;
    }
}
</pre>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p><strong>Step 4 – Configure the modeling properties</strong></p>
<style type="text/css">.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
</style>

<p></p>
<p>Add the PeakLoadModelingPlugin to your load test. The modeling properties can be configured through the Add Load Test Plug-in dialog.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_4.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="385" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulatePeakLoadModeling_CFBA/image_thumb_1.png" width="556" border="0"></a></p>]]></content:encoded>
    </item>
    <item>
      <title>Web/Load Test Automation</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/webload-test-automation</link>
      <pubDate>Fri, 26 Mar 2010 19:37:00 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/03/26/webload-test-automation/</guid>
      <description><![CDATA[You can use MsTest.exe to&nbsp;execute Unit, Web, and Load tests from a command line. For more...]]></description>
      <content:encoded><![CDATA[<P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">You can use MsTest.exe to&nbsp;execute Unit, Web, and Load tests from a command line. For more information, please read <A title=https://msdn.microsoft.com/en-us/library/ms182486.aspx href="https://msdn.microsoft.com/en-us/library/ms182486.aspx">https://msdn.microsoft.com/en-us/library/ms182486.aspx</A>. Sean Lumley also blogged the details&nbsp;on how to <A class="" href="https://blogs.msdn.com/slumley/pages/running-web-and-load-tests-from-the-command-line.aspx" mce_href="https://blogs.msdn.com/slumley/pages/running-web-and-load-tests-from-the-command-line.aspx">run Web, coded Web, and load tests through&nbsp;mstest.exe</A>. This post&nbsp;will show you by&nbsp;creating a wrapper of the mstest process, you can automate Web/Load tests in code.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN></P>
<P><STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Step 1&nbsp;– Create a RunHelper class to wrap up the MsTest.exe process</SPAN></STRONG></P>
<P><STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN></STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">This helper class constructs the command-line argument list for MsTest.exe, starts the MsTest process to run your tests, and logs the output. You can modify the </SPAN><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">MSTestArgumentsFormat </SPAN><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">to use different set of mstest switches.<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; COLOR: blue; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">public</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: #2b91af">RunHelper</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: blue">string</SPAN> VSPath = <SPAN style="COLOR: #2b91af">Path</SPAN>.Combine(<SPAN style="COLOR: #2b91af">Environment</SPAN>.GetEnvironmentVariable(<SPAN style="COLOR: #a31515">"ProgramFiles"</SPAN>),<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"Microsoft Visual Studio 10.0\Common7\IDE"</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: blue">string</SPAN> MSTestPath = <SPAN style="COLOR: #2b91af">Path</SPAN>.Combine(VSPath, <SPAN style="COLOR: #a31515">"MSTest.exe"</SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: blue">string</SPAN> MSTestArgumentsFormat =<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">string</SPAN>.Format(<SPAN style="COLOR: #2b91af">CultureInfo</SPAN>.InvariantCulture,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">"/testcontainer:{0} /testsettings:{1} /resultsfile:{2}"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"{0}"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"{1}"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"{2}"</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">void</SPAN> RunMSTest(<SPAN style="COLOR: blue">string</SPAN> container, <SPAN style="COLOR: blue">string</SPAN> testsettings, <SPAN style="COLOR: blue">string</SPAN> resultsFileName, <SPAN style="COLOR: blue">int</SPAN> timeout)<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: green">// Build the command line argument</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">string</SPAN> commandLineArguments = <SPAN style="COLOR: blue">string</SPAN>.Format(<SPAN style="COLOR: #2b91af">CultureInfo</SPAN>.InvariantCulture,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>MSTestArgumentsFormat,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>container,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>testsettings,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SPAN>resultsFileName<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">ProcessStartInfo</SPAN> startInfo =<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">new</SPAN> <SPAN style="COLOR: #2b91af">ProcessStartInfo</SPAN>(<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>MSTestPath,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>commandLineArguments<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>startInfo.CreateNoWindow = <SPAN style="COLOR: blue">true</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>startInfo.UseShellExecute = <SPAN style="COLOR: blue">false</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>startInfo.RedirectStandardError = <SPAN style="COLOR: blue">true</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>startInfo.RedirectStandardOutput = <SPAN style="COLOR: blue">true</SPAN>;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>startInfo.WindowStyle = <SPAN style="COLOR: #2b91af">ProcessWindowStyle</SPAN>.Hidden;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: green">// Create and run the process</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Process</SPAN> mstestProcess = <SPAN style="COLOR: #2b91af">Process</SPAN>.Start(startInfo);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>mstestProcess.StartInfo = startInfo;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>mstestProcess.Start();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">string</SPAN> stdout = mstestProcess.StandardOutput.ReadToEnd();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">string</SPAN> stderr = mstestProcess.StandardError.ReadToEnd();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>mstestProcess.WaitForExit(timeout);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">int</SPAN> exitCode = mstestProcess.ExitCode;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>mstestProcess.Close();<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: green">// log the output</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Console</SPAN>.WriteLine(<SPAN style="COLOR: #a31515">"{0} {1}"</SPAN>, MSTestPath, commandLineArguments);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Console</SPAN>.WriteLine(<SPAN style="COLOR: #a31515">"exitcode: {0}"</SPAN>, exitCode);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Console</SPAN>.WriteLine(<SPAN style="COLOR: #a31515">"stdout: {0}"</SPAN>, stdout);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #2b91af">Console</SPAN>.WriteLine(<SPAN style="COLOR: #a31515">"stderr: {0}"</SPAN>, stderr);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">}<o:p></o:p></SPAN></P>
<P><STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Step 2&nbsp;– Create a TestRunner class to run all the tests<o:p></o:p></SPAN></STRONG></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I added three simple functions to the following helper class for running Web, coded Web, and load tests. Basically, you can add your logics to the methods to use different testsettings files in different test environments, e.g. local vs remote, 32-bit mode vs 64-bit mode, running tests with or without data collection, and running tests using different controllers.<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; COLOR: blue; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; COLOR: blue; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">public</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"> <SPAN style="COLOR: blue">class</SPAN> <SPAN style="COLOR: #2b91af">TestRunner</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: green">// Specify a proper timeout for you testing</SPAN><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">readonly</SPAN> <SPAN style="COLOR: blue">int</SPAN> TIMEOUT = 120000;<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">void</SPAN> RunWebTests()<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>RunHelper.RunMSTest(<SPAN style="COLOR: #a31515">@"e:\webtest1.webtest"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\local.testsettings"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\webtest1Result.trx"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>TIMEOUT);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">void</SPAN> RunCodedWebTests()<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>RunHelper.RunMSTest(<SPAN style="COLOR: #a31515">@"e:\codedTests.dll"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\remote.testsettings"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\CodedWebtestResults.trx"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>TIMEOUT);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: blue">static</SPAN> <SPAN style="COLOR: blue">public</SPAN> <SPAN style="COLOR: blue">void</SPAN> RunLoadTests()<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>{<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>RunHelper.RunMSTest(<SPAN style="COLOR: #a31515">@"e:\Stress1.loadtest"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\64Bit.testsettings"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN><SPAN style="COLOR: #a31515">@"e:\Stress1Result.trx"</SPAN>,<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>TIMEOUT);<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>}<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="mso-font-kerning: 0pt"><FONT size=3><FONT face="Times New Roman">}<o:p></o:p></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Step 3&nbsp;–&nbsp;Run the tests from&nbsp;a console application</SPAN></STRONG><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> </SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">The last step is to create a console application, add classes created in step 1 and 2, and call methods in the TestRunner class. In the following code, it just calls the TestRunner to run all the Web tests.</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p></o:p></SPAN>&nbsp;</P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif><FONT size=1><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; COLOR: blue; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas">static</SPAN><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"> <SPAN style="COLOR: blue">void</SPAN> <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><st1:place w:st="on">Main</st1:place>(<SPAN style="COLOR: blue">string</SPAN>[] args)<o:p></o:p></SPAN></FONT></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><FONT face=arial,helvetica,sans-serif><FONT size=1>{<o:p></o:p></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><FONT face=arial,helvetica,sans-serif><FONT size=1><SPAN style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN></FONT></FONT><SPAN style="COLOR: #2b91af">TestRunner</SPAN>.RunWebTests();<FONT face=arial,helvetica,sans-serif><FONT size=1><o:p></o:p></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><FONT face=arial,helvetica,sans-serif><FONT size=1>}<o:p></o:p></FONT></FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 9.5pt; FONT-FAMILY: Consolas; mso-font-kerning: 0pt; mso-bidi-font-family: Consolas"><o:p>&nbsp;</o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">And the output is</SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"></SPAN>&nbsp;</P><SPAN lang=EN-US style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif size=1>E:\school\TestProject1\ConsoleApplication1\bin\Debug&gt;ConsoleApplication1.exe<BR>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\MSTest.exe /testcontainer:e:\webtest<BR>1.webtest /testsettings:e:\local.testsettings /resultsfile:e:\webtest1Result.trx<BR>exitcode: 0<BR>stdout: Microsoft (R) Test Execution Command Line Tool Version 10.0.30208.0<BR>Copyright (c) Microsoft Corporation. All rights reserved.</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif size=1>Loading e:\local.testsettings...<BR>Loading e:\webtest1.webtest...<BR>Starting execution...</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif size=1>Results&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Top Level Tests<BR>-------&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------<BR>Passed&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e:\webtest1.webtest<BR>1/1 test(s) Passed</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif size=1>Summary<BR>-------<BR>Test Run Completed.<BR>&nbsp; Passed&nbsp; 1<BR>&nbsp; ---------<BR>&nbsp; Total&nbsp;&nbsp; 1<BR>Results file:&nbsp; e:\webtest1Result.trx<BR>Test Settings: Perf Run</FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align=left><FONT face=arial,helvetica,sans-serif size=1>stderr:</FONT></SPAN></P>]]></content:encoded>
    </item>
    <item>
      <title>Load Test Plug-in – Simulate Multiple and Repeated User Load Patterns (Step 2-2)</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-2</link>
      <pubDate>Mon, 15 Mar 2010 19:02:10 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/03/15/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-2/</guid>
      <description><![CDATA[With the Load Test Editor, you can configure one load test profile for a given scenario. However, in...]]></description>
      <content:encoded><![CDATA[<p>With the Load Test Editor, you can configure one load test profile for a given scenario. However, in the real-world testing, you may want to observe the performance of your applications / system under tests under different load patterns. And this can be achieved by writing your custom load profiles management classes and a load test plug-in. (Sample code included)</p> <p>For example, in the below graph for a 30-min Load run, several load profiles, including const, stepUp, stepDown, CustomSinWave, are simulated about every 7.5 minutes.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleand_FBFB/image_4.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleand_FBFB/image_4.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="246" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleand_FBFB/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleand_FBFB/image_thumb_1.png" width="635" border="0"></a> </p> <p>This post will show you step by step on how to </p> <p>1) Create customize user load profiles besides the existing LoadTestConstLoadProfile, LoadTestStepLoadProfile, and LoadTestGoalBasedLoadProfile (Covered in Step 1)</p> <p>2) Simulate multiple and repeated user load patterns in a load test run (Covered in Step 2)</p> <p>In the previous blog post, we have completed Step 2-1, i.e. Creating CustomLoadProfiles library. In this post, we will complete the load test plug-in code.</p> <p><strong>Step2 – Create Load Test Plug-in To Simulate User Load Patterns</strong></p> <p>The changes to enable multi- load profiles are highlighted as below </p> <p><strong>1) Plug-in data members</strong>  <p>Add a private member of type LoadProfileManager. It is used to manage the profile groups, and return the load test profile at run time.  <p><strong>2) Initialize()</strong>  <p>Add a Load Test heartbeat event handler to apply the user load change.  <p>Add the profile groups you want to simulate. To simulate more than one load patterns, you can add multiple profiles to a given load test, e.g. const load 40 for 60 seconds followed by user load oscillation between (800, 1000) for 240 seconds. To simulate repeated load pattern group, you can specify the duration of the pattern group. During the load test run, the plug-in will cycle through the load profiles and apply the load accordingly.  <p><strong>3) Load Test heartbeat event handler</strong>  <p>Get the Load profile to be applied for the current heart beat event.  <p><strong>[LoadTestPlugin.cs]</strong> For graphical view, see the screenshot at the beginning of this post.  <p>using System;<br>using System.IO;<br>using System.Reflection;<br>using System.Collections;<br>using System.Collections.Generic;<br>using Microsoft.VisualStudio.TestTools.LoadTesting;<br>using CustomLoadProfiles;  <p>namespace TestProject1<br>{<br>&nbsp;&nbsp;&nbsp; // How to use this class? <br>&nbsp;&nbsp;&nbsp; // This is a regular load test plugin class<br>&nbsp;&nbsp;&nbsp; // InitLoadProfileGroups() - You specify the pattern groups you want to simulate // m_loadTest_Heartbeat event handler() - <br>&nbsp;&nbsp;&nbsp; // CustomLoadProfiles.cs - add more custom load profiles to this file </p> <p>&nbsp;&nbsp;&nbsp; public class MultiLoadPatternsPlugin : ILoadTestPlugin<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTest m_loadTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadProfileManager m_profileManager;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void Initialize(LoadTest loadTest)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_loadTest = loadTest;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileManager = new LoadProfileManager();  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The heartbeat event will be fired every second, it can be used to adjust the user load<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_loadTest.Heartbeat += new EventHandler&lt;HeartbeatEventArgs&gt;(m_loadTest_Heartbeat);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add the pattern groups you want to simulate<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitLoadProfileGroups();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void InitLoadProfileGroups()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add profiles to a group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Simulate a custom user load pattern for 30 mins<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadProfileGroup profileGroup = new LoadProfileGroup("Custom1", 2400);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Simulate Const load 50 for 60 seconds<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileGroup.AddProfile(new ConstLoadWrapper(50, 60));  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add custom load profile - simulate sin curve load <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CustomLoadWrapper profileWrapper = new CustomLoadWrapper(240);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper.Profile = new LoadTestSinLoadProfile(60, 30, 30, 1, 5);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileGroup.AddProfile(profileWrapper);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Simulate step up load - step up 30 users every 5 seconds for 40 seconds <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileGroup.AddProfile(new StepLoadWrapper(60, 0, 300, 30, 5, 0, 40));  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Simulate user load oscillation between [280, 320] for 60 seconds<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper = new CustomLoadWrapper(60);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper.Profile = new LoadTestSinLoadProfile(300, 20, 30, 2, 5);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileGroup.AddProfile(profileWrapper);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Step down user load - step down 30 users every 5 seconds for 40 seconds <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper = new CustomLoadWrapper(40);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper.Profile = new LoadTestStepDownLoadProfile(300, 60, 300, 30, 5);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileGroup.AddProfile(profileWrapper);  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Add the profile group <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileManager.ProfileGroups.Add(profileGroup);</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileManager.SetStartEndTimeForProfileGroups(0);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The following heartbeat event will be fired every second, it can be used to adjust the user load<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void m_loadTest_Heartbeat(object sender, HeartbeatEventArgs e)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!e.IsWarmupComplete)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get the load profile to be applied for the event<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestLoadProfile profile = m_profileManager.GetCurrentLoadProfile(e.ElapsedSeconds, m_loadTest.Scenarios[0].CurrentLoad);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (profile != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_loadTest.Scenarios[0].LoadProfile = profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}  ]]></content:encoded>
    </item>
    <item>
      <title>Load Test Plug-in - Simulate Multiple and Repeated User Load Patterns (Step 2-1)</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-1</link>
      <pubDate>Mon, 15 Mar 2010 19:01:12 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/03/15/load-test-plug-in-simulate-multiple-and-repeated-user-load-patterns-step-2-1/</guid>
      <description><![CDATA[With the Load Test Editor, you can configure one load test profile for a given scenario. However, in...]]></description>
      <content:encoded><![CDATA[<p>With the Load Test Editor, you can configure one load test profile for a given scenario. However, in the real-world testing, you may want to observe the performance of your applications / system under tests under different load patterns. And this can be achieved by writing custom load profile management classes and a load test plug-in. (Sample code included and available for <a href="https://teamtestplugins.codeplex.com/">downloading</a> from codeplex)</p> <p>For example, in the below graph for a 30-min Load run, several load profiles, including const, stepUp, stepDown, CustomSinWave, are simulated about every 7.5 minutes.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleandRepeate_F92A/image_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleandRepeate_F92A/image_2.png"><img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="238" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleandRepeate_F92A/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/LoadTestPluginSimulateMultipleandRepeate_F92A/image_thumb.png" width="594" border="0"></a> </p> <p>This post will show you step by step on how to </p> <p>1) Create customized user load profiles and profile group management classes (Covered in Step 1)</p> <p>2) Simulate multiple and repeated user load patterns in a load test run (Covered in Step 2)</p> <p><strong>Step1 – Create CustomLoadProfiles Library</strong></p> <p>In the sample code, I have implemented two *.cs files to manage the custom load patterns.</p> <p>CustomLoadProfiles.cs – This file contains </p> <blockquote> <p>-- Two custom Step load profiles. One for linear stepping down and the other for simulating user load oscillations with a Math.Sin() curve.</p> <p>-- CustomLoadProfile wrapper classes for existing and customized LoadTestLoadProfiles. A wrapper class allows you to specify the duration you want to simulate the user pattern.</p></blockquote> <p>LoadProfileManager.cs – This files contains two classes.</p> <blockquote> <p>-- LoadProfileGroup class </p> <p>&nbsp;&nbsp; The class contains all the profiles you want to simulate. For example, a const load profile for 60 seconds, a sin wave for 120 seconds, and a step down load for 40 seconds.&nbsp; You&nbsp; can specify the duration of the profile group. For example, if the duration of this group is set to 20 min. The Load test plug-in will cycle through all the load profiles added to this group till the end of 20th minute if the duration of the load test is longer than 20 mins.</p> <p>-- LoadProfileGroupManagers class</p> <p>&nbsp;&nbsp; It allows you to simulate multiple pattern groups in your run. It will find the right load test profile to be applied at run time.</p></blockquote> <p><strong>1) Create a class library and add the reference to the Microsoft.VisualStudio.TestTools.LoadTesting.</strong></p> <p><strong>2) Create the custom load profiles. (CustomLoadProfiles.cs)</strong></p> <p>Details on how to create custom load profiles can be found in <a title="https://blogs.msdn.com/billbar/pages/load-test-api-enhancements-in-vsts-2008-sp1-beta.aspx" href="https://blogs.msdn.com/billbar/pages/load-test-api-enhancements-in-vsts-2008-sp1-beta.aspx">https://blogs.msdn.com/billbar/pages/load-test-api-enhancements-in-vsts-2008-sp1-beta.aspx</a>.</p> <p>Add the following code to your library and add your own custom load profiles.&nbsp; </p> <p>using System;<br>using System.IO;<br>using System.Collections;<br>using System.Collections.Generic;<br>using Microsoft.VisualStudio.TestTools.LoadTesting;  <p>// CustomLoadProfiles.cs<br>// Add more cutom profiles in this file<br>namespace CustomLoadProfiles<br>{<br>&nbsp;&nbsp;&nbsp; #region Custom LoadProfile  <p>&nbsp;&nbsp;&nbsp; // The base class for customized load profile<br>&nbsp;&nbsp;&nbsp; // Add different validations as needed<br>&nbsp;&nbsp;&nbsp; [Serializable]<br>&nbsp;&nbsp;&nbsp; public class CustomLoadProfile : LoadTestStepLoadProfile<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_currentUserLoad;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomLoadProfile()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_currentUserLoad = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int CurrentUserLoad<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_currentUserLoad; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_currentUserLoad = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override int GetLoad(int elaspsedTimeInProfile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override void&nbsp; Validate() {}<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; // Custom step up/down - Sin wave simulation<br>&nbsp;&nbsp;&nbsp; // y(t) = A * sin(2* PI * f * t / unitTimeInterval)<br>&nbsp;&nbsp;&nbsp; // t - time<br>&nbsp;&nbsp;&nbsp; // f - number of oscillations occur in an unit time interval<br>&nbsp;&nbsp;&nbsp; [Serializable]<br>&nbsp;&nbsp;&nbsp; public class LoadTestSinLoadProfile : CustomLoadProfile<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_amplitude;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_unitTimeInterval;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_freq;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadTestSinLoadProfile(int initCount, int amplitude, int unitTmeInterval, int frequency, int stepDuration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitialUserCount = initCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StepDuration = stepDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_amplitude = amplitude;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_unitTimeInterval = unitTmeInterval;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_freq = frequency;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override int GetLoad(int elapsedTimeInProfile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (elapsedTimeInProfile % StepDuration == 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentUserLoad = CalculateUserLoad(elapsedTimeInProfile);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (int)Math.Max(CurrentUserLoad, MinUserCount);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If you are familiar with Sin curves, you can modify the formula to calculate user load<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int CalculateUserLoad(int elapsedTimeInProfile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double userLoad = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userLoad = Math.Sin(2* Math.PI * m_freq * elapsedTimeInProfile / m_unitTimeInterval) * m_amplitude;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; userLoad = InitialUserCount + userLoad;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (Int32)(userLoad);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; // Custom step down - linear<br>&nbsp;&nbsp;&nbsp; [Serializable]<br>&nbsp;&nbsp;&nbsp; public class LoadTestStepDownLoadProfile : CustomLoadProfile<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadTestStepDownLoadProfile(int initCount, int minCount, int maxCount, int stepCount, int stepDuration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InitialUserCount = initCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StepUserCount = stepCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StepDuration = stepDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MinUserCount = minCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MaxUserCount = maxCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentUserLoad = initCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override int GetLoad(int elapsedTimeInProfile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (elapsedTimeInProfile % StepDuration == 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurrentUserLoad -= StepUserCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (int)Math.Max(CurrentUserLoad, MinUserCount);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; #endregion  <p>&nbsp;&nbsp;&nbsp; #region CustomLoadProfile Warpper Classes<br>&nbsp;&nbsp;&nbsp; // The base class (wrapper) for a customized load profile<br>&nbsp;&nbsp;&nbsp; public abstract class LoadProfileWrapper<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool m_inUse;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_duration;&nbsp; // How long this pattern will be simulated  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int Duration<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_duration; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_duration = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public bool InUse<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_inUse; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_inUse = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public abstract LoadTestLoadProfile Profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public virtual void UpdateProfileStatus(bool inUse, int currentUserLoad)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InUse = inUse;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; public class CustomLoadWrapper : LoadProfileWrapper<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestLoadProfile m_profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public CustomLoadWrapper(int patternDuration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile = new LoadTestConstantLoadProfile(); // instantiate it as an const load file<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InUse = false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Duration = patternDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override LoadTestLoadProfile Profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_profile; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_profile = (LoadTestLoadProfile)value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override void UpdateProfileStatus(bool inUse, int currentUserCount)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InUse = inUse;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m_profile is CustomLoadProfile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((CustomLoadProfile)m_profile).CurrentUserLoad = currentUserCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; #endregion<br>}  <p><strong>3) Add the LoadProfileManager.cs to your library</strong></p> <p>using System;<br>using System.IO;<br>using System.Collections;<br>using System.Collections.Generic;<br>using Microsoft.VisualStudio.TestTools.LoadTesting;  <p>namespace CustomLoadProfiles<br>{<br>&nbsp;&nbsp;&nbsp; // This the pattern group class<br>&nbsp;&nbsp;&nbsp; // It contains the list of profiles to be simulated in a specified time window<br>&nbsp;&nbsp;&nbsp; // Each group can contain several load test profiles<br>&nbsp;&nbsp;&nbsp; // During a load run, the test engine will cycle through the LoadTestProfiles and ajust the user load <br>&nbsp;&nbsp;&nbsp; public class LoadProfileGroup<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string m_name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;LoadProfileWrapper&gt; m_profileGroup;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_startTime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_endTime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_patternCycleDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_timeInGroup;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int m_previousCycleCount;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadProfileGroup(string name, int duration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_name = name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_duration = duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_timeInGroup = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_previousCycleCount = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_patternCycleDuration = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileGroup = new List&lt;LoadProfileWrapper&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void AddProfile(LoadProfileWrapper profile)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileGroup.Add(profile);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_patternCycleDuration += profile.Duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The load profiles to be simulated<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;LoadProfileWrapper&gt; LoadProfiles<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { get { return m_profileGroup; } }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int StartTime<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_startTime; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_startTime = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int EndTime<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_endTime; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_endTime = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int Duration<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { get { return m_duration; } }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String Name<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { get { return m_name; } }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This function will find out what load test profile will be used for current heartbeat event<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If no change will be made, null will be returned<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadTestLoadProfile GetLoadProfile(int elapsedTime, int currentUserLoad)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Calculate the elapased time in the group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_timeInGroup = elapsedTime - m_startTime;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int currentCycleCount = m_timeInGroup / m_patternCycleDuration;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Reset the InUse status of each profile to false at the beginning of each cycle<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m_previousCycleCount &lt; currentCycleCount &amp;&amp; m_timeInGroup % m_patternCycleDuration != 0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_previousCycleCount++;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; LoadProfiles.Count; i++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadProfileWrapper profileWrapper = LoadProfiles[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper.InUse = false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Find out if new load test profile should be applied <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int durationLength = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (LoadProfileWrapper profileWrapper in LoadProfiles)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; durationLength += profileWrapper.Duration;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((m_timeInGroup == 0) || // the first profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (m_timeInGroup &gt; 0 &amp;&amp; m_timeInGroup % m_patternCycleDuration &lt;= durationLength))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!profileWrapper.InUse)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Found the new profile to be applied<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profileWrapper.UpdateProfileStatus(true, currentUserLoad);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (LoadTestLoadProfile)profileWrapper.Profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;<br>&nbsp;&nbsp;&nbsp; /// Manages all pattern groups to be simulated in the load test run<br>&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;<br>&nbsp;&nbsp;&nbsp; public class LoadProfileManager<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;LoadProfileGroup&gt; m_profileGroups;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private string previousGroup;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadProfileManager()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profileGroups = new List&lt;LoadProfileGroup&gt;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // All the profiles included in this pattern<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;LoadProfileGroup&gt; ProfileGroups<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_profileGroups; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_profileGroups = value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get the current Load profile based on the elapsed time<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public LoadTestLoadProfile GetCurrentLoadProfile(int elapsedSeconds, int currentUserLoad)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestLoadProfile profile = null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bool foundProfileGroup = false;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (LoadProfileGroup group in m_profileGroups)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get the pattern group to be simulated<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (elapsedSeconds &lt;= group.EndTime &amp;&amp; elapsedSeconds &gt; group.StartTime)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foundProfileGroup = true;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!String.Equals(previousGroup, group.Name, StringComparison.OrdinalIgnoreCase))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; previousGroup = group.Name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Get the profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile = group.GetLoadProfile(elapsedSeconds, currentUserLoad);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If no profile group is found, the load test run will continue with a const load</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (foundProfileGroup == false)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; profile = new LoadTestConstantLoadProfile();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((LoadTestConstantLoadProfile)profile).UserCount = currentUserLoad;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Set the start/end times for each pattern group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void SetStartEndTimeForProfileGroups(int elapsedSeconds)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int prevGroupEndTime = elapsedSeconds;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int duration = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; foreach (LoadProfileGroup group in m_profileGroups)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set the start time <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; group.StartTime = prevGroupEndTime;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set the end time<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; duration += group.Duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; group.EndTime = duration;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // update the start time for next pattern group<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prevGroupEndTime = duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}  <p><strong>4) Add the class library for assembly binding</strong></p> <p>Drop the class library to the %Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies to avoid any serialization issues at run-time.</p> <p>If you want the initialization code of load profiles in the Load test plug-in to be simple and clean,&nbsp; you can add the wrapper classes for the build-in load profiles to CustomLoadProfiles.cs</p> <p>// The const load profile wrapper<br>&nbsp;&nbsp;&nbsp; public class ConstLoadWrapper : LoadProfileWrapper<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestConstantLoadProfile m_profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ConstLoadWrapper(int userCount, int duration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile = new LoadTestConstantLoadProfile();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.UserCount = userCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Duration = duration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override LoadTestLoadProfile Profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_profile; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_profile = (LoadTestConstantLoadProfile)value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; // The goal based load profile wrapper<br>&nbsp;&nbsp;&nbsp; public class GoalBasedLoadWrapper : LoadProfileWrapper<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestGoalBasedLoadProfile m_profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public GoalBasedLoadWrapper(int initialCount, int minCount, int maxCount, int maxIncrement, int maxDecrement, int patternDuration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile = new LoadTestGoalBasedLoadProfile();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.InitialUserCount = initialCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MinUserCount = minCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MaxUserCount = maxCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MaxUserCountIncrease = maxIncrement;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MaxUserCountDecrease = maxDecrement;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Duration = patternDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void SetCounter(string machine, string category, string counter, string instance, bool stopAdjustingAtGoal)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MachineName = machine;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.InstanceName = instance;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.CategoryName = category;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.CounterName = counter;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.StopAdjustingAtGoal = stopAdjustingAtGoal;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override LoadTestLoadProfile Profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_profile; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_profile = (LoadTestGoalBasedLoadProfile)value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp; // The step load profile wrapper<br>&nbsp;&nbsp;&nbsp; public class StepLoadWrapper : LoadProfileWrapper<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LoadTestStepLoadProfile m_profile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public StepLoadWrapper(int initCount, int minCount, int maxCount, int stepCount, int stepDuration, int stepRampTime, int patternDuration)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile = new LoadTestStepLoadProfile();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.InitialUserCount = initCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MinUserCount = minCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.MaxUserCount = maxCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.StepUserCount = stepCount;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.StepDuration = stepDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; m_profile.StepRampTime = stepRampTime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InUse = false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Duration = patternDuration;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override LoadTestLoadProfile Profile<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get { return m_profile; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set { m_profile = (LoadTestStepLoadProfile)value; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; } </p>]]></content:encoded>
    </item>
    <item>
      <title>VSTS 2010 Feature: Silent Installation of Controller and Agent</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/vsts-2010-feature-silent-installation-of-controller-and-agent</link>
      <pubDate>Fri, 15 Jan 2010 10:51:00 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2010/01/15/vsts-2010-feature-silent-installation-of-controller-and-agent/</guid>
      <description><![CDATA[In VSTS 2010, silent installation has been added to Controller and Agent setup.
Installation 
Run...]]></description>
      <content:encoded><![CDATA[<P>In VSTS 2010, silent installation has been added to Controller and Agent setup.</P>
<P><STRONG>Installation </STRONG></P>
<P>Run setup.exe /full /q from command line.</P>
<P><STRONG>Controller/Agent Configurations</STRONG> </P>
<P>The configuration can be done through UI or command line tools.</P>
<P>To configure through UI, go to Start-&gt;Programs-&gt;Microsoft Visual Studio 2010-&gt; Microsoft Visual Studio Test Controller 2010 Configuration Tool for controller configuration; and go to go to Start-&gt;Programs-&gt;Microsoft Visual Studio 2010-&gt; Microsoft Visual Studio Test&nbsp;Agent 2010 Configuration Tool for agent configuration.</P>
<P>To configure through command line tools, use TestControllerConfig.exe/TestAgentConfig.exe under D:\Program Files (or x86 on 64-bit machine) \Microsoft Visual Studio 10.0\Common7\IDE. Type /? for helps.</P>]]></content:encoded>
    </item>
    <item>
      <title>VSTS 2010 Feature: File Upload record/playback just works</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/vsts-2010-feature-file-upload-recordplayback-just-works</link>
      <pubDate>Fri, 12 Jun 2009 01:12:36 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2009/06/12/vsts-2010-feature-file-upload-recordplayback-just-works/</guid>
      <description><![CDATA[In VSTS2008 and VSTS2005, after a user records a simple file upload request, the user needs to...]]></description>
      <content:encoded><![CDATA[<p>In VSTS2008 and VSTS2005, after a user records a simple file upload request, the user needs to manually add it to the Deployment section in the test configuration file in order to playback the Web Test successfully. In addition, the user will notice that there is only one copy of the uploaded file on the Web Server regardless of how many times the Web test is executed. Therefore, it is not easy to find out whether files are uploaded correctly during load testing. In VSTS2010, we made the following four improvements to this File Upload feature. We will go through these with a simple Web test that has one file upload request, which uploads a file named test.txt&nbsp; <p>1. After a user records an http Upload request, the uploaded file is automatically added to the test project by a build-in FileUpload Plug-in. As you can see, test.txt is added to the test project after recording.  <p>2. A new property called Generate Unique Name is added to the File Upload Parameter. By default, its value is set to true, which indicates that a unique file name will be generated before the request is sent. If it is set to false,&nbsp; the file name will not be modified during test execution, which is the same as the upload behavior in VSTS2008 and VSTS2005. Note: In VSTS2010, for a upgraded Web test that contains a file upload request, the value is set to false.  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/Fu1_2.jpg" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/Fu1_2.jpg"><img title="Fu1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="383" alt="Fu1" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/Fu1_thumb.jpg" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/Fu1_thumb.jpg" width="781" border="0"></a>  <p>3. When a user runs the recorded file upload Web test, the file to be uploaded is automatically deployed. A user does not need to add it explicitly to the deployment section of&nbsp; the VSTS2010 .testsettings file before test execution.  <p>After the sample Web test is executed, as you can see, the uploaded file is prefixed with a timestamp.&nbsp;&nbsp; <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/image9.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/image9.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="385" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/image9_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureFileUploadrecordplaybackj_E25/image9_thumb.png" width="783" border="0"></a>  <p>If the server-side script does not modify the name of the uploaded file, a user should find the file "11062009091608978test.txt" on the Web Server machine.</p> <p>4. Playback of the generate coded Web test just works. As you can see in the below code, the file to be uploaded is automatically added as a deployment item.</p> <p>//------------------------------------------------------------------------------<br>// &lt;auto-generated&gt;<br>//&nbsp;&nbsp;&nbsp;&nbsp; This code was generated by a tool.<br>//&nbsp;&nbsp;&nbsp;&nbsp; Runtime Version:4.0.20608.0<br>//<br>//&nbsp;&nbsp;&nbsp;&nbsp; Changes to this file may cause incorrect behavior and will be lost if<br>//&nbsp;&nbsp;&nbsp;&nbsp; the code is regenerated.<br>// &lt;/auto-generated&gt;<br>//------------------------------------------------------------------------------  <p>namespace TestProject1<br>{<br>&nbsp;&nbsp;&nbsp; using System;<br>&nbsp;&nbsp;&nbsp; using System.Collections.Generic;<br>&nbsp;&nbsp;&nbsp; using System.Text;<br>&nbsp;&nbsp;&nbsp; using Microsoft.VisualStudio.TestTools.WebTesting;<br>&nbsp;&nbsp;&nbsp; using Microsoft.VisualStudio.TestTools.WebTesting.Rules;  <p>&nbsp;&nbsp;&nbsp; [DeploymentItem("test.txt")]<br>&nbsp;&nbsp;&nbsp; public class WebTest2Coded : WebTest<br>&nbsp;&nbsp;&nbsp; {  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public WebTest2Coded()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.PreAuthenticate = true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public override IEnumerator&lt;WebTestRequest&gt; GetRequestEnumerator()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Initialize validation rules that apply to all requests in the WebTest<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((this.Context.ValidationLevel &gt;= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValidateResponseUrl validationRule1 = new ValidateResponseUrl();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ValidateResponse += new EventHandler&lt;ValidationEventArgs&gt;(validationRule1.Validate);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((this.Context.ValidationLevel &gt;= Microsoft.VisualStudio.TestTools.WebTesting.ValidationLevel.Low))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ValidationRuleResponseTimeGoal validationRule2 = new ValidationRuleResponseTimeGoal();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; validationRule2.Tolerance = 0D;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.ValidateResponseOnPageComplete += new EventHandler&lt;ValidationEventArgs&gt;(validationRule2.Validate);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebTestRequest request1 = new WebTestRequest("<a href="https://teamtestweb1/testwebsite/FileUpload.aspx&quot;);">https://teamtestweb1/testwebsite/FileUpload.aspx");</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request1.ThinkTime = 26;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExtractHiddenFields extractionRule1 = new ExtractHiddenFields();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; extractionRule1.Required = true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; extractionRule1.HtmlDecode = true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; extractionRule1.ContextParameterName = "1";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request1.ExtractValues += new EventHandler&lt;ExtractionEventArgs&gt;(extractionRule1.Extract);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield return request1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request1 = null;  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebTestRequest request2 = new WebTestRequest("<a href="https://teamtestweb1/testwebsite/FileUpload.aspx&quot;);">https://teamtestweb1/testwebsite/FileUpload.aspx");</a><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2.Method = "POST";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FormPostHttpBody request2Body = new FormPostHttpBody();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2Body.FormPostParameters.Add("__VIEWSTATE", this.Context["$HIDDEN1.__VIEWSTATE"].ToString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2Body.FormPostParameters.Add(new FileUploadParameter("UploadFile", "test.txt", "text/plain", true));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2Body.FormPostParameters.Add("UploadButton", "Upload");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2Body.FormPostParameters.Add("SaveName", "test.txt");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2Body.FormPostParameters.Add("__EVENTVALIDATION", this.Context["$HIDDEN1.__EVENTVALIDATION"].ToString());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2.Body = request2Body;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yield return request2;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request2 = null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }<br>}  ]]></content:encoded>
    </item>
    <item>
      <title>VSTS 2010 Feature: View Recording Log in Web Test Playback Window</title>
      <link>https://docs.microsoft.com/archive/blogs/yutong/vsts-2010-feature-view-recording-log-in-web-test-playback-window</link>
      <pubDate>Wed, 10 Jun 2009 17:25:00 GMT</pubDate>
      <dc:creator><![CDATA[yutong]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/yutong/2009/06/10/vsts-2010-feature-view-recording-log-in-web-test-playback-window/</guid>
      <description><![CDATA[In VSTS2010, when a user records a Web test using Web Test Recorder, the recorded session result,...]]></description>
      <content:encoded><![CDATA[<p>In VSTS2010, when a user records a Web test using Web Test Recorder, the recorded session result, including those for the dependant and redirected requests, is saved and can be loaded into the Web Test Result window later. So if the playback fails, for example, due to correlation (dynamic parameter detection) issues, a user can always compare the recorded result and the playback result side by side.  <p>In the following example, the recorded Web test contains three requests. The first one is a non-redirect request and does not contain any dependant, the second one is request that is redirected twice, and the third one is redirected once and the redirect contains some dependant requests.  <p>To load the recorded result in Web Test Result window, a user can run the Web test till completion and click on the Recorded Result button on the toolbar.  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image_2.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image_2.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="663" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image_thumb.png" width="1043" border="0"></a>  <p>&nbsp;</p> <table cellspacing="0" cellpadding="0"> <tbody> <tr> <td width="231"></td></tr> <tr> <td></td> <td><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/clip_image001%5B8%5D.gif" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/clip_image001%5B8%5D.gif"></a></td></tr></tbody></table> <p>Below is the screenshot of the recorded result.  <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image28.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image28.png"><img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="604" alt="image" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image28_thumb.png" original-url="https://blogs.msdn.com/blogfiles/yutong/WindowsLiveWriter/VSTS2010FeatureViewRecordingLoginWebTest_F510/image28_thumb.png" width="1041" border="0"></a> </p> <p>In the launched Recorded Result window, not only can a user view the recorded details, i.e. headers, cookies, query string parameters, post parameters, and the response for a selected request, the user can also perform a search or go to the recorded Web Test. With VSTS2010, only the first recorded session result will be saved at the end of recording. </p>]]></content:encoded>
    </item>
  </channel>
</rss>