Заметки консультанта

Шамрай Александр Владимирович

Archive for the ‘Team Foundation Server’ Category

Обновление Wiki страниц Azure DevOps через PowerShell и Rest Api

Posted by Shamrai Alexander на 25 марта, 2021

Часто есть необходимо автоматически создавать страницы в Wiki репозитории, например, для целей:

  • Отчетности по итерациям
  • Состава релиза
  • И других отчетных задач

Создание страницы выполняется довольно просто через Rest Api запрос Pages — Create Or Update. Но если через этот же запрос попытаться обновить страницу, то в результате сгенерируется исключение:

{«$id»:»1″,»innerException»:null,»message»:»The page ‘/PageName.md’ specified in the add operation already exists in the wiki. Please specify a new page path.»,»typeName»:»Microsoft.TeamFoundation.Wiki.Server.WikiPageAlreadyExistsException, Microsoft.TeamFoundation.Wiki.Server»,»typeKey»:»WikiPageAlreadyExistsException»,»errorCode»:0,»eventId»:3000}

Связанно это с тем, что при обновлении запросу необходимо передавать Etag в заголовках запроса. Etag можно получить через запрос Rest Api Pages — Get Page, который возвращает его в заголовках. Пример:

$restApiUpdateWikiPut = «$orgUrl/$teamProject/_apis/wiki/wikis/$wikiRepoName/pages?path={path}&api-version=6.1-preview.1»

function InvokeGetETag ($GetUrl)

{

$Headers = $null

Invoke-RestMethod -Uri $GetUrl -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)} -ResponseHeadersVariable ‘Headers’

return $Headers[«ETag»]

}

$updateUrl = $restApiUpdateWikiPut.Replace(«{path}», $wkPagePath)

$eTagRaw = InvokeGetETag $updateUrl

$ETag = $eTagRaw -join «»

Далее Etag нужно добавить в заголовки запроса для обновления страницы в виде «If-Match»=»eTag»:

$restApiUpdateWikiPut = «$orgUrl/$teamProject/_apis/wiki/wikis/$wikiRepoName/pages?path={path}&api-version=6.1-preview.1»

function InvokePutRequest ($PutUrl, $body, $eTag)

{

return Invoke-RestMethod -Uri $PutUrl -Method Put -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo);»If-Match»=»$eTag»} -Body $body

}

InvokePutRequest $updateUrl $wikiContentUpdate $eTag

Пример PowerShell скрипта для создания и обновления wiki страниц можно найти здесь:

https://github.com/ashamrai/AzureDevOpsExtensions/blob/master/CustomPSTasks/UpdateWikiPage.ps1

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio | Отмечено: , | Leave a Comment »

Экспорт и импорт запросов по рабочим элементам Azure DevOps между проектами через Rest API

Posted by Shamrai Alexander на 9 февраля, 2021

Каждая организация может иметь какой-то полезный набор запросов рабочим элементам, который хотелось бы перенести в другой проект. Стандартная процедура переноса в себя включает редактирование и сохранение запроса через Visual Studio. Однако, когда запросов много, ручной перенос может быть длительным. Этот вариант можно автоматизировать с помощью Rest API и PowerShell, например:

  1. Экспорт и импорт запросов через файловую систему. Имеет смысл для копирования между организациями.
  2. Копирование запросов между проектами в рамках одной организации.

Для работы примеров ниже нужно сгенерировать персональный маркер доступа для каждой организации Azure DevOps: Use personal access tokens.

Экспорт и импорт через файловую систему

Получить информацию о запросах по рабочим элементам можно с помощью Get метода: Queries – List. Запрос в адресе принимает только каталог, который нужно проверить на наличие дочерних запросов или вложенных каталогов с запросами после ключевого слова queries. В рамках ответа основными параметрами для экспорта является wiql запрос и наименование запроса. Пример сохранения запросов в файловую систему:

$queriesUrl = «$orgUrl/$teamProject/_apis/wit/queries/$sourceQueryFolder»+»?`$depth=1&`$expand=all&api-version=5.0″

 

function InvokeGetRequest ($GetUrl)

{

return Invoke-RestMethod -Uri $GetUrl -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

}

$resQuries = InvokeGetRequest $queriesUrl

if (![System.IO.Directory]::Exists($targetLocalFolder))

{

New-Item -Path $targetLocalFolder -ItemType «directory»

}

if ($resQuries.isFolder -and $resQuries.hasChildren)

{

foreach($item in $resQuries.children)

{

if (!$item.isFolder)

{

$queryJson = «{`»name`»:`»{queryname}`», `»wiql`»:`»{querywiql}`»}»

$queryJson = $queryJson -replace «{queryname}», $item.name

$queryJson = $queryJson -replace «{querywiql}», $item.wiql

$filepath = «$targetLocalFolder/» + $item.name

Set-Content -Path $filepath -Value $queryJson

}

}

}

