<?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>Nidhi Thakur's Blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/nidhithakur/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/nidhithakur/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:50:21 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>TFS: Programatically importing testcase results to MTM</title>
      <link>https://docs.microsoft.com/archive/blogs/nidhithakur/tfs-programatically-importing-testcase-results-to-mtm</link>
      <pubDate>Fri, 08 Apr 2011 03:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Nidhi Thakur]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/nidhithakur/2011/04/08/tfs-programatically-importing-testcase-results-to-mtm/</guid>
      <description><![CDATA[This post is intended to provide&nbsp;a detailed approach&nbsp;to importing testcase...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;"><span style="color: #000000;">This post is intended to provide&nbsp;a detailed approach&nbsp;to importing testcase results&nbsp;from a source/system to Microsoft Test Manager associated with TFS.</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">You will need to process data from your system/source which you can then add to MTM.&nbsp;An XML file source with Axe IDs and corresponding results has been used as an example in this post. Each AXE Id should map to a test points in TFS for the result to be created/saved. <br />Note : Test Points and Test cases are treated differently by MTM. Each Testcase can be run with a number of configurations and each combination of test case and configuration is called a test point. When creating a test run, we will use test points as tests are executed and results are stored against test points and not test cases.</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">The overall approach can be broken down into a couple of tasks:</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;"></span></span><span style="font-size: small;"><span style="color: #000000;">1. Reading/Storing test result data from your system into some form/structure.</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">2. Establishing connection to TFS</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">3. Identifying test points which correspond to the results from our source.</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">4. Adding results corresponding to the test points and uploading them to TFS</span></span></p>
<p>&nbsp;<span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff;"><span style="font-size: small;"><span style="color: #000000;">The following assemblies will be needed for the operations below:<br /></span></span></span></span></span></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">System;<br />System.Net;<br /></span></span></em></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">System.Linq;<br /></span></span></em></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">System.Text;<br /></span></span></em></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">System.Xml;<br /></span></span></em></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">System.Collections.Generic;<br />Microsoft.TeamFoundation.Client;<br /></span></span></em></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">Microsoft.TeamFoundation.TestManagement.Client;<br /></span></span></em></span></span></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">Microsoft.TeamFoundation.TestManagement.Common;<br /></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;">Microsoft.TeamFoundation.WorkItemTracking.Client;</span></span></span></span></em></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">Part I:</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">For the first part,&nbsp;an xml file with AXE Ids and corresponding results will be processed for storing data in a more usable form. Here, a</span></span><span style="font-size: small;"><span style="color: #000000;"> dictionary is created&nbsp;with the key as the Axe Id which is&nbsp;the Id&nbsp;which will&nbsp;be&nbsp;used to identify the test point in TFS.</span></span></p>
<p>&nbsp;<span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">//Dictionary to store the Axe Ids and corresponding results from the MTM xml file<br />Dictionary&lt;string, TestPointResultData&gt; test_point_result_dictionary = new Dictionary&lt;string, TestPointResultData&gt;();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></em></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">&nbsp;// Create an instance of XmlTextReader and call Read method to read the file&nbsp;<br />&nbsp;XmlTextReader textReader = null;&nbsp;<br />&nbsp;textReader = new XmlTextReader(&lt;xml-file-path&gt;);<br />&nbsp;textReader.Read();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;//&lt; write your own code ro read the XML bits which contain the Ids and results data and store them in the dictionary&gt;<br /></span></span></em></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">A&nbsp;class TestPointResultData has been used&nbsp;to store result data correspoding to the Axe ID. The details of the class are as below:</span></span></p>
<p><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff; font-size: x-small;"><span style="font-family: Consolas; color: #0000ff;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">class </span></span></em></span></span></span></span><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af; font-size: x-small;"><span style="font-family: Consolas; color: #2b91af;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">TestPointResultData<br /></span></span></em></span></span></span></span><span style="font-family: Consolas; font-size: x-small;"><span style="font-family: Consolas;"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">{<br /></span></span></em></span></span></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">// Field to store the test point outcome<br /></span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">public</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">String</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> Outcome { </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">get</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;">; </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">set</span></span></span></span></span></em></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">; }<br /></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">public</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">bool</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> hasTestPoint { </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">get</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;">; </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">set</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;">; }</span></span></span></span></span></span></em></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">// Field to store the info about failure<br /></span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">public</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">String</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> Info { </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">get</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;">; </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">set</span></span></span></span></span></em></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">; }<br /></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">public</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> TestPointResultData(</span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">String</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> outcome, </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">bool</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> foundTestPoint, </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">String</span></span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"> info = </span></span><span style="font-family: Consolas;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">null</span></span></span></span></span></em></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><span style="font-family: Consolas;"><span style="font-family: Consolas;">) <br /></span></span>}</span></span></em></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">Part II:<br /></span></span><span style="font-size: small;"><span style="color: #000000;">Now that&nbsp;the data&nbsp;to be inserted into TFS has been identified and stored, establish a connection to TFS. </span></span></p>
<p>&nbsp;<span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">string serverurl = "</span></span></em></span><a href="https://<tfs-server-name><port-number>"><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">https://&lt;tfs-server-name&gt;:&lt;port-number&gt;/tfs</span></span></em></span></a><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">";&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />TeamFoundationServer tfs = new TeamFoundationServer(serverurl, new UICredentialsProvider());&nbsp;&nbsp;&nbsp;&nbsp;<br />// Or use&nbsp;this for entering credentials via code and avoiding UI prompt:&nbsp;tfs <span style="background-color: transparent; font-family: Courier New; font-weight: normal;">=</span> <span style="background-color: transparent; font-family: Courier New; font-weight: normal;">new</span> TeamFoundationServer(tfServerName, '''<span style="background-color: transparent; font-family: Courier New; font-weight: normal;">new</span> NetworkCredential(<span style="background-color: transparent; font-family: Courier New; font-weight: normal;">"User"</span>, <span style="background-color: transparent; font-family: Courier New; font-weight: normal;">"Password"</span>, <span style="background-color: transparent; font-family: Courier New; font-weight: normal;">"Domain"</span>);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />// Ensure the current user can authenticate with TFS<br />tfs.EnsureAuthenticated();<br /></span></span></em></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;"><br />TfsTeamProjectCollection tfsCollection = new TfsTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(serverurl));<br />ITestManagementService tms = tfs.GetService&lt;ITestManagementService&gt;();<br />ITestManagementTeamProject project = tms.GetTeamProject(&lt;project-name&gt;);<br />ITestPlanHelper planHelper = project.TestPlans;<br />ITestPlan foundPlan =&nbsp;project.TestPlans.Find(&lt;test-plan-number&gt;);&nbsp;</span></span></em></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">The test plan where the results are to be inserted has now been retrieved.</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">Part III:<br /></span></span><span style="font-size: small;"><span style="color: #000000;">To be able to add results to this test plan, create a new test run in the test plan. map the test points&nbsp;which are present in the dictionary&nbsp;and add to this test run. Ideally, you should be&nbsp;able to add the results while adding the test point to the&nbsp;run but the run.Save() API is only working for single&nbsp;Save right now. So, you will need to add all the testpoints, save the test run and then iterate over the run collection to add results individually. For better performance, save the result collection once after all the results have been added/updated.</span></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">//create a test run&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />ITestRun run = foundPlan.CreateTestRun(true);<br />run.Title =&nbsp;&lt;custom-title&gt;<br />foreach (ITestSuiteBase suite in foundPlan.RootSuite.SubSuites)<br />{<br />IStaticTestSuite staticSuite = suite as IStaticTestSuite;<br />ITestPointCollection testPoints = foundPlan.QueryTestPoints(string.Format("SELECT * FROM TestPoint WHERE SuiteId = {0}", suite.Id));<br />int number = testPoints.Count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />System.Linq.IQueryable&lt;ITestPoint&gt; linqQuery = testPoints.AsQueryable();<br />foreach (string testID in test_point_result_dictionary.Keys)<br />{<br />&nbsp; if (test_point_result_dictionary[testID].hasTestPoint) continue;<br /></span></span></em></span><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">&nbsp; // Use linq query to find the test point correspoding to each AXE Id.<br />&nbsp; var mytestPoint = linqQuery.Where(point =&gt; point.TestCaseWorkItem.Implementation.DisplayText.Contains(testID));<br />&nbsp; foreach (ITestPoint tp in mytestPoint)<br />&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; run.AddTestPoint(tp, null);<br />&nbsp;&nbsp; }<br />&nbsp;}<br />}</span></span></em></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">//save the added testpoints in this test run <br />run.Save();</span></span></em></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">Part IV:<br /></span></span></em></span><span style="font-size: x-small;"><span style="font-size: small;"><span style="color: #000000;">Test Run with required test points has been created. Adding results:</span></span></span></p>
<p><span style="font-size: x-small;"><em><span style="font-size: small;"><span style="color: #000000;">ITestCaseResultCollection resultCollection = run.QueryResults();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />foreach( ITestCaseResult result1 in resultCollection)<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp; ITestCase testcase = result1.GetTestCase();<br />&nbsp;&nbsp;&nbsp;&nbsp; string displayText = testcase.Implementation.DisplayText;<br />&nbsp;&nbsp;&nbsp;&nbsp; string[] displayTextArray = displayText.Split('.');<br />&nbsp;&nbsp;&nbsp;&nbsp; string axeID = displayTextArray[displayTextArray.Count()-1];<br />&nbsp;&nbsp;&nbsp;&nbsp; TestPointResultData value;<br />&nbsp; &nbsp;&nbsp; if (null != axeID &amp;&amp; test_point_result_dictionary.TryGetValue(axeID, out value))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result1.State = TestResultState.Completed;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (value.Outcome)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case "Pass": result1.Outcome = TestOutcome.Passed; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case "Fail": result1.Outcome = TestOutcome.Failed; break;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // add other cases<br />&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;<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />}</span></span></em></span></p>
<p><em><span style="font-size: small;"><span style="color: #000000;">//save the result collection once in the end.<br />resultCollection.Save(false);</span></span></em></p>
<p><span style="font-size: small;"><span style="color: #000000;">Once the result collection is saved, you should be able to see this test run and corrresponding results&nbsp;in TFS/MTM under Test-&gt;Analyse Test Runs.&nbsp;To keep this blog simple and focus on the approach, most the error handling has been ommited. </span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;">Finally, to see the results that have been added to TFS, you can interate over the result collection:</span></span></p>
<p><span style="font-size: small;"><span style="color: #000000;"><em>//Iterate over results to diplay the Recorded results<br />foreach (ITestCaseResult result1 in resultCollection)<br />{<br />&nbsp; ITestCase testcase = result1.GetTestCase();<br />&nbsp; Console.WriteLine("Testcase {0} Outcome {1}", testcase.Implementation.DisplayText, result1.Outcome);<br />}</em></span></span></p>
<p></p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
  </channel>
</rss>