0

I am using TFS 2015 to build, deploy and Run my selenium UI tests. Its working fine for me. I also have different build definition for different customers(tests run here are same but they run against different dbs).

My Tests Run every night and in morning I have to individually go to every build definition to see the result(I get a mail with the numbers of test fail and pass). but to see which test are failing and other details like why it is failing i need to go to the TFS build def on the server every time.

I intend to make a simple app which will fetch me that data display it at one place like a simple MVC web app(internal purpose). so far I am only able to get the simple data of the build like name and result by using

using Microsoft.TeamFoundation.Build.WebApi;

but I am not able to get the test run details and event the individual test details can anyone suggest me which API can I use to achieve this and display the data in simpler form.

I got to this link but I am not sure how can I consume this in my app. https://www.visualstudio.com/en-us/docs/integrate/api/test/results

Thanks,

Amey

Ak02
  • 143
  • 4
  • 16

2 Answers2

1

You can get the test results for a specific project with the REST API (The link you mentioned above)

For example, below PowerShell script sample can get all the failed test results from a specific project and alternatively export to .csv file, then open it in Excel to filter later:

Param(
   [string]$collectionurl = "http://server:8080/tfs/Collection", 
   [string]$project = "ProjectName",
   [string]$user = "username",
   [string]$token = "password"
) 

# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))

#Get test runs
$testrunsUrl = "$collectionurl/$project/_apis/test/runs?api-version=1.0"
$testruns = (Invoke-RestMethod -Uri $testrunsUrl -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}).value

#Get unit tests from each test run
$UnitTestResults = @()

foreach ($testrun in $testruns)
{
$testrunID = $testrun.id

#Get test results for specific test run
$baseUrl = "$collectionurl/$project/_apis/test/runs/$testrunID/results?api-version=3.0-preview"
$response = Invoke-RestMethod -Uri $baseUrl -Method Get -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}
$unittests = $response.value | where({$_.outcome -eq 'Failed'})

$customObject = new-object PSObject -property @{
          "ComputerName" = @($unittests.computerName -join ',')|Select-Object
          "BuildId" = @($unittests.build.id -join ',')|Select-Object
          "BuildName" = @($unittests.build.name -join ',')|Select-Object
          "BuildUrl" = @($unittests.build.url -join ',')|Select-Object
          "TestRunID" = $testrunID
          "ProjectName" = @($unittests.project.name -join ',')|Select-Object
          "TestRunName" = @($unittests.testRun.name -join ',')|Select-Object
          "TestRunURL" = @($unittests.testRun.url -join ',')|Select-Object
          "UnitTestname" = @($unittests.automatedTestName -join ',')|Select-Object
          "outcome" = @($unittests.outcome -join ',')|Select-Object
          "errorMessage" = @($unittests.errorMessage -join ',')|Select-Object
          "TestResultsUrl" = @($unittests.url -join ',')|Select-Object
          "completedDate" = @($unittests.completedDate -join ',')|Select-Object 
        } 

    $UnitTestResults += $customObject
}