Создание запросов по рабочим элементам выполняется с помощью Queries – Create, которому нужно передать наименование нового запроса, его содержимое и, по необходимости, сортировку колонок. Пример создания запроса на основе выгрузки выше:

$queriesUrl = «$orgUrl/$teamProject/_apis/wit/queries/$targetQueryFolder»+»?api-version=5.0″

function InvokePostRequest ($PostUrl, $body)

{

return Invoke-RestMethod -Uri $PostUrl -Method Post -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)} -Body $body

}

$files = Get-ChildItem -File -Path $sourceLocalFolder

foreach($wiqlfile in $files)

{

$wiqlBody = Get-Content $wiqlfile

InvokePostRequest $queriesUrl $wiqlBody

}

Копирование между проектами

Копирование между проектами выполнить проще, т.к. нужно просто получить запрос по рабочим элементам и создать новый с такими же параметрами. В примере ниже выполняется копирование наименования, wiql запроса, набора колонок и их сортировку:

$queriesPostUrl = «$orgUrl/$teamProjectTarget/_apis/wit/queries/$targetQueryFolder»+»?api-version=5.0″

$queriesGettUrl = «$orgUrl/$teamProjectSource/_apis/wit/queries/$sourceQueryFolder»+»?`$depth=1&`$expand=all&api-version=5.0″

function InvokeGetRequest ($GetUrl)

{

return Invoke-RestMethod -Uri $GetUrl -Method Get -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)}

}

function InvokePostRequest ($PostUrl, $body)

{

return Invoke-RestMethod -Uri $PostUrl -Method Post -ContentType «application/json» -Headers @{Authorization=(«Basic {0}» -f $base64AuthInfo)} -Body $body

}

$resQuries = InvokeGetRequest $queriesGettUrl

if ($resQuries.isFolder -and $resQuries.hasChildren)

{

foreach($item in $resQuries.children)

{

if (!$item.isFolder)

{

$queryObject.name = $item.name

$queryObject.wiql = $item.wiql

$queryObject.columns = $item.columns

$queryObject.sortcolumns = $item.sortcolumns

$wiqlbody = ConvertTo-Json $queryObject -Depth 10

InvokePostRequest $queriesPostUrl $wiqlBody

}

}

}

 

Исходники скриптов:

 

Posted in azure, devops, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , | Leave a Comment »

Обновление Azure DevOps сервер до 2020

Posted by Shamrai Alexander на 18 января, 2021

Шаги обновления:

  1. Перед обновлением необходимо проверить, что системные и программные требования соответствуют целевой версии: Requirements for Azure DevOps on-premises.
  2. Также необходимо выполнить резервное копирование баз данных конфигурации и коллекций. Если используется сервер отчетности, то базы отчетности. Ключ сервера отчетности тоже желательно скопировать. Хотя базы данных отчетности всегда можно пересобрать.
  3. Теперь можно выполнять обновление сервера. Для этого нужно запустить AzureDevOps2020.exe с диска установки.

  1. В окне выбора пути установки необходимо нажать кнопку Install.

  1. Дождаться развертывания нового сервера.

  1. После развертывания необходимо выполнить перезагрузку.

  1. После перезагрузки запустится мастер настройки, в котором нужно нажать кнопку Next.

  1. Далее необходимо выбрать тип развертывания на существующие базы данных.

  1. Указать имя сервера баз данных и выбрать базу конфигурации для обновления. При этом нужно подтвердить, что выполнено резервное копирование необходимых баз данных.

  1. На следующем шаге необходимо выбрать сценарий обновления (продуктивный или тестирование обновления).

  1. Указать имя сервисной учетной записи, от которой будет работать сервер

  1. Указать порт веб-сервиса и необходимость использование ssh протокола.

  1. Если Вы планируете использовать компоненты поиска, то необходимо указать параметры службы.

  1. Если необходимо выполнить конфигурирование сервиса отчетности, то необходимо выбрать пункт Configure Reporting for use with Azure DevOps Server.

  1. На следующие шаге указываем имя сервера отчетности и нажимаем кнопку Populate URLs

  1. Далее необходимо выбрать базу данных отчетности.

  1. На следующем шаге необходимо указать сервер аналитики.

  1. Далее необходимо указать учетную запись для подключения к базе данных отчетности на сервере отчетов.

  1. На шаге Review необходимо нажать кнопку Verify.

  1. После проверки конфигурации, мастер обновления может показать предупреждения. Предупреждения будут отличаться в зависимости от предыдущей версии Azure DevOps. С предупреждения необходимо согласиться и нажать кнопку Configure.

  1. Далее необходимо дождаться окончания конфигурирования сервисов:

  1. После выполнения конфигурирования необходимо нажать кнопку Next для обновления баз коллекция проектов.

  1. После обновления коллекций проектов необходимо нажать кнопку Next.

  1. Обновление завершено.

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio | Отмечено: | Leave a Comment »

