2013-12-03 2 views
3

У меня есть объект ITestCaseResult, и я не могу понять, как извлечь из него информацию о тестовом классе. Объект содержит имя тестового метода в свойстве TestCaseTitle, но в нашей базе кода имеется много дубликатов, и я хотел бы получить дополнительную информацию.В TFS API, как получить полное имя класса для данного теста?

Предполагая, что у меня есть Foo.Bar сборки с классом Baz и методом ThisIsATestMethod, я в настоящее время имею доступ только к ThisIsATestMethod информации из заголовка в, но я хотел бы получить Foo.Bar.Baz.ThisIsATestMethod.

Как это сделать, используя API TFS?

Вот некоторые урезанная код:

var def = buildServer.CreateBuildDetailSpec(teamProject.Name); 
def.MaxBuildsPerDefinition = 1; 
def.QueryOrder = BuildQueryOrder.FinishTimeDescending; 
def.DefinitionSpec.Name = buildDefinition.Name; 
def.Status = BuildStatus.Failed | BuildStatus.PartiallySucceeded | BuildStatus.Succeeded; 

var build = buildServer.QueryBuilds(def).Builds.SingleOrDefault(); 
if (build == null) 
    return; 

var testRun = tms.GetTeamProject(teamProject.Name).TestRuns.ByBuild(build.Uri).SingleOrDefault(); 
if (testRun == null) 
    return; 

foreach (var outcome in new[] { TestOutcome.Error, TestOutcome.Failed, TestOutcome.Inconclusive, TestOutcome.Timeout, TestOutcome.Warning }) 
    ProcessTestResults(bd, testRun, outcome); 

...

private void ProcessTestResults(ADBM.BuildDefinition bd, ITestRun testRun, TestOutcome outcome) 
{ 
    var results = testRun.QueryResultsByOutcome(outcome); 
    if (results.Count == 0) 
     return; 


    var testResults = from r in results // The "r" in here is an ITestCaseResult. r.GetTestCase() is always null. 
         select new ADBM.Test() { Title = r.TestCaseTitle, Outcome = outcome.ToString(), ErrorMessage = r.ErrorMessage }; 
} 

ответ

5

Вы можете сделать это, загрузив файл TRX из TFS и разобрав его вручную. Для того, чтобы скачать файл TRX для тестового запуска, выполните следующие действия:

TfsTeamProjectCollection tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(new Uri("http://my-tfs:8080/tfs/DefaultCollection")); 
    ITestManagementService tms = tpc.GetService<ITestManagementService>(); 
    ITestManagementTeamProject tmtp = tms.GetTeamProject("My Project"); 
    ITestRunHelper testRunHelper = tmtp.TestRuns; 
    IEnumerable<ITestRun> testRuns = testRunHelper.ByBuild(new Uri("vstfs:///Build/Build/123456")); 
    var failedRuns = testRuns.Where(run => run.QueryResultsByOutcome(TestOutcome.Failed).Any()).ToList(); 
    failedRuns.First().Attachments[0].DownloadToFile(@"D:\temp\myfile.trx"); 

Затем разобрать файл TRX (который является XML), ищет <TestMethod> элемент, который содержит полное имя класса в " className ":

<TestMethod codeBase="C:/Builds/My.Test.AssemblyName.DLL" adapterTypeName="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestAdapter, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.Adapter, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" className="My.Test.ClassName, My.Test.AssemblyName, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name="Test_Method" /> 
+0

Замечательно, это очень хорошо работает для моего инструмента. Большое спасибо. – Vache

2

Здесь у вас есть способ получить имя сборки:

foreach (ITestCaseResult testCaseResult in failures) 
    { 
     string testName = testCaseResult.TestCaseTitle; 
     ITmiTestImplementation testImplementation = testCaseResult.Implementation as     ITmiTestImplementation; 
    string assembly = testImplementation.Storage; 
    } 

К сожалению, ITestCaseResult и ITmiTestImplementation, похоже, не содержат пространства имен тестового примера.

Отметьте последний ответ в this link, что может помочь. Удачи!

EDIT: Это основано на Чарльз ответ Крейн «s, но получить имя класса без необходимости загрузки на файл:

var className = GetTestClassName(testResult.Attachments); 

а сам метод:

private static string GetTestClassName(IAttachmentCollection attachmentCol) 
    { 
     if (attachmentCol == null || attachmentCol.Count == 0) 
     { 
      return string.Empty; 
     } 

     var attachment = attachmentCol.First(att => att.AttachmentType == "TmiTestResultDetail"); 

     var content = new byte[attachment.Length]; 
     attachment.DownloadToArray(content, 0); 
     var strContent = Encoding.UTF8.GetString(content); 

     var reader = XmlReader.Create(new StringReader(RemoveTroublesomeCharacters(strContent))); 
     var root = XElement.Load(reader); 
     var nameTable = reader.NameTable; 
     if (nameTable != null) 
     { 
      var namespaceManager = new XmlNamespaceManager(nameTable); 
      namespaceManager.AddNamespace("ns", "http://microsoft.com/schemas/VisualStudio/TeamTest/2010"); 

      var classNameAtt = root.XPathSelectElement("./ns:TestDefinitions/ns:UnitTest[1]/ns:TestMethod[1]", namespaceManager).Attribute("className"); 

      if (classNameAtt != null) return classNameAtt.Value.Split(',')[1].Trim(); 
     } 

     return string.Empty; 
    } 

    internal static string RemoveTroublesomeCharacters(string inString) 
    { 
     if (inString == null) return null; 

     var newString = new StringBuilder(); 

     foreach (var ch in inString) 
     { 
      // remove any characters outside the valid UTF-8 range as well as all control characters 
      // except tabs and new lines 
      if ((ch < 0x00FD && ch > 0x001F) || ch == '\t' || ch == '\n' || ch == '\r') 
      { 
       newString.Append(ch); 
      } 
     } 
     return newString.ToString(); 
    } 
+0

Спасибо. К сожалению, приложение не работает на той же машине, что и тесты, поэтому у него нет прямого доступа к сборкам ... – Vache

2

Поскольку данные тестового теста хранятся в рабочем элементе, вы можете получить данные, обратившись к рабочему элементу для тестового примера

ITestCaseResult result; 
var testCase = result.GetTestCase(); 
testCase.WorkItem["Automated Test Name"]; // fqdn of method 
testCase.WorkItem["Automated Test Storage"]; // dll 
+0

Это выглядит многообещающим, но 'result.GetTestCase()' всегда возвращает null. Любая идея о том, какой параметр в моих определениях построения или в TFS может вызвать это? – Vache

+0

Свойство 'TestCaseId' всегда' 0', которое может быть связано ... – Vache

+0

@Vache, пожалуйста, поделитесь своим кодом в вопросе. – allen