$UnitTestResults | Select `
                ProjectName,
                ComputerName,
                BuildId,
                BuildName,
                BuildUrl,
                TestRunID,
                TestRunName,
                TestRunURL, 
                UnitTestname,
                outcome,
                errorMessage,
                TestResultsUrl,
                completedDate | where({$_.outcome -like '*Failed*'}) #|export-csv -Path C:\LC\UnitTest.csv -NoTypeInformation

You can also use the TFS API to achieve that. The test result of the build is stored in test runs, so you need to get the test run of the build first and then retrieve the test result from the test run.

You can reference below threads:

enter image description here

Andy Li-MSFT
  • 28,712
  • 2
  • 33
  • 55
  • apologies for late reply. – Ak02 Jan 31 '18 at 05:10
  • Actually I am working on your approach but I am trying to do it in c#. struggling but so didn't replied anything yet. and I want to display all test result data on a portal. so cant use this power shell script here. approach is correct but want to do the same thing in c#. – Ak02 Jan 31 '18 at 09:26
  • @Amey Yes, the first part is the PowerShell solution. And as you can see, I also provided the C# samples for your reference, you can refer to the links in the end of the answer, you need to use the TFS API. – Andy Li-MSFT Jan 31 '18 at 09:32
0

Here is a PowerShell script I use to get the results from TFS 2018 rest API which is running multiple selenium tests running as UI tests using TFS Release Management. You can change the API version number to support TFS 2015 and simplify below script to access and email your test results. In the script I consider multiple release environments since I am using it in TFS Release Management. The script has hard-coded access of Task ID 7, to find the status of release environment. Remove those steps in this example and simplify it to use with the builds. You can execute the PowerShell as inline script in the PowerShell build task.

param(
    [Parameter(Mandatory=$true)]
    [string] $TestEnvIds,
    [String] $recipients
)
$collectionUri = $Env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI
$TeamProject = $Env:SYSTEM_TEAMPROJECT
$ReleaseId = $Env:RELEASE_RELEASEID




$resultHtml='';

#$securePassword = $Password | ConvertTo-SecureString -AsPlainText -Force   
#$credential = New-Object System.Management.Automation.PSCredential($User, $securePassword)       


$Uri = $collectionUri + $TeamProject + '/_apis/Release/releases/' + $ReleaseId + '?api-version=4.0-preview.4'

write-host 'calling:' $Uri

$ReleaseInstance = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri -UseDefaultCredentials #-Credential $credential -Body $ReleaseMetadata 

$TestEnvIdArray =  $TestEnvIds.Split('; ',[System.StringSplitOptions]::RemoveEmptyEntries);
write-host "Test Run Results"
write-host "*************************"

$PassedTotTestCount = 0;
$FailedTotTestCount = 0;


foreach($TestEnvId in $TestEnvIdArray)
{
    #get definition environment id
    $tempEnv=  $ReleaseInstance.environments.Where({$_.definitionEnvironmentId -eq $TestEnvId})
    $envid=$tempEnv.id

    $resultHtml = $resultHtml + '<h2><u>' + $tempEnv.name + '</u></h2>'

    if($tempEnv.deploysteps.tasks.Count-gt0)
    {

        $Uri1=$collectionUri + $TeamProject + '/_apis/Release/releases/' + $ReleaseId + '/environments/'+$envid+'/tasks/7/logs?api-version=4.0-preview.4'
        $ReleaseText = Invoke-RestMethod -Method Get -ContentType application/json -Uri $Uri1 -UseDefaultCredentials

        if($ReleaseText.Contains('Deployment on this environment failed.'))
        {
            write-host "Deployment of test agent failed or other error occured."
            $resultHtml = $resultHtml + '<h3>Deployment of test agent failed or other error occured.</h3>'
        }
        else
        {
            #get test run id of environment
            $pattern="Test Run with Id(.*?)Queued"
            $testRunID=[regex]::Match($ReleaseText,$pattern).Groups[1].Value.trim()

            $testResultUri=$collectionUri + $TeamProject + '/_apis/test/runs/'+$testRunID+'/results?api-version=4.0-preview.4'
            $TestResults = Invoke-RestMethod -Method Get -ContentType application/json -Uri $testResultUri -UseDefaultCredentials

            # print Test Results
            write-host "**********Test Env" $TestResults.value[0].computerName"***************"
            write-host "---------------------------"

            $resultDetHtml =  '<ul>'

            $PassedCountEnv = 0;
            $FailedCountEnv = 0;

            for($i = 0; $i -lt $TestResults.value.Count; $i++)
            {
                write-host 'Test Id :'  $TestResults.value[$i].testCase.id 'Test Name:' $TestResults.value[$i].testCase.name 'Status:' $TestResults.value[$i].outcome
                $resultDetHtml = $resultDetHtml + '<li style="font-family: Arial; font-size: 12pt;">'+ $TestResults.value[$i].outcome + ' Test:'+ $TestResults.value[$i].testCase.id + ' - ' + $TestResults.value[$i].testCase.name + '</li>'

                if($TestResults.value[$i].outcome.tolower() -eq 'passed')
                {
                    $PassedCountEnv += 1;
                }
                else
                {
                    $FailedCountEnv += 1;
                }

            }
            $resultDetHtml = $resultDetHtml + '</ul>'

            $resultHtml = $resultHtml + '<h3>Pass Rate: <span style="color: #3366ff;"> {0:N2}' -f + (($PassedCountEnv/($PassedCountEnv+$FailedCountEnv))*100) + '% </span> <span style="color: #339966;">Passed</span>:' + $PassedCountEnv + '<span style="color: #ff0000;"> Failed</span>:' + $FailedCountEnv  + '</h3>'
            $resultHtml = $resultHtml + $resultDetHtml

            $PassedTotTestCount = $PassedTotTestCount + $PassedCountEnv
            $FailedTotTestCount = $FailedTotTestCount + $FailedCountEnv

        }

    }
    else
    {
        write-host "Test environment has failed."
        $resultHtml = '<h3>Test environment has failed.</h3>' + $resultHtml 
    }
}



$ReultsEmailSubject = 'Test results for Release:' + $ReleaseInstance.description

$resultHtml = '<h1><u>' + $ReultsEmailSubject +'</u><h1>' + '<h3>Pass Rate: <span style="color: #3366ff;"> {0:N2}' -f +(($PassedTotTestCount/($PassedTotTestCount+$FailedTotTestCount))*100) + '% </span> <span style="color: #339966;">Passed</span>:' + $PassedTotTestCount + '<span style="color: #ff0000;"> Failed</span>:' + $FailedTotTestCount  + '</h3>' + $resultHtml 
#$resultHtml

write-host "Now sending email"


$recipientsArray = $recipients.Split(',')

Send-MailMessage -To $recipientsArray -Subject $ReultsEmailSubject -Body $resultHtml -BodyAsHtml -SmtpServer yourSMTPserver  -From tfs@yourdomain.com

write-host "Email Sent"

enter image description here

ChamindaC
  • 1,452
  • 10
  • 10