Автоматизация удаления тегов и ветвей в репозитории Azure DevOps Git

Posted by Shamrai Alexander на 18 декабря, 2020

Центральные репозитории со временем «раздуваются» и начинают включать в себя теги, ветви, которые не несут в себе никакой полезной информации. Вернуться на тег, который был год назад, конечно можно…, но зачем, когда код уже ушел далеко? Хотя этот вопрос уже каждая команда решается для себя сама, например, если необходимо хранить важные вехи проекта. Но в общем, когда заходишь в раздел ветвей или тегов и видишь длинный список объектов, и искать возможно только через ключевые слова, то глаз это не радует. Кроме этого, начинает увеличиваться время изъятия репозитория не только из-за количества коммитов, но и из-за множества ветвей и тегов. Основные причины роста их количества можно выделить следующие:

  1. Разработчики забывают удалять ветви с фичами после слияния изменений, даже если есть автоматизация такого процесса.
  2. Разработчик перешел в другую команду, компанию, и тут точно за собой ничего чистить не будет.
  3. Создаются различные временные ветви для выпусков, экспериментов, которые потом никогда не сливаются в основной поток.
  4. Сборки метят наш код в качестве непрерывной интеграции.
  5. И т.д.

Удаление можно выполнить на основе Rest Api и ниже описаны некоторые шаги для достижения результата.

Получить список объектов для анализа

Набор ветвей и тегов, которые есть в репозитории, можно получить через вызов Refs – List:

  1. Для получения ветвей, нужно установить фильтр «heads/»
  2. Для получения тегов, ставим фильтр «tags/»

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

Понять, что удалять

Конечно, главным признаком для удаления будет дата:

  1. Для тегов: дата коммита, на котором он висит.
  2. Для ветвей: дата последнего коммита в нем.

Для того, чтоб получить дату коммита тега, необходимо выполнить получение описание тега Annotated Tags – Get, при этом используем objectId как идентификатор тега. Но для некоторых тегов будем получать исключение в виде «Expected a Tag, but objectId resolved to a Commit». Это теги, которые были применены сборками, что описано здесь: «Expected a Tag, but objectId resolved to a Commit» when using «annotatedtags» REST API. Т.е. если мы не получаем такое исключение при запросе информации о теге, то используем дату из его результата taggedBy.date. Если же есть исключение, то придется обратится к коммиту с тем же objectId через запрос Commits – Get. В коммите ищем свойство committer.date.

Чтобы получить дату последних изменений в ветке, нам также необходимо получить информацию о коммите через запрос Commits – Get и свойство objectId. В качестве даты также используем свойство committer.date. Но для ветвей есть еще дополнительные моменты:

  1. Ветвь заблокирована. Информация о блокировке ветви находится в ее свойстве isLocked.
  2. Ветвь имеет дополнительные правила. Тут необходимо выполнить запрос для получения правил для ветви: Policy Configurations – Get. Если там есть хоть что-то, то ветвь игнорируем.
  3. Ветвь может иметь не влитые изменения. Тут нам поможет запрос Diffs – Get, где как baseVersion будем использовать master, а для targetVersion установим путь для нашей ветви, который можно выделить из свойства name. Если свойство aheadCount имеет какие-то значения, значит эту ветвь тоже желательно пропустить.

Удалить тег или ветвь

Для удаления теги или ветви необходимо использовать Refs — Update Ref и свойство objectId. При этом тело этого запроса будет сдержать сброс свойства ObjectId к значению «0000000000000000000000000000000000000000». Описание этого можно найти здесь: Delete Tags or Branches using rest apis.

Пример исходного кода решения

PowerShell скрипт, который реализует все описанное выше, можно посмотреть здесь: https://github.com/ashamrai/AzureDevOpsExtensions/blob/master/CustomPSTasks/CleanUpTagsBranches.ps1

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

Дополнительные настройки

Если у вас участники процесса публикуют свои теги в общий репозиторий через операцию push, то им придется от этого отказаться. Дело в том, что удаление тегов из общего репозитория не приводит к их удалению локально, т.е. публикация снова вернет все теги. У участников придется забрать право на публикацию тегов:

Рисунок 1. Право на создание тегов в репозитории

Если планируется использовать скрипт через сборку, то для группы сервисов сборки коллекции необходимо будет выдать право на участие и перезапись изменений:

Рисунок 2. Разрешение на перезапись изменений

Эта проблема обсуждалась здесь: the build agent doesn’t have enough permission to perform a git push !

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , | 1 Comment »

