Question

I have found several samples about retrieving test results using the TFS API, but no documentation on creating results programmatically. My aim is to create a lightweight alternative to using Microsoft Test Manager for running manual tests. Does anyone have experience with this? Are there any examples out there that I'm missing?

Here's what I have so far:

ITestCaseResult CreateNewTestCaseResult(ITestSuiteEntry testCaseEntry)
{
    var run = testCaseEntry.TestSuite.Plan.CreateTestRun(false /* not automated */);
    run.AddTest(testCaseEntry.TestCase.Id, suiteEntry.TestSuite.DefaultConfigurations[0].Id, suiteEntry.TestSuite.Plan.Owner);
    run.Save(); // so that results object is created
    return run.QueryResults()[0];
}

I'm not sure if this is the correct way to initate a new run, and I'm not sure how to record results for each action of the test.

Was it helpful?

Solution

Update 15 Aug 2012:

The sample below has now been integrated into my open source TFS Test Steps Editor tool. In the latest version it gained the ability to publish test results to TFS. See the source on GitHub.


I now have working code for publishing test results. Note, the following code accepts ITestPoint (this represents a test case within a particular suite) and has some of my internal classes (not included) that just provide outcome and attachment paths for each step.

var tfsRun = _testPoint.Plan.CreateTestRun(false);

tfsRun.DateStarted = DateTime.Now;
tfsRun.AddTestPoint(_testPoint, _currentIdentity);
tfsRun.DateCompleted = DateTime.Now;
tfsRun.Save(); // so results object is created

var result = tfsRun.QueryResults()[0];
result.Owner = _currentIdentity;
result.RunBy = _currentIdentity;
result.State = TestResultState.Completed;
result.DateStarted = DateTime.Now;
result.Duration = new TimeSpan(0L);
result.DateCompleted = DateTime.Now.AddMinutes(0.0);

var iteration = result.CreateIteration(1);
iteration.DateStarted = DateTime.Now;
iteration.DateCompleted = DateTime.Now;
iteration.Duration = new TimeSpan(0L);
iteration.Comment = "Run from TFS Test Steps Editor by " + _currentIdentity.DisplayName;

for (int actionIndex = 0; actionIndex < _testEditInfo.TestCase.Actions.Count; actionIndex++)
{
    var testAction = _testEditInfo.TestCase.Actions[actionIndex];
    if (testAction is ISharedStepReference)
        continue;

    var userStep = _testEditInfo.SimpleSteps[actionIndex];

    var stepResult = iteration.CreateStepResult(testAction.Id);
    stepResult.ErrorMessage = String.Empty;
    stepResult.Outcome = userStep.Outcome;

    foreach (var attachmentPath in userStep.AttachmentPaths)
    {
        var attachment = stepResult.CreateAttachment(attachmentPath);
        stepResult.Attachments.Add(attachment);
    }

    iteration.Actions.Add(stepResult);
}

var overallOutcome = _testEditInfo.SimpleSteps.Any(s => s.Outcome != TestOutcome.Passed)
    ? TestOutcome.Failed
    : TestOutcome.Passed;

iteration.Outcome = overallOutcome;

result.Iterations.Add(iteration);

result.Outcome = overallOutcome;
result.Save(false);

OTHER TIPS

Test Action does not appear to have properties for setting pass/fail or to add attachments.

public interface ITestAction : INotifyPropertyChanged {
    int Id { get; }
    ITestBase Owner { get; }
    ITestActionGroup Parent { get; }

    ITestAction CopyToNewOwner(ITestBase newOwner);
    void MoveToNewOwner(ITestBase newOwner); }

That is done at the parent level (TestCase).

ITestCaseResult result = run.QueryResults()[0];
IAttachmentCollection collection = result.Attachments;
string x = result.Comment;

Here is how you correctly initiate a new run:

namespace SampleRunCreation
{
    class Program
    {
        static void Main(string[] args)
        {
            TfsTeamProjectCollection tfs = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://pradeepn-tcm:8080/tfs/DefaultCollection"));
            ITestManagementTeamProject project = tfs.GetService<ITestManagementService>().GetTeamProject("Pradeep");

            // 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];

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

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

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

        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;
        }
    }
}

Reference

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top