Определение имени файла результатов для vstest.console.exe

Может быть, глупый вопрос, но кто-нибудь знает, как указать вывод имя_файла запуска VSTEST.Console.exe? Моя строка команд выглядит следующим образом:

 vstest.console.exe [assembly] /logger:trx

В конце прогона в консоли появляется следующее:

 ResultsFile: somepath\TestResults\{username}_{workstation} {timestamp}.trx

Я попытался использовать файл .runsettings, чтобы указать местоположение вывода, но это только управляет выходным каталогом, но не выходным файлом. Не нашел ничего, что могло бы контролировать его.

Я хочу проанализировать TRX файл и создать отчет из него (это уже работает, но если я не могу указать путь вывода файла TRX, я не буду знать, где его взять скрипты!)

Мне здесь что-то не хватает...

Ответ 1

Нет, вы ничего не пропустили. Регистратор TRX не поддерживает никаких параметров (в отличие от регистратора издателей TFS).

Узел регистратора находится в "C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\Extensions\Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.dll". Если вы проверите это в своем любимом декомпиляторе .NET, вы увидите метод TrxLogger.GetTrxFileName. Он использует некоторые базовые знания о текущем тестовом прогоне для создания искаженного имени формы {username}_{workstation} {timestamp}.trx и не имеет заметного способа настройки.

Насколько я могу судить, файл TRX создается в папке TestResults\ в текущем рабочем каталоге, если не задано иное. Что вы можете сделать, это:

  • Создайте новую временную папку
  • Изменить текущий каталог на него
  • Запустите тестовый бегун
  • Сканировать папку для файла результата .trx, используя ваш любимый метод рекурсивного поиска файлов, и вы закончили

По крайней мере, это то, что я делаю в нашей сборке (MSBuild, sob):

<ItemGroup>
  <TestResult Include="**\*.trx"/>
</ItemGroup>

I.e, соберите все .trx файлы в текущем каталоге и добавьте их в группу элементов @(TestResult) для дальнейшей обработки.

Ответ 2

По-видимому, вы можете указать каталог, куда поместить файл *.trx(но не сам файл). Это, однако, выполняется через файл .runsettings, а не через командную строку.

Отрывок из Блог Bhuvaneshwari:

Если по умолчанию местоположение результатов должно быть переопределено, пользователю необходимо передайте это значение, используя файл runsettings.

Пример:

Mstest.exe /testcontainer:abc.dll /results:C:\Results.trx 

Vstest.console.exe abc.dll /settings:output.runsettings 

где контекст .runsettings будет выглядеть примерно так:

<?xml version="1.0" encoding="UTF-8"?> 
<RunSettings> 
  <RunConfiguration>
   <ResultsDirectory>c:\</ResultsDirectory>
  </RunConfiguration>
 </RunSettings>

Ответ 3

У меня тоже была эта проблема. Я решил написать цель MSBuild, которая запускает vstest.console с помощью задачи EXEC, обрабатывая все его результаты, включая результаты покрытия.

В основном, я захватил вывод vstest и использовал регулярное выражение для захвата части *.trx и *.coverage вывода, которая оказалась очень простой. Кроме того, он удаляет каталог TestResults, чтобы поддерживать рабочее и чистое рабочее пространство.

В итоге вы получите файл *.trx и файл *.coverage(необязательно).

script может показаться немного сложным, но это необходимо для удовлетворения наших потребностей. Я попытался немного почистить его. Надеюсь, это поможет.