Azure DevOps Rest Api. 25. Создание нового релиза

Posted by Shamrai Alexander на 12 апреля, 2020

Для работы с релизами необходим дополнительный пакет Microsoft.VisualStudio.Services.Release.Client, который содержит клиент ReleaseHttpClient. С его помощью здесь мы выполним следующие операции:

  • Создание нового релиза с параметрами по умолчанию
  • Просмотр состояния релиза и каждой его среды
  • Скачивание журнала развертывания релиза

Создание нового выполняется с помощью метода CreateReleaseAsync, которому передаются два основных параметра:

  1. Метаданные релиза
  2. Наименование релиза

Метаданные релиза описываются объектом класса ReleaseStartMetadata, который имеет важное свойство DefinitionId – идентификатор определения релиза. Результатом создания релиза является объект класса Release, который содержит идентификатор нового релиза и описание его состояния. Пример создания релиза:

private static int CreateRelease(string teamProjectName, int releaseDefId)

{

ReleaseStartMetadata startMetadata = new ReleaseStartMetadata();

startMetadata.DefinitionId = releaseDefId;

startMetadata.Description = «Start from command line»;

var release = ReleaseClient.CreateReleaseAsync(startMetadata, teamProjectName).Result;

return release.Id;

}

Чтобы получить текущее состояние релиза, можно выполнить метод GetReleaseAsync, который принимает два параметра: идентификатор релиза и наименование командного проекта. Результатом выполнения метода является объект класса Release. Состояние релиза можно найти через свойство Status. Также полезным будет свойство Environments, которое содержит перечень сред для развертывания. Каждая среда содержит свойство Name (наименование) и Status (состояние). Пример получения состояния релиза:

private static void CheckStatus(string teamProjectName, int releaseId)

{


var release = ReleaseClient.GetReleaseAsync(teamProjectName, releaseId).Result;

Console.WriteLine(«\nStatus: « + release.Status + «\nEnvironments:»);

foreach(var env in release.Environments)

{

Console.Write(env.Name + » : « + env.Status + «; «);

}

}

Чтобы получить журнал выполнения, необходимо выполнить метод GetLogsAsync, который принимает два параметра: наименование командного проекта и идентификатор релиза. Результатом выполнения является поток данных, который можно сохранить в zip файл. Пример получение журнала развертывания релиза:

private static void DownloadReleaseLogs(string teamProjectName, int releaseId)

{

Stream logReader = ReleaseClient.GetLogsAsync(teamProjectName, releaseId).Result;

using (var fileStream = new FileStream(«C:\\Temp\\rel_» + releaseId + «_logs.zip», FileMode.Create))

{

logReader.CopyTo(fileStream);

}

}

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/25.TFRestApiAppCreateRelease

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio | Отмечено: , | Leave a Comment »

Сборка дельта-пакетов с помощью Azure DevOps Pipeline и GIT

Posted by Shamrai Alexander на 31 января, 2020

В общих случаях результатами сборки являются скомпилированные исполняемые файлы, библиотеки или опубликованные для развертывания веб-решения. Однако встречаются потребности, когда необходимо опубликовать только изменившиеся файлы, например для статического сайта, пакета обновления Salesforce и т.д. В этом случае стандартные шаги сборки не подходят и нужно общаться с системой версионного контроля, чтобы получить необходимую информацию.

Какие шаги нам необходимо будет здесь выполнить? Рассмотрим возможные на основе непрерывной интеграции:

  1. Получить список файлов, которые изменились от предыдущей версии.
  2. Скопировать измененные файлы.

Получить список измененных файлов

Список изменившихся от последней версии нужно получать, исходя из системы ветвления и поставки изменений. Например, если выполняется разработка в отдельных ветвях и слияние в основной поток выполняется одним коммитом (через стандартный мерж), то достаточно сравниться с предыдущим коммитом. Однако, если выполняется работа в одном потоке или выполняется слияние с перебазированием, то тут желательно выставить для сборки установку тега и сравниваться между последним коммитом и последним тегом.

Рисунок 1. Установка тега в сборке

Для того, чтобы сравнить с последним комитом, необходимо выполнить следующую команду на агенте сборки через PowerShell:

$changes = git diff —name-only —relative —diff-filter AMR HEAD^ HEAD .

В случае с тегами, стоит сначала найти последний тег, а потом уже выполнять сравнение:

$last_tag = git describe —tags —abbrev=0 —match «[0-9]*»

$changes = git diff —name-only —relative —diff-filter AMR $last_tag HEAD .

Скопировать измененные файлы

Чтобы скопировать файлы с сохранением структуры, можно использовать команды New-Item и copy-item для форсирования создания структуры каталогов. При этом как целевая директория будет каталог для артефактов на агенте сборки. Пример:

$targetfolder = «$(Build.StagingDirectory)» + «/»

