Question

I'm trying to use the TFS API to update test results from automation run separately. I've tried the suggestions from other questions here (particularly How to create a test run and result using the Team Foundation Server API?) as well as from searches elsewhere. No matter what I try I have the same problem: every time I try to add a test point to a test run, I receive the error -

Microsoft.TeamFoundation.TestManagement.Client.TestManagementInvalidOperationException: This test run cannot be created with the test points.

The test points are retrieved from TFS using WIQL, and I check each test point to ensure that it is correct for the test plan, test suite, and test configuration before I attempt to add it.

I can't save the test run without test points.

Sample code (I've gone through so many attempts that my code is now beyond messy)

    public void UpdateTests(TestSuiteRun suiteRun)
    {


        this.Config = FindConfig(suiteRun.Description);
        this.Suite = FindSuite(suiteRun.Name); 
        this.Plan = Suite.Plan;
        this.Points = FindPoints(this.Suite.Id, this.Config.Id);
        ITestCaseCollection testCases = Suite.AllTestCases;
        this.Run = TeamProject.TestRuns.Create();
        ConfigureTestRun(); // failing here

        this.Result = CreateRunResults();

        this.Iteration = CreateSingleIteration(suiteRun.Description);
        {
            UpdateResultsForScenario(scen);
        }


     }

And the method to configure the test run:

    private void ConfigureTestRun()
    {
        this.Run.DateStarted = DateTime.Now;
        this.Run.DateCompleted = DateTime.Now;
        // find the points that correspond to test cases in the run suite
        foreach (ITestPoint point in this.Points)
        {
            if (point.TestCaseExists && point.Plan.Id == this.Plan.Id && point.ConfigurationId == this.Config.Id)
            {
                this.Run.AddTestPoint(point, this.CurrentUser); // fails with InvalidOperationException
            }
        }

        this.Run.Save();
    }

I'm able to connect to TFS and retrieve all the data I need but adding test points to a new test run is driving me crazy.

What have I done wrong?

Was it helpful?

Solution

After an insane amount of experimenting and beating my head against the wall, I've found the answer.

For those who are curious, here's how it works:

  • If I create the test run using ITestManagementService.TestRuns.Create(); I can add Test Cases but not Test Points.

  • If I create the test run using ITestPlan.CreateTestRun(isAutomated); I can add Test Points but not Test Cases.

I overcomplicated things a lot trying to get this working - I've now cleaned up a lot of the mess and have my application correctly reporting test results to TFS.

I'm using a fake build more or less as described by Jason Prickett's blog.

One thing I did find was that I couldn't define the run as an automated run because I have no test run controllers in my environment and couldn't find a way to move the test run state from WaitingForController to Completed.

There's more cleanup to go but the core works this way:

        this.Run = this.Plan.CreateTestRun(false);
        ConfigureTestRun(build);

        this.Result = CreateRunResults();

        this.Iteration = CreateSingleIteration(suiteRun.Description);

// custom processing omitted for brevity

        this.Result.Iterations.Add(this.Iteration);
        // Attach the run log to the results
        ITestAttachment item = this.Iteration.CreateAttachment(ConfigurationManager.AppSettings["LogFile"], SourceFileAction.None);
        this.Result.State = TestResultState.Completed;
        this.Result.Save();
        this.Run.Attachments.Add(item);
        this.Run.Save();

And the test run configuration routine is:

    private void ConfigureTestRun(IBuildDetail build)
    {
        this.Run.DateStarted = DateTime.Now;
        this.Run.DateCompleted = DateTime.Now;
        this.Run.BuildDirectory = build.DropLocation;
        this.Run.BuildFlavor = "debug";
        this.Run.BuildNumber = build.BuildNumber;
        this.Run.BuildPlatform = "test platform";
        this.Run.BuildUri = build.Uri;
        this.Run.Controller = build.BuildController.Name;


        // find the points that correspond to test cases in the run suite
        foreach (ITestPoint point in this.Points)
        {
            if (point.TestCaseExists && point.Plan.Id == this.Plan.Id && point.ConfigurationId == this.Config.Id)
            {
                this.Run.AddTestPoint(point, this.CurrentUser);
            }
        }

        this.Run.Save();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top