<Target Name="Test" DependsOnTargets="Build">
    <!-- Declare the defaults and arrange parameters -->
    <PropertyGroup>
      <ArtifactsPath Condition=" '$(ArtifactsPath)' == '' ">Artifacts</ArtifactsPath>
      <VSTestSessionName Condition=" '$(VSTestSessionName)' == ''">TestResults</VSTestSessionName>
      <VSTestExe Condition=" '$(VSTestExe)' == '' ">C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow\vstest.console.exe</VSTestExe>
      <VSTestFailBuildOnTestFail Condition=" '$(VSTestFailBuildOnTestFail)' == '' ">false</VSTestFailBuildOnTestFail>
      <VSTestInIsolation Condition=" '$(VSTestInIsolation)' == '' ">true</VSTestInIsolation>
      <VSTestUseVsixExtensions Condition=" '$(VSTestUseVsixExtensions)' == '' ">true</VSTestUseVsixExtensions>
      <VSTestFramework Condition=" '$(VSTestFramework)' == '' ">framework45</VSTestFramework>
      <VSTestLogger Condition=" '$(VSTestLogger)' == '' ">trx</VSTestLogger>
      <ErrorCode>0</ErrorCode>
    </PropertyGroup>
    <ItemGroup>
      <VSTestResultsPath Include="$(VSTestResultsPath)" />
      <VSTestParams Include="@(VSTestFiles ->'&quot;%(FullPath)&quot;', ' ')" />
      <VSTestParams Condition="$(VSTestEnableCodeCoverage)" Include="/EnableCodeCoverage" />
      <VSTestParams Condition="$(VSTestInIsolation)" Include="/InIsolation" />
      <VSTestParams Include="/UseVsixExtensions:$(VSTestUseVsixExtensions)" />
      <VSTestParams Include="/Framework:$(VSTestFramework)" />
      <VSTestParams Include="/Logger:$(VSTestLogger)" />
      <VSTestParams Condition="$(VSTestCaseFilter) != ''" Include="/TestCaseFilter:&quot;$(VSTestCaseFilter)&quot;" />
      <VSTestParams Condition="$(VSTestRunSettings) != ''" Include="/Settings:&quot;$(VSTestRunSettings)&quot;" />
    </ItemGroup>

    <Message Text="TestAssembly: %(VSTestFiles.Identity)" Importance="high"/>

    <Exec ContinueOnError="!$(VSTestFailBuildOnTestFail)" ConsoleToMSBuild="true" WorkingDirectory="$(WorkingDirectory)" Condition=" '@(VSTestFiles)' != ''" 
          Command="&quot;$(VSTestExe)&quot; @(VSTestParams, ' ')">
      <Output TaskParameter="ExitCode" PropertyName="ErrorCode"/>
      <Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
    </Exec>
    <Message Importance="high" Text="VSTest exitcode: $(ErrorCode)"/>

    <!-- Use the VSTest output to discover the Results & Coverage files respectively -->
    <PropertyGroup>
      <!-- Unencoded Regex: (?<=(Results file: )).*?(?=\;)|(?<=(Attachments:;)).*?(?=\;) -->
      <ResultsFileRegexPattern>(?&lt;=(Results File: )).*.trx</ResultsFileRegexPattern>
      <CoverageFileRegexPattern>(?&lt;=(Attachments:;)).*.coverage</CoverageFileRegexPattern>
      <SourceResultsFile>$([System.Text.RegularExpressions.Regex]::Match($(OutputOfExec), $(ResultsFileRegexPattern)))</SourceResultsFile>
      <SourceCoverageFile Condition="$(VSTestEnableCodeCoverage)">$([System.Text.RegularExpressions.Regex]::Match($(OutputOfExec), $(CoverageFileRegexPattern)))</SourceCoverageFile>
    </PropertyGroup>

    <ItemGroup>
      <TestArtifact Include="$(SourceResultsFile)" />
      <TestArtifact Include="$(SourceCoverageFile)" />
    </ItemGroup>

    <Warning Condition=" '$(SourceResultsFile)' == '' " Text=".trx file not found" />
    <Warning Condition=" $(VSTestEnableCodeCoverage) and '$(SourceCoverageFile)' == '' " Text=".coverage file not found" />

    <!-- Copy files to the artifact directory -->
    <Copy SourceFiles="@(TestArtifact)" DestinationFiles="@(TestArtifact->'$(ArtifactsPath)\$(VSTestSessionName)%(Extension)')" />

    <!-- Clear the test results temporary directory -->
    <RemoveDir Directories="@(TestResults)" />

    <ItemGroup>
      <TestFile Include="$(ArtifactsPath)\**\$(VSTestSessionName).trx" />
      <CoverageFile Include="$(ArtifactsPath)\**\$(VSTestSessionName).coverage" />
    </ItemGroup>

    <Message Text="TestReport: @(TestFile)" />
    <Message Text="CoverageReport: @(CoverageFile)" />
</Target>

Ответ 4

Это работало для меня для тестирования ядра .net. Я не пробовал его с .net framework:

vstest.console.exe [assembly] /logger:trx;LogFileName=[filename].trx

Возможно, это новая вещь