function CopyFiles{

param( [string]$source )

$target = $targetfolder + $source

New-Item -Force $target

copy-item $source $target -Force

}

В результате шаг в сборке может выглядеть следующим образом:

Рисунок 2. Шаг копирования изменившихся файлов

Далее необходимо добавить финальный шаг публикации артефактов:

Рисунок 3. Публикация артефактов

Скрипты для копирования файлов можно найти здесь:

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio | Отмечено: , | 1 Comment »

Azure DevOps Rest Api. 20. Просмотр определений сборки для командного проекта

Posted by Shamrai Alexander на 10 июня, 2019

Для управление сборками используется клиент BuildHttpClient. В рамках данный статьи мы рассмотрим методы для получения всех определений сборок и просмотра их последних запусков.

Для получения всех определений сборок командного проекта используется метод GetDefinitionsAsync, которому необходимо передать только наименование командного проекта. Результатом выполнения метода является список доступных определений сборки. Каждое определение сборка содержит следующие полезные атрибуты:

  • Id – идентификатор определения сборки
  • Name – наименование определения сборки
  • Path – путь, по которому храниться определение сборки
  • Revision– версия определения сборки
  • Queue – очередь, в которую поставлена сборка
  • QueueStatus – состояние сборки в очереди

Пример получения списка определений сборки:

List<BuildDefinitionReference> buildDefs = BuildClient.GetDefinitionsAsync(TeamProjectName).Result;

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

  • Id – идентификатор сборки
  • BuildNumber – номер сборки
  • Status – состояние сборки
  • StartTime – время старта процесса сборки
  • FinishTime – время завершения процесса сборки

Пример получения списка сборок для конкретного определения сборки:

List<Build> builds = BuildClient.GetBuildsAsync(TeamProjectName, new List<int> { buildDef.Id }).Result;

Дополнительно для каждой сборки можно получить список комитов, которые были основой для ее создания, через метод GetBuildChangesAsync:

var changes = BuildClient. GetBuildChangesAsync(TeamProjectName, builds[i].Id).Result;

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/20.TFRestApiAppExploreBuildDefinitions

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , | Leave a Comment »

Azure DevOps Rest Api. 14. Создание и добавление тестовых сценариев

Posted by Shamrai Alexander на 11 мая, 2019

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Примечание: На основе Microsoft.TeamFoundationServer.Client 16.150.0-preview

Создание тестового сценария

Примечание: На момент написания статьи не существовало официальных задокументированных возможностей для создания тестовых сценариев через Rest Api. Ниже описанное о тестовых шагах получено опытным путем.

Клиент TestPlanHttpClient не содержит каких-либо методов для создания тестовых сценариев. Тестовые сценарии создаются как обычные рабочие элементы через клиент WorkItemTrackingHttpClient (см. Создание и редактирование рабочих элементов). Особенностью является формирование шагов тестирования и параметров для них.

Структура содержимого шагов тестирования в сценарии

Шаги тестирования содержатся в поле Microsoft.VSTS.TCM.Steps в следующем формате:

<steps id=»0″ last=»{LAST_STEP_ID}»>

<step type=»ActionStep» id=»{STEP_ID}»>

<parameterizedString isformatted=»true»>{ACTION_DESCRIPTION}</parameterizedString>

<parameterizedString isformatted=»true»></parameterizedString>

</step>

<step type=»ValidateStep» id=»{STEP_ID}»>

<parameterizedString isformatted=»true»>{ ACTION _DESCRIPTION}</parameterizedString>

<parameterizedString isformatted=»true»>{VALIDATION_DESCRIPTION}</parameterizedString>

</step>

</steps>

Тут можно выделить следующие атрибуты:

  1. {LAST_STEP_ID} – идентификатор последнего шага.
  2. type – тип шага. Если установлено значение ActionStep, то заполняется только содержимое для первой строки шага(parameterizedString), содержимое второй строки остается пустым. Если же установлено ValidateStep, то обе строки заполняются.
  3. {STEP_ID} – порядковый номер шага. Отсчет начинается с 2.
  4. {ACTION_DESCRIPTION} – описание действий в шаге.
  5. {VALIDATION_DESCRIPTION} – описание проверок правильного выполнения шага.

Структура содержимого параметров шагов тестирования

Если тестовый сценарий не использует локальные параметры, то этот пункт можно упустить. Описание параметров разделяется на две части:

  1. Описание набора параметров.
  2. Описание значений параметров.

Описание набора параметров

Набор параметров содержится в поле Microsoft.VSTS.TCM.Parameters в следующем виде:

<parameters>

<param name=»param1″ bind=»default»/>

<param name=»param2″ bind=»default»/>

</parameters>

Т.е. для каждого параметра в блоке parameters описывается строка <param name=»ИМЯ_ПАРАМЕТРА» bind=»default»/>.

