We need a way to access the trx file generated by vstest test runner on CI server (TFS 2013) so that I can inject some missing elements to it before generating living documentation (Specification by example style) using Pickles(a tool that read the trx and output a html test result file.). I am unable to figure out how to do it. I tried using .runsettings file and changing build definition in couple of ways and no luck yet. Each attempt, the test result folder is empty and no trx file in it. I can do it in my local machine like below
vstest.console.exe myTestFile.dll /Settings:Local.RunSettings /InIsolation /TestCaseFilter:"Priority=1" /Logger:trx
But unable to figure out how to do it in the CI server as build definition only allows allows to specify the test dll file, no way to specify the switches such as /Logger:trx etc. Any workable approach is highly appreciated.
After some research, I found out that, TFS2013 doesn't write it to given location, but stores the TRX file in TFS DB. You can download it using TFS API. Below code returns the Latest TRX file as a XDocument. However, if you want to write to a known location in the CI server, use below code in line 78 instead of returning a XDocument.
latestRun.Attachments[0].DownloadToFile("C:\myxml.trx");
Here is my TFS Service Wrapper class that gets the latest TRX from TFS 2013., Enjoy!!
using System.Linq;
using System.Net;
using System.Xml;
using System.Xml.Linq;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
using System.Configuration;
using System;
namespace TfsService
{
public class TfsServiceWrapper
{
public TfsTeamProjectCollection TeamProjectCollection { get; private set; }
public string TeamProject { get; private set; }
public string BuildName { get; private set; }
public Uri TfsUri { get; private set; }
public TfsServiceWrapper()
{
TfsUri = new Uri(ConfigurationManager.AppSettings["tfsUri"]);
TeamProject = ConfigurationManager.AppSettings["teamProject"];
BuildName = ConfigurationManager.AppSettings["buildName"];
ConnectToTeamProjectCollection();
}
public TfsServiceWrapper(Uri tfsUri, string teamProject, string buildName)
{
TfsUri = tfsUri;
TeamProject = teamProject;
BuildName = buildName;
ConnectToTeamProjectCollection();
}
private void ConnectToTeamProjectCollection()
{
TeamProjectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(TfsUri);
TeamProjectCollection.EnsureAuthenticated();
}
public IBuildDetail LatestBuildDetail
{
get
{
var spec = BuildServer.CreateBuildDetailSpec(TeamProject, BuildName);
spec.MaxBuildsPerDefinition = 1;
spec.QueryOrder = BuildQueryOrder.FinishTimeDescending;
return BuildServer.QueryBuilds(spec).Builds.FirstOrDefault();
}
}
public IBuildServer BuildServer
{
get
{
return (IBuildServer)TeamProjectCollection.GetService(typeof(IBuildServer));
}
}
public ITestManagementService TestManagementService
{
get
{
return (ITestManagementService)TeamProjectCollection.GetService(typeof(ITestManagementService));
}
}
public XDocument LatestTestResultFile
{
get
{
var latestRun = TestManagementService.GetTeamProject(TeamProject).TestRuns.ByBuild(LatestBuildDetail.Uri).First(run => run.QueryResults().Any());
var resolver = new XmlUrlResolver {Credentials = CredentialCache.DefaultCredentials};
var settings = new XmlReaderSettings {XmlResolver = resolver};
var reader = XmlReader.Create(latestRun.Attachments[0].Uri.ToString(), settings);
return XDocument.Load(reader);
}
}
}
}