Code snippets on Test Management APIs?


This post shares code snippets on how to do some common operations using Test Management APIs.

Snippet #1 : – Given a test run, find associated test suite.

// Query results from the run.
ITestCaseResult result = testManagementRun.QueryResults()[0];

// Find the test plan
ITestPlan testPlan = testManagementProject.TestPlans.Find(testManagementRun.TestPlanId);

// Get test point from result.
ITestPoint testPoint = testPlan.FindTestPoint(result.TestPointId);

ITestSuiteBase testSuite = testManagementProject.TestSuites.Find(testPoint.SuiteId);
return testSuite.Title;

(Update 25/8/2012)

Snippet #2:- Find all test plans which are active and where the ‘end date’ is before a date.

ITestPlanCollection tpc = proj.TestPlans.Query("Select * from
TestPlan where PlanState = ‘Active’ AND EndDate < ‘2009-10-14’ ");

Snippet #3: – Find test results in a manual test run

// Get the test runs
IEnumerable<ITestRun> testRuns = testManagementService.QueryTestRuns(string.Format("select * From TestRun where TestRunID={0} AND IsAutomated=0", testRunId));

// Use the first test run assuming that there is a valid run
ITestRun testRun = testRuns.FirstOrDefault();

// Find results in the run
ITestCaseResultCollection results = testRun.QueryResults();

(Update 10/8/2012)

Snippet #4: – How to create/update a new test run

// Create a new test run
ITestRun testRun = testPlan.CreateTestRun(true);     
   
// Add the tests that are part of the run
testPoints = testPlan.QueryTestPoints("SELECT * from TestPoint");
foreach (ITestPoint testPoint in testPoints)
{
    testRun.AddTestPoint(testPoint, null);
}
testRun.Save();         

 

// Update the outcome of the tests      
ITestCaseResultCollection results = testRun.QueryResults();
foreach(ITestCaseResult result in results)
{
    result.Outcome = TestOutcome.Passed;
    result.State = TestResultState.Completed;
    result.Save();
}
testRun.Save();
testRun.Refresh();

(Update 7/5/2013)

Snippet #4: – How to change order of columns for the parameters?

// Get a handle to the test
ITestManagementService service = teamProjectCollection.GetService<ITestManagementService>();
var project = service.GetTeamProject("MyProject");
var test = project.TestCases.Find(1266064);

 

// Get the parameters table
DataTable table = test.Data.Tables[0];

 

// Move the parameter named myparam1 to second column
table.Columns["myparam1"].SetOrdinal(1);

 

// Move the parameter named myparam2 to first column
table.Columns["myparam2"].SetOrdinal(0);

 

// Save the test
test.Save();

(Update 16/9/2013)

Snippet #5: – How to do bulk edit of test steps?

// Get a handle to the test
ITestManagementService tcmService = collection.GetService<ITestManagementService>();
ITestManagementTeamProject project = tcmService.GetTeamProject("MyProject");
ITestCase testCase = project.TestCases.Find(1257815);

// Iterate through the steps
for (int i = 0; i < testCase.Actions.Count;i++ )
  {
     ITestStep step = testCase.Actions[i] as ITestStep;
     if (step == null)
     {
         continue;
     }

     // Replace "before" with "after" in the title part of steps.
     string initialTitleDocument = step.Title.FlowDocumentString;
     string updatedTitleDocument = RichTextUtilities.Replace(titleDocument, "before", "after");

     // Replace the title.
     ParameterizedString newTitle = ParameterizedString.FromFlowDocument(updatedTitleDocument);
     step.Title = title;

     // You can update the ExpectedResult also the same as title.
  }

testCase.Save();

(Update 18/9/2013)

Snippet #6: – How to update the repro steps in a bug?

// Get the bug whose repro steps need to be updated
WorkItemStore store = collection.GetService<WorkItemStore>();
ITestManagementTeamProject project = collection.GetService<ITestManagementService>().GetTeamProject("myProject");
WorkItem bug = store.GetWorkItem(1811);

// Get the test case from which the repro steps needs to be populated
ITestCase tc = project.TestCases.Find(1737);

// Get the new repro steps
string newReproSteps = GetReproSteps(tc);

// update the repro steps 
Field reproSteps = wit.Fields["Microsoft.VSTS.TCM.ReproSteps"];
reproSteps.Value = newReproSteps;
bug.Save();

private static string GenerateHtmlString(ITestCase tc)
{
   string reproStep = "<table>";
   TestActionCollection steps = tc.Actions;
   ITestStep step;

   reproStep += "<tr><td style=’padding-right:10px;’ >’ + ‘Step No’ + ‘</td><td style=’padding-right:10px;’>’ + ‘Step Content’ + ‘</td></tr>’;
   for(int i=0;i<steps.Count;i++)
   {
       step = steps[i] as ITestStep;
       reproStep += "<tr><td style=’padding-right:10px;verical-align:top;’>’ + i.ToString() + ‘</td><td style=’padding-right:10px;’>’ + step.Title + ‘<div><b>Expected</b>’+step.ExpectedResult+'</div></td></tr>’;
   }
   reproStep += "</table>";
   return reproStep;
}

(Updated 25/10/2013)

Snippet #7: – How to find tfs test run/case/point details in test methods?

public void TestMethod()
{
// Get test run ID from current test run
int? testRunID = TestContext.Properties["__Tfs_TestRunId__"] as int?;
// Get the test case
// (If you have associated 1 test method with more than 1 test case, then it
//   can return wrong results. Assumption is that 1 test method is mapped to 1 test case only)
int? testcaseId = TestContext.Properties["__Tfs_TestCaseId__"] as int?;
// Get the test point so that you can find configuration etc from the test run.
//
using (TfsTeamProjectCollection collection = new TfsTeamProjectCollection(new Uri("myserver")))
{
    // Get the ongoing run object
    ITestManagementService tcmService = collection.GetService<ITestManagementService>();
    ITestManagementTeamProject project = tcmService.GetTeamProject("myproject");
    ITestRun testRun = project.TestRuns.Find(testRunID.Value);

    // Find the in-progress test. Since updates are pushed async to tfs (default interval is 30 sec)
    // wait for this test to show up in the progress list
    //
    ITestCaseResultCollection testResults = null;
    do
    {
        testResults = testRun.QueryResultsByStatus(TestResultState.InProgress);
        Thread.Sleep(100);
    }
    while (testResults == null || testResults.Count == 0);
    Debug.Assert(testResults.Count > 0, "Results should be more than 0");

    // Find the result for current test & get test point from it. here
    ITestCaseResult testCaseResult = testResults.Where(t => t.TestCaseId == testcaseId).First();
    int testPointId = testCaseResult.TestPointId;

    // Now you can get more interesting data about configuration etc & use it in your test method.
}                         
}

(Updated 12/4/2013)

Snippet #8 Create a test run, Mark steps passed/failed, associate attachments with it.

This sample is created by Pradeep and is available here and the important code file is mentioned below.

using System;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;

namespace SampleRunCreation
{
    class Program
    {
        static void Main(string[] args)
        {
            // Replace project collection with your project collection
            TfsTeamProjectCollection tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://myserver:8080/tfs/DefaultCollection"));

            // Replace project name with your team project.
            ITestManagementTeamProject project = tfs.GetService<ITestManagementService>().GetTeamProject("ScrumProject");

            // Create a test case.
            ITestCase testCase = CreateTestCase(project, "My test case");

            // Create test plan.
            ITestPlan plan = CreateTestPlan(project, "My test plan");

            // Create test configuration. You can reuse this instead of creating a new config everytime.
            ITestConfiguration config = CreateTestConfiguration(project, string.Format("My test config {0}", DateTime.Now));

            // Create test points.
            IList<ITestPoint> testPoints = CreateTestPoints(project,
                                                            plan,
                                                            new List<ITestCase>(){testCase},
                                                            new IdAndName[] { new IdAndName(config.Id, config.Name) });

            // Create test run using test points.
            ITestRun run = CreateTestRun(project, plan, testPoints);

            // Query results from the run.
            ITestCaseResult result = run.QueryResults()[0];

            // Add step results.
            AddStepResults(testCase, result);

            // Mark few step results.
            MarkStepResults(result);

            // Add attachment to run, result, iteration, and a step
            AddAttachment(run);
            run.Save();

            AddAttachment(result);
            AddAttachment(result.Iterations[1]);
            AddAttachment(result.Iterations[1].Actions[2]);

            // Fail the result.
            result.Outcome = TestOutcome.Failed;
            result.State = TestResultState.Completed;
            result.Save();

            Console.WriteLine("Run {0} completed", run.Id);
        }

        private static void AddAttachment(IAttachmentOwner attachmentOwner)
        {
            var attachment = attachmentOwner.CreateAttachment("SampleAttachment.txt");
            attachmentOwner.Attachments.Add(attachment);
        }

        private static void MarkStepResults(ITestCaseResult result)
        {
            result.Iterations[1].Actions[0].Outcome = TestOutcome.Passed;
            result.Iterations[1].Actions[1].Outcome = TestOutcome.Passed;
            result.Iterations[1].Actions[2].Outcome = TestOutcome.Failed;
        }

        private static void AddStepResults(ITestCase testCase, ITestCaseResult result)
        {
            // Create an iteration result. This is needed to create step results.
            var iteration = result.CreateIteration(1);
            foreach (var action in testCase.Actions)
            {
                var step = action as ITestStep;
                var stepResult = iteration.CreateStepResult(action.Id);

                // Add step results in iteration.
                iteration.Actions.Add(stepResult);
            }

            result.Iterations.Add(iteration);
        }

        private static ITestCase CreateTestCase(ITestManagementTeamProject project,
                                                string title)
        {
            // Create a test case.
            ITestCase testCase = project.TestCases.Create();
            testCase.Title = title;

            // Add steps.
            AddStep(testCase, "Step 1", string.Empty);
            AddStep(testCase, "Step 2", string.Empty);
            AddStep(testCase, "Step 3", "Expected 1");
           
            testCase.Save();
            return testCase;
        }

        private static void AddStep(ITestCase testCase, string title, string expected)
        {
            var testStep = testCase.CreateTestStep();
            testStep.Title = title;
            testStep.ExpectedResult = expected;
            testCase.Actions.Add(testStep);
        }

        private static ITestPlan CreateTestPlan(ITestManagementTeamProject project, string title)
        {
            // Create a test plan.
            ITestPlan testPlan = project.TestPlans.Create();
            testPlan.Name = title;
            testPlan.Save();
            return testPlan;
        }

        private static ITestConfiguration CreateTestConfiguration(ITestManagementTeamProject project, string title)
        {
            ITestConfiguration configuration = project.TestConfigurations.Create();
            configuration.Name = title;
            configuration.Description = "DefaultConfig";
            configuration.Values.Add(new KeyValuePair<string, string>("Browser", "IE"));
            configuration.Save();
            return configuration;
        }

        public static IList<ITestPoint> CreateTestPoints(ITestManagementTeamProject project,
                                                         ITestPlan testPlan,
                                                         IList<ITestCase> testCases,
                                                         IList<IdAndName> testConfigs)
        {
            // Create a static suite within the plan and add all the test cases.
            IStaticTestSuite testSuite = CreateTestSuite(project);
            testPlan.RootSuite.Entries.Add(testSuite);
            testPlan.Save();

            testSuite.Entries.AddCases(testCases);
            testPlan.Save();

            testSuite.SetEntryConfigurations(testSuite.Entries, testConfigs);
            testPlan.Save();

            ITestPointCollection tpc = testPlan.QueryTestPoints("SELECT * FROM TestPoint WHERE SuiteId = " + testSuite.Id);
            return new List<ITestPoint>(tpc);
        }

        private static IStaticTestSuite CreateTestSuite(ITestManagementTeamProject project)
        {
            // Create a static test suite.
            IStaticTestSuite testSuite = project.TestSuites.CreateStatic();
            testSuite.Title = "Static Suite";
            return testSuite;
        }

        private static ITestRun CreateTestRun(ITestManagementTeamProject project,
                                             ITestPlan plan,
                                             IList<ITestPoint> points)
        {
            ITestRun run = plan.CreateTestRun(false);
            foreach (ITestPoint tp in points)
            {
                run.AddTestPoint(tp, null);
            }

            run.Save();
            return run;
        }
    }
}

(Updated 10/24/2014)

Snippet #9 Create a test settings

ITestSettingsHelper testSettingsHelper = tcmTeamProject.TestSettings;
ITestSettings ts = testSettingsHelper.Create();
ts.IsAutomated = true;
ts.Name = "mysettings"
ts.AreaPath = projectName;

#Load the content of testSettings file
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("mysettings.testsettings");
ts.Settings = xmldoc.DocumentElement;

ts.Save();

Comments (11)

  1. Muralitharan says:

    We can get the test case id from Tfs_TestCaseId

    string tcId = TestContext.Properties["Tfs_TestCaseId"].ToString();

    How to capture Test Case Title that's current being run in the MTM in C# test method?

  2. Murali, Apologies for the late reply. You have to query the title using the TFS APIs.

  3. Bruce Cutler says:

    How do I create a new test configuration?

  4. AddUpdate notes says:

    Thank you for your post! Very helpful. Could you please help me write script to update Notes of tes case in specific test run?

    TfsTeamProjectCollection tfs = new TfsTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(""));

               ITestManagementService tms = tfs.GetService<ITestManagementService>();

               ITestManagementTeamProject proj = tms.GetTeamProject("");

               var results = proj.TestResults.Query(string.Format("SELECT * FROM TestResult WHERE TestRunId = 30504 and TestCaseId = 216674"));

               foreach(ITestCaseResult result in results)

               {

                   var errorMessage = result.ErrorMessage;

               }        

           }

  5. Test case result and the test case work item are different entities. Can you elaborate a bit further, if you wish to update the test result notes (comments) or test case work item notes (summary/description)? If you want to update the test case result comments you can set the ITestResult.Comment Property (msdn.microsoft.com/…/microsoft.teamfoundation.testmanagement.client.itestresult.comment.aspx)  in ITestResult itself. However, if you want to update the test case notes  you will have to access the test case work item and update the System.Description field. The test case work item ID is available in ITestCaseResult.TestCaseId Property. See here to find sample code to edit work items: msdn.microsoft.com/…/bb130323.aspx

  6. Ali says:

    Hi I am trying to create a Query tree view based test suite under MTM

    When i run query all workitems shows up in Parent child relation in MTM, but the moment i save the query all the workitmes are placed in flat hierarchy and it does not maintain the parent child relation anymore.. with this the order of the test cases changes..

    Could you please let me know how to update query so that all tests related one product backlog item are displayed first and then the next one..

    Also please send me code snippet to retrive suite id's in a given test plan

    Thanks

    Ali

  7. Manoj says:

    Ali,

    List of test cases in a test suite is a flat list. We support test suites that can be arranged hierarchically to organize test cases. For example, for your query regarding organising test cases per backlog item, I’d suggest you use requirement based suites so that all test cases that test a backlog item show up in an associated requirement based suite. Also, you can order test cases in a static test suite, but not requirement based suite or query based suite.

  8. Shweta says:

    How can I delete test steps from an existing test case.

  9. Johann says:

    Hello,

    Any idea when this bug will be resolved ?

    // (If you have associated 1 test method with more than 1 test case, then it

    //   can return wrong results. Assumption is that 1 test method is mapped to 1 test case only)

    Thank you !

  10. Alex says:

    Shweta,

    use method

    testCase.Actions.Clear();

    Then, of course, don't forget to save the test case:

    testcase.Save();

    Cheers,

    Alex

  11. name says:

    How can create testpoint for individual test cases from the already existing configurations in the project