Описание значений параметров

Набор параметров содержится в поле Microsoft.VSTS.TCM.LocalDataSource в следующем виде:

<NewDataSet>

<xs:schema id=’NewDataSet’ xmlns:xs=’http://www.w3.org/2001/XMLSchema&#8217; xmlns:msdata=’urn:schemas-microsoft-com:xml-msdata’>

    <xs:element name=’NewDataSet’ msdata:IsDataSet=’true’ msdata:Locale=»>

        <xs:complexType>

<xs:choice minOccurs=’0′ maxOccurs = ‘unbounded’>

            <xs:element name=’Table1′>

<xs:complexType>

                <xs:sequence>

                    <xs:element name=’param1′ type=’xs:string’ minOccurs=’0′ />

                    <xs:element name=’param2′ type=’xs:string’ minOccurs=’0′ />

                </xs:sequence>

            </xs:complexType>

        </xs:element>

    </xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

<Table1><param1>value1</ param1>< param2>value2</ param2></Table1>

<Table1>< param1>value3</ param1>< param2>value4</ param2></Table1>

</NewDataSet>

Т.е. это описание набора данных с его содержимым. Для каждого нового параметра необходимо в разделе <xs:sequence> добавить новую строку с описанием параметра: <xs:element name=’ИМЯ_ПАРАМЕТРА’ type=’xs:string’ minOccurs=’0′ /> .

Далее внизу в таблице <Table1> прописываются значения для каждого из параметров. Сколько новых строк будет в таблице – столько итераций тестирования будет запускать мастер выполнения тестовых сценариев.

Пример генерирования содержимого тестовых шагов и параметров находится в файле в TestStepsHelper.cs тестового решения ниже.

Создание сценарий тестирования с его применением может выглядеть следующим образом:

Dictionary<string, object> fields = new Dictionary<string, object>();
LocalStepsDefinition stepsDefinition = new LocalStepsDefinition();
stepsDefinition.AddStep(«Run Application»);

stepsDefinition.AddStep(«Enter creds @user_name @user_password»);

stepsDefinition.AddStep(«Check available functions», «Functions for: @user_role»);

LocalTestParams testParams = new LocalTestParams();

testParams.AddParam(«user_name», new string[] { «admin», «user», «manager» });

testParams.AddParam(«user_password», new string[] { «admin_pswrd», «user_pswrd», «manager_pswrd» });

testParams.AddParam(«user_role», new string[] { «Administrator», «Local User», «Shop Manager» });

fields.Add(«Title», «new test case»);

fields.Add(FieldSteps, stepsDefinition.StepsDefinitionStr);

fields.Add(FieldParameters, testParams.ParamDefinitionStr);

fields.Add(FieldDataSource, testParams.ParamDataSetStr);

CreateWorkItem(TeamProjectName, «Test Case», fields);

А выполнение шагов будет отображаться так:

Рисунок 1. Выполнение теста

Добавление тестового сценария в существующий набор тестов

Тестовые сценарии могут быть добавлены только в статический набор тестов или набор тестов для требования. Для добавления используется метод AddTestCasesToSuiteAsync клиента TestPlanHttpClient с параметрами: список экземпляров класса SuiteTestCaseCreateUpdateParameters, который описывает ссылку на рабочий элемент теста; наименование командного проекта; идентификатор плана тестирования для новых тестовых сценариев и идентификатор набора тестов. Класс SuiteTestCaseCreateUpdateParameters содержит два атрибута (workItem и PointAssignments), мы будем использовать только атрибут workItem для создания ссылки на рабочий элемент. Пример:

TestSuite testSuite = TestPlanClient.GetTestSuiteByIdAsync(TeamProjectName, TestPlanId, testSuiteId).Result;
if (testSuite.SuiteType == TestSuiteType.StaticTestSuite || testSuite.SuiteType == TestSuiteType.DynamicTestSuite)
{

List<SuiteTestCaseCreateUpdateParameters> suiteTestCaseCreateUpdate = new List<SuiteTestCaseCreateUpdateParameters>();


foreach (int testCaseId in TestCasesIds)

suiteTestCaseCreateUpdate.Add(new SuiteTestCaseCreateUpdateParameters()

{

workItem = new Microsoft.VisualStudio.Services.TestManagement.TestPlanning.WebApi.WorkItem()

{

Id = testCaseId

}

});

TestPlanClient.AddTestCasesToSuiteAsync(suiteTestCaseCreateUpdate, TeamProjectName, TestPlanId, testSuiteId).Wait();

}

else

Console.WriteLine(«The Test Suite ‘» + StaticSuitePath + «‘ is not static or requirement»);

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/14.TFRestApiAppCreateAndAddTestCase

