Сбой сборки, если покрытие кода ниже порога в TFS2012
Я пытаюсь сбить сборки в TFS Service (Hosted TFS2012), когда охват кода ниже порога.
Я возился с решением на http://scrumdod.blogspot.co.uk/2011/04/fail-build-if-code-coverage-is-low.html
Тем не менее, я использую TFS2012 и многое изменилось. В частности, конфигурация тестового прогона совершенно иная, и, похоже, нет никакого способа получить или установить местоположение и имя файла.coverage ни в шаблоне процесса сборки, ни в файле.runsettings.
Как мне найти (или установить) расположение файла.coverage в TFS2012 или TFSService?
С другой стороны, есть ли другой способ, которым я могу потерпеть неудачу при сборке, если покрытие кода ниже порога?
3 ответа
Это потребует нескольких шагов:
- Создать пользовательский процесс сборки
- Добавьте действие в контроллер сборки
- Вызов этой пользовательской операции сборки в новом процессе сборки
- Используйте новый процесс сборки
1. Создайте пользовательское действие по сборке.
Сделайте новый проект в VS2012 (я назвал мой CodeCoverageLibrary. Ссылка на следующие сборки:
- Microsoft.TeamFoundation.Build.Client
- Microsoft.TeamFoundation.Client
- Microsoft.TeamFoundation.TestManagement.Client
- Microsoft.TeamFoundation.WorkItemTracking.Client
- система
- System.Activities
- System.Core
- System.Xaml
Вы можете использовать следующий код:
using System;
using System.Activities;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.TestManagement.Client;
namespace CodeCoverageLibrary
{
[BuildActivity(HostEnvironmentOption.All)]
public sealed class GetCodeCoverage : CodeActivity<double>
{
public InArgument<IBuildDetail> BuildDetail { get; set; }
protected override double Execute(CodeActivityContext context)
{
var buildDetail = BuildDetail.Get(context);
var buildCoverages = GetBuildCoverages(buildDetail.BuildServer.TeamProjectCollection.Uri,
buildDetail.TeamProject, buildDetail.Uri);
return GetTotalCoverage(buildCoverages);
}
private static IEnumerable<IBuildCoverage> GetBuildCoverages(Uri uri, string projectName, Uri buildUri)
{
return TfsTeamProjectCollectionFactory.GetTeamProjectCollection(uri)
.GetService<ITestManagementService>()
.GetTeamProject(projectName)
.CoverageAnalysisManager.QueryBuildCoverage(buildUri.ToString(),
CoverageQueryFlags.Modules);
}
private static double GetTotalCoverage(IEnumerable<IBuildCoverage> buildCoverages)
{
int totalCoveredBlocks = 0, totalUncoveredBlocks = 0;
foreach (var buildCoverage in buildCoverages)
{
foreach (var module in buildCoverage.Modules)
{
totalCoveredBlocks += module.Statistics.BlocksCovered;
totalUncoveredBlocks += module.Statistics.BlocksNotCovered;
}
}
return (totalCoveredBlocks == 0 && totalUncoveredBlocks == 0)
? 0.0
: ((double) totalCoveredBlocks) /
((double) (totalCoveredBlocks + totalUncoveredBlocks));
}
}
}
Скомпилируйте проект и добавьте к пути с управлением версиями в TFS.
2. Добавьте действие в контроллер сборки
В Team Explorer выберите " Сборки" > " Действия" > " Управление контроллерами сборки". Затем нажмите Свойства... для контроллера сборки. Под Путь контроля версий для пользовательских сборок укажите путь, который вы использовали выше.
3. Запустите эту пользовательскую деятельность по сборке в процессе сборки.
Скопируйте BuildProcessTemplates\DefaultTemplate.11.1.xaml в новый файл.
Обновите начало нового файла XAML, включив в него следующее:
<Activity ...
xmlns:ccl="clr-namespace:CodeCoverageLibrary;assembly=CodeCoverageLibrary"
...
>
<x:Members>
...
<x:Property Name="CodeCoverageTolerance" Type="InArgument(x:Double)" />
</x:Members>
...
<this:Process.Metadata>
<mtbw:ProcessParameterMetadataCollection>
...
<mtbw:ProcessParameterMetadata BrowsableWhen="EditingDefinition" Category="#900 Misc" DisplayName="CodeCoverageTolerance" Description="If the overall code coverage drops below this threshold, then the build will fail. This is a number between 0 and 1." ParameterName="CodeCoverageTolerance" />
</mtbw:ProcessParameterMetadataCollection>
</this:Process.Metadata>
Обновите конец файла XAML, включив в него следующее:
<Sequence DisplayName="Code Coverage Check" mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="x:Double" Name="CodeCovered" />
</Sequence.Variables>
<ccl:GetCodeCoverage DisplayName="Getting Code Coverage" BuildDetail="[BuildDetail]" Result="[CodeCovered]" />
<If Condition="[CodeCovered < CodeCoverageTolerance]">
<If.Then>
<Sequence DisplayName="Comparing Code Coverage Against Tolerance">
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Failed" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" />
<mtbwa:WriteBuildError Message="["Code Coverage of " + CodeCovered.ToString("P") + " is less than required " + CodeCoverageTolerance.ToString("P")]" />
</Sequence>
</If.Then>
</If>
</Sequence>
</mtbwa:AgentScope>
<mtbwa:InvokeForReason DisplayName="Check In Gated Changes for CheckInShelveset Builds" Reason="CheckInShelveset">
<mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" />
</mtbwa:InvokeForReason>
</Sequence>
</Activity>
Проверьте это в TFS.
4. Используйте новый процесс сборки
В Team Explorer перейдите в Builds и щелкните правой кнопкой мыши по определению вашей сборки. Перейдите в Изменить определение сборки... > Процесс. Разверните шаблон процесса сборки и нажмите " Создать". Нажмите Выбрать существующий файл XAML и укажите путь к новому файлу XAML. Нажмите ОК. Теперь вы должны увидеть CodeCoverageTolerance под 4. Разное. Вы можете ввести число от 0 до 1, чтобы указать желаемый процент.
Только одна вещь в решении выше, вы должны изменить расчет так, чтобы процентное значение возвращалось с двумя десятичными разрядами.
return (totalCoveredBlocks == 0 && totalUncoveredBlocks == 0)
? 0.0
: Math.Round(((double)totalCoveredBlocks) /
((double)(totalCoveredBlocks + totalUncoveredBlocks)) * 100, 2);
Вы можете добавить свое действие после действия RunTests, в котором вы можете запросить сборку для вложений покрытия кода и объединить и проанализировать файлы.coverage, чтобы пропустить / не выполнить сборку.