Posted in azure, devops, Microsoft, Team Foundation Server, Visual Studio, visual studio team services | Отмечено: , | Leave a Comment »

Azure DevOps Rest Api. 13. Создание плана тестирования и наборов тестов

Posted by Shamrai Alexander на 11 мая, 2019

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Примечание: На основе Microsoft.TeamFoundationServer.Client 16.150.0-preview

Создание плана тестирования

План тестирования создается с помощью метода CreateTestPlanAsync из клиента TestPlanHttpClient. Данный метод принимает только два параметра:

  • Объект класса TestPlanCreateParams, который описывает основные параметры плана тестирования.
  • И имя командного проекта.

Класс TestPlanCreateParams включает следующие атрибуты, которые интересуют нас при создании на данном этапе:

  • Name – наименование нового плана тестирования
  • StartDate – дата начала плана тестирования в виде строки
  • EndDate – дата окончания плана тестирования в виде строки
  • AreaPath – путь области
  • Iteration – путь итерации

Пример создания плана тестирования:

TestPlanCreateParams newPlanDef = new TestPlanCreateParams()
{

Name = TestPlanName,

StartDate = StartDate,

EndDate = FinishDate,

AreaPath = AreaPath,

Iteration = IterationPath

};

return TestPlanClient.CreateTestPlanAsync(newPlanDef, TeamProjectName).Wait();

Создание тестового набора

Создание тестового набора выполняется схожим методом с созданием плана тестирования, т.е. через отдельный объект, который описывает свойства нового набора тестов. Этот объект описывается классом TestSuiteCreateParams, который включает атрибуты:

  1. SuiteType – тип набор тестирования, который может быть одним из значений перечисления TestSuiteType:
    1. StaticTestSuite – статический набор тестов, который может включать дочерние наборы тестов и тестовые сценарии.
    2. DynamicTestSuite – динамический набор тестов, который содержит тесты, отобранные его запросом через атрибут queryString.
    3. RequirementTestSuite – набор тестов, который ассоциируется с рабочим элементов группы требований и может содержать только тестовые сценарии.
  2. Name – наименование нового набора тестов.
  3. QueryString – WIQL запрос для отбора тестов для динамического набора тестов.
  4. RequirementId – идентификатор рабочего элемента группы требований, для которого будет создан тестовый набор с типом RequirementTestSuite.
  5. ParentSuite – родительский набор тестов, который описывается экземпляром класса TestSuiteReference. Класс TestSuiteReference содержит атрибут Id, которому присваивается идентификатор родительского набора тестов.

Создание тестового набора выполняется с помощью метода CreateTestSuiteAsync, в который передаются:

  1. Экземпляр класса TestSuiteCreateParams.
  2. Наименование командного проекта.
  3. Идентификатор плана тестирования, в котором будет создан новый набор тестов.

Прим создания набора тестов:

TestSuiteCreateParams newSuite = new TestSuiteCreateParams()
{

Name = TestSuiteName,

SuiteType = SuiteType,

QueryString = SuiteQuery,

RequirementId = RequirementId,

ParentSuite = new TestSuiteReference() { Id = parentsuiteId }

};

TestSuite testSuite = TestPlanClient.CreateTestSuiteAsync(newSuite, TeamProjectName, TestPlanId).Result;

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/13.TFRestApiAppCreateTestPlanAndSuites

Posted in Microsoft, Team Foundation Server, Team Foundation Server FAQ, Visual Studio, visual studio team services | Отмечено: , | Leave a Comment »

Azure DevOps Rest Api. 12. Просмотр содержимого плана тестирования

Posted by Shamrai Alexander на 23 апреля, 2019

<< Перейти в радел «Azure DevOps Services (TFS/VSTS) Rest Api»

Примечание: На основе Microsoft.TeamFoundationServer.Client 16.150.0-preview

Для работы с объектами тестирования используется клиент TestPlanHttpClient (пространство имен Microsoft.VisualStudio.Services.TestManagement.TestPlanning.WebApi). В рамках планирования тестирования используются следующие основные объекты:

  1. План тестирования – класс TestPlan. Он содержит в основном информацию о названии, планируемых датах тестирования и т.д.
  2. Набор тестов – класс TestSuite. Содержит дочерние наборы, а также сценарии тестирования. Наборы тестов могут быть статическими, наборам для требований (т.е. ссылаются на конкретное требование) и динамическими (на основе запроса по рабочим элементам).
  3. Тестовый сценарий – класс TestCase. Содержит информацию о рабочем элементе тестового сценария, тестировщике и конфигурации для тестирования.

Для того, чтобы получить информацию о всех объектах тестирования, необходимо:

  1. Получить план тестирования.
  2. Получить дерево наборов тестов плана тестирования.
  3. Получить содержимое набора тестов, т.е. тестовые сценарии.

Для получения тестового сценария используется метод GetTestPlanByIdAsync с использованием имени командного проекта и идентификатора. Идентификатор можно увидеть через интерфейс:

Рисунок 1. Редактирование плана тестирование

Рисунок 2. Идентификатор плана тестирования

Набор планов тестирования с использованием имени командного проекта можно получить через метод GetTestPlansAsync, который вернет список List планов тестирования.

Пример получения плана тестирования и его свойств:

TestPlan testPlan = TestPlanClient.GetTestPlanByIdAsync(TeamProjectName, TestPlanId).Result;

Console.WriteLine(«================================================================»);

Console.WriteLine(«Test Plan : {0} : {1} : {2}», testPlan.Id, testPlan.State, testPlan.Name);

Console.WriteLine(«Area Path : {0} : Iteration Path : {1}», testPlan.AreaPath, testPlan.Iteration);

Console.WriteLine(«Plan Dates : {0} — {1}»,

(testPlan.StartDate.HasValue) ? testPlan.StartDate.Value.ToShortDateString() : «none»,

(testPlan.EndDate.HasValue) ? testPlan.EndDate.Value.ToShortDateString() : «none»);

Дерево наборов тестов для плана тестирования можно получить через метод GetTestSuitesForPlanAsync, который использует наименование проекта, идентификатор плана тестирования. Пример получения дерева набора тестов и просмотра его структуры:

List<TestSuite> suitesDetail = TestPlanClient.GetTestSuitesForPlanAsync(TeamProjectName, TestPlanId, asTreeView: true).Result;

ExploreTestSuiteTree(TeamProjectName, TestPlanId, suitesDetail, «»);

static
void ExploreTestSuiteTree(string TeamProjectName, int TestPlanId, List<TestSuite> SuitesSubTree, string ParentPath)

{

foreach (TestSuite testSuite in SuitesSubTree)

{

PrintSuiteInfo(testSuite, ParentPath);

if (testSuite.HasChildren) ExploreTestSuiteTree(TeamProjectName, TestPlanId, testSuite.Children, ParentPath + «\\» + testSuite.Name);

}

}

static
void PrintSuiteInfo(TestSuite Suite, string ParentPath)

{

Console.WriteLine(«================================================================»);

Console.WriteLine(«Test Suite : {0} : {1}», Suite.Id, Suite.Name);

Console.WriteLine(«Suite Type : {0} : {1}», Suite.SuiteType,

(Suite.SuiteType == TestSuiteType.StaticTestSuite) ? «» :

(Suite.SuiteType == TestSuiteType.DynamicTestSuite) ? «\nQuery: « + Suite.QueryString : «Requirement ID « + Suite.RequirementId.ToString());


if (Suite.ParentSuite == null) Console.WriteLine(«This is a root suite»);


else Console.WriteLine(«Parent Path: « + ParentPath);

Console.WriteLine(«—————————————————————-«);

}

Список тестов в наборе тестов можно получить через метод GetTestCaseListAsync, который использует наименование проекта, идентификатор плана тестирования и идентификатор набора тестирования. Кроме этого, тестовый сценарий содержит идентификатор рабочего элемента и его поля. Пример получения списка тестов и свойств рабочих элементов:

List<TestCase> testCases = TestPlanClient.GetTestCaseListAsync(TeamProjectName, TestPlanId, testSuite.Id).Result;

if (testCases.Count > 0)

{

foreach (TestCase testCase in testCases)

{

Console.WriteLine(«Test: {0} — {1}», testCase.workItem.Id, testCase.workItem.Name);

var wiFields = GetWorkItemFields(testCase.workItem.WorkItemFields);

if (wiFields.ContainsKey(«System.State»))

Console.WriteLine(«Test Case State: {0}», wiFields[«System.State»].ToString());


foreach (var config in testCase.PointAssignments)

Console.WriteLine(«Run for: {0} : {1}», config.Tester.DisplayName, config.ConfigurationName);

}

}

private
static Dictionary<string, object> GetWorkItemFields(List<object> WorkItemFieldsList)

{

Dictionary<string, object> wiFields = new Dictionary<string, object>();


foreach (object wiField in WorkItemFieldsList)

{

Dictionary<string, object> fld = JsonConvert.DeserializeObject<Dictionary<string, object>>(wiField.ToString());

wiFields.Add(fld.Keys.ElementAt(0), fld[fld.Keys.ElementAt(0)]);

}

return wiFields;

}

Пример тестового приложения можно посмотреть здесь:

https://github.com/ashamrai/TFRestApi/tree/master/12.TFRestApiAppTestPlanDelails

Posted in Microsoft, Team Foundation Server, Team Foundation Server FAQ, Visual Studio, visual studio team services | Отмечено: , , , | Leave a Comment »