С начала этого месяца мне уже три раза задавали вопрос "Как настроить номер итерации по умолчанию в TFS?".
Ответ на этот вопрос я упонимал здесь, но, поскольку часто спрашивают, решил ответить еще отдельным постом.
Ответ: Никак. Но есть обходной вариант.
Номер итерации хранится в поле Iteration Path, а TFS не позволяет для поля Iteration Path создавать правило DEFAULT, так что значение по умолчанию задавать нельзя. Кроме того, правило PROHIBITEDVALUES задавать также нельзя, поэтому нельзя запретить указывать старые итерации, которые уже остались в прошлом.
Для того, чтобы решить эту проблему я отказался от использования поля Iteration Path и вместо него создал свое аналогичное поле, но только не типа TreePath, а типа String со списком доступных значений, соответствующих списку нужных итераций.
Для этого поля уже было можно задавать значение по умолчанию и вообще любые правила.
Старое поле Iteration Path на форме Work Item'а я заменил на новое и исправил все запросы к списку work item'ов так, чтобы они использовали новое поле вместо старого.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
Показаны сообщения с ярлыком Visual Studio 2010. Показать все сообщения
Показаны сообщения с ярлыком Visual Studio 2010. Показать все сообщения
понедельник, 15 ноября 2010 г. - www.msmirnov.ru
понедельник, 1 ноября 2010 г. - www.msmirnov.ru
Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
Преамбула.
Вообще говоря, задача, ради которой я решил посмотреть как добавлять свои контролы была такова: довольно часто случается ситуация, когда в текст бага в TFS помещается Stack Trace исключения, которое происходит в работе системы.
Для удобства и ускорения работы хотелось добавить в TFS возможность быстрого перехода от текста стека к коду, создавшему исключение.
Проще говоря, на форме ошибки решили поместить кнопку, при нажатии на которую в Visual Studio будет открываться строка кода, указанная в Stack Trace в Details текущего Work Item.
В этом посте я расскажу о том, как добавлять свои котролы на форму Work Item'а, в следующем - как настроить локацию кода.
Затем добавляем в проект новый User Control, назовем его LocateCodeControl.
После создания, помещаем на него кнопку LocateCodeButton, с текстом “Locate code”.
После этого имеем новый контрол такого вида:

Подключаем в проект две библиотеки:
1. Microsoft.TeamFoundation.WorkItemTracking.Client (путь: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.WorkItemTracking.Client.dll)
2. Microsoft.TeamFoundation.WorkItemTracking.Controls (путь C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll)
Созданный нами контрол LocateCodeControl наследуем от интерфейса IWorkItemControl.
Реализуем интерфейс что называется “по-умолчанию”:
После этого код контрола имеет следующий вид:
Сам контрол на этом готов и если все сделано правильно, то проект должен компилироваться.
Теперь для подключения контрола к TFS в нашем проекте создаем xml-файл с раширением .wicc, который будет использоваться TFS для загрузки библиотеки обработчика контрола. Назовем его LocateCodeControl.wicc
Вот текст файла (как видим, он содержит имя сборки и имя класса контрола.):
После всех манипуляций проект будет иметь следующий вид:

Теперь добавим немного поведения (в качестве теста) для нашей кнопки.
Создадим ей обработчик события Click по которому будем просто отображать Title текущего Work Item’а в MessageBox.
Код обработчика очень простой:
Теперь приступим к тестовому развертыванию нашего контрола.
Для этого необходимо поместить откомпилированную библиотеку контрола и .wcc файл (в нашем случае это файлы TFSControlsLibrary.dll и LocateCodeControl.wicc) в каталог "C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\10.0" на каждой машине, на которой будет использоваться данный контрол, так как исполнение кода осуществляется локально, а не на сервере и если этого не сделать, то студия будет писать, что не находит контрол.
После этого можно поместить контрол на форму для какого-либо Work Item Type.
Встроенный в студию Process Editor делать этого не умеет, поэтому придется править xml-файл нашего Work Item'а вручную.
Для этого экспортируем Work Item Type из имеющегося Team Project в локальный xml-файл.
Затем находим этот файл и подключаем в него наш контрол в следующем виде:
Затем импортируем наш файл обратно в Team Project.
После этого закрываем Visual Studio и снова открываем ее, иначе она не загрузит наш контрол. Для повторного развертывания наших файлов ее, кстати, также надо будет закрывать, так как она блокирует файлы.
Если все сделано правильно, то при создании бага видим нашу кнопку на форме:

При нажатии на кнопку видим наш MessageBox:

На этом первичное создание контрола завершено, в следующем посте я расскажу о том, как обеспечить локацию кода по Stack Trace в тексте бага.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
Вообще говоря, задача, ради которой я решил посмотреть как добавлять свои контролы была такова: довольно часто случается ситуация, когда в текст бага в TFS помещается Stack Trace исключения, которое происходит в работе системы.
Для удобства и ускорения работы хотелось добавить в TFS возможность быстрого перехода от текста стека к коду, создавшему исключение.
Проще говоря, на форме ошибки решили поместить кнопку, при нажатии на которую в Visual Studio будет открываться строка кода, указанная в Stack Trace в Details текущего Work Item.
В этом посте я расскажу о том, как добавлять свои котролы на форму Work Item'а, в следующем - как настроить локацию кода.
Создание контрола для Work Item Type.
Прежде всего в студии создаем новый проект типа Class Library который назовем TFSControlsLibrary.Затем добавляем в проект новый User Control, назовем его LocateCodeControl.
После создания, помещаем на него кнопку LocateCodeButton, с текстом “Locate code”.
После этого имеем новый контрол такого вида:
Подключаем в проект две библиотеки:
1. Microsoft.TeamFoundation.WorkItemTracking.Client (путь: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.TeamFoundation.WorkItemTracking.Client.dll)
2. Microsoft.TeamFoundation.WorkItemTracking.Controls (путь C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.WorkItemTracking.Controls.dll)
Созданный нами контрол LocateCodeControl наследуем от интерфейса IWorkItemControl.
Реализуем интерфейс что называется “по-умолчанию”:
После этого код контрола имеет следующий вид:
using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using System.Data;using System.Linq;using System.Text;using System.Windows.Forms;using Microsoft.TeamFoundation.WorkItemTracking.Controls;using Microsoft.TeamFoundation.WorkItemTracking.Client;namespace TFSControlsLibrary{public partial class LocateCodeControl : UserControl, IWorkItemControl
{public LocateCodeControl(){InitializeComponent();
}
#region IWorkItemControl Memberspublic event EventHandler AfterUpdateDatasource;
public event EventHandler BeforeUpdateDatasource;
void IWorkItemControl.Clear() { }void IWorkItemControl.FlushToDatasource() { }void IWorkItemControl.InvalidateDatasource() { }System.Collections.Specialized.StringDictionary IWorkItemControl.Properties {get; set;}bool IWorkItemControl.ReadOnly {get; set;}void IWorkItemControl.SetSite(IServiceProvider serviceProvider) { }public object WorkItemDatasource {get; set;}
string IWorkItemControl.WorkItemFieldName {get; set;}#endregion}
}
Теперь для подключения контрола к TFS в нашем проекте создаем xml-файл с раширением .wicc, который будет использоваться TFS для загрузки библиотеки обработчика контрола. Назовем его LocateCodeControl.wicc
Вот текст файла (как видим, он содержит имя сборки и имя класса контрола.):
<?xml version="1.0" encoding="utf-8" ?>
<CustomControl xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Assembly>TFSControlsLibrary</Assembly>
<FullClassName>TFSControlsLibrary.LocateCodeControl</FullClassName>
</CustomControl>
После всех манипуляций проект будет иметь следующий вид:
Теперь добавим немного поведения (в качестве теста) для нашей кнопки.
Создадим ей обработчик события Click по которому будем просто отображать Title текущего Work Item’а в MessageBox.
Код обработчика очень простой:
private void LocateCodeButton_Click(object sender, EventArgs e)
{var ds = WorkItemDatasource as WorkItem;MessageBox.Show(ds.Title);
}
Теперь приступим к тестовому развертыванию нашего контрола.
Для этого необходимо поместить откомпилированную библиотеку контрола и .wcc файл (в нашем случае это файлы TFSControlsLibrary.dll и LocateCodeControl.wicc) в каталог "C:\ProgramData\Microsoft\Team Foundation\Work Item Tracking\Custom Controls\10.0" на каждой машине, на которой будет использоваться данный контрол, так как исполнение кода осуществляется локально, а не на сервере и если этого не сделать, то студия будет писать, что не находит контрол.
После этого можно поместить контрол на форму для какого-либо Work Item Type.
Встроенный в студию Process Editor делать этого не умеет, поэтому придется править xml-файл нашего Work Item'а вручную.
Для этого экспортируем Work Item Type из имеющегося Team Project в локальный xml-файл.
Затем находим этот файл и подключаем в него наш контрол в следующем виде:
<Control Type="LocateCodeControl" />
Затем импортируем наш файл обратно в Team Project.
После этого закрываем Visual Studio и снова открываем ее, иначе она не загрузит наш контрол. Для повторного развертывания наших файлов ее, кстати, также надо будет закрывать, так как она блокирует файлы.
Если все сделано правильно, то при создании бага видим нашу кнопку на форме:
При нажатии на кнопку видим наш MessageBox:
На этом первичное создание контрола завершено, в следующем посте я расскажу о том, как обеспечить локацию кода по Stack Trace в тексте бага.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
четверг, 28 октября 2010 г. - www.msmirnov.ru
Как создать work item в TFS (Team Foundation Server) из письма в Outlook
Некоторое время назад встала задача создавать баги в TFS из писем в Outlook без использования Visual Studio и Web Access.
Для решения задачи был создан add-in для Outlook.
Процесс создания описан ниже.
Прежде всего создаем проект Outlook 2007 Add-In.

После этого имеем текст класса нашего компонента в следующем виде:

Для начала создадим панель в Outlook, которая будет называться “TFS Integration toolbar”
Подключим несколько сборок:
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
Затем модифицируем метод ThisAddIn_Startup следующим образом:

В начале метода мы создаем панель:
Затем помещаем на нее два контрола:
1. ComboBox MyAssignedToList, который будет содержать список сотрудников, для создания бага
2. Собственно кнопку CreateWIButton, которая будет приводить к созданию бага. Для кнопки определяем обработчик события Click.


На этом подготовка к работе нашего контрола закончена.
Теперь реализуем обработчик события Click для нашей кнопки:

Здесь находим выделенное письмо, подключаемся к TFS и создаем наш баг.
На этом проект готов.
Теперь в Visual Studio делаем публикацию проекта, получаем инсталляционный пакет и запускаем его.
Компонент устанавливается, затем перезапускаем Outlook и включаем нашу панель:

После нажатия на кнопку “Create TFS Bug” создает work item типа Bug, который назначен на выбранного сотрудника и содержит в теле текст выбранного письма.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
Для решения задачи был создан add-in для Outlook.
Процесс создания описан ниже.
Прежде всего создаем проект Outlook 2007 Add-In.
После этого имеем текст класса нашего компонента в следующем виде:
Для начала создадим панель в Outlook, которая будет называться “TFS Integration toolbar”
Подключим несколько сборок:
using System.Windows.Forms;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Server;
Затем модифицируем метод ThisAddIn_Startup следующим образом:
В начале метода мы создаем панель:
Затем помещаем на нее два контрола:
1. ComboBox MyAssignedToList, который будет содержать список сотрудников, для создания бага
2. Собственно кнопку CreateWIButton, которая будет приводить к созданию бага. Для кнопки определяем обработчик события Click.
Список значений для поля "Assigned To" будем отображать в MyAssignedToList. Для этого заполняем его доступным списком значений из нашего Team Project в TFS.
На этом подготовка к работе нашего контрола закончена.
Теперь реализуем обработчик события Click для нашей кнопки:
Здесь находим выделенное письмо, подключаемся к TFS и создаем наш баг.
На этом проект готов.
Теперь в Visual Studio делаем публикацию проекта, получаем инсталляционный пакет и запускаем его.
Компонент устанавливается, затем перезапускаем Outlook и включаем нашу панель:
После нажатия на кнопку “Create TFS Bug” создает work item типа Bug, который назначен на выбранного сотрудника и содержит в теле текст выбранного письма.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
четверг, 7 октября 2010 г. - www.msmirnov.ru
Учет трудозатрат, времени сотрудников и отчетность в TFS (Team Foundation Server)
В этом посте я продолжаю описание своего опыта внедрения TFS (Team Foundation Server), начатое здесь, здесь и здесь.
Некоторое время назад появилась необходимость составить отчетность о трудозатратах, которые мы осуществляем при разработке и тестировании задач, выполняемых в рамках работы над выпуском новых версий нашего продукта.
Деятельность наша продукто-ориентированная, а не проектно-ориентированная, поэтому не было необходимости учета и сравнения плановых и фактических трудозатрат - речь шла только о фактических трудозатратах.
На выходе необходимо было иметь отчет следующего вида:
| Task name | Development hrs | Testing hrs | Management hrs |
|---|---|---|---|
| Task 1 | ... | ... | ... |
| Task 2 | ... | ... | ... |
| Task 3 | ... | ... | ... |
Лирическое отсупление
Перед внедрением учета трудозатрат я опросил несколько коллег, работающих в различных небольших компаниях на предмет того, как у них организован учет трудозатрат. Ответы были следующие: - Учет трудозатрат не ведется. - Учет трудозатрат ведется суммарно по двум направлениям - разработка и исправление багов. Трудозатраты по отдельным задачам и трудозатраты на тестирование не учитываются. - Учет трудозатрат ведется по компонентам разрабатываемого продукта. Трудозатраты по отдельным задачам на учитываются. Практически никто из опрошенных: - не ведет учет плановых трудозатрат - не сравнивает фактические и плановые трудозатраты - не связывает баги с задачами (некоторые вообще для задач использует один инструмент, для ошибок - другой) - не суммирует время, потраченное на исправление ошибок, к задаче, к которой относятся данные ошибки (у многих вообще нет разницы между задачами и ошибками). |
Для того, чтобы организовать учет времени по выполняемым задачам мне пришлось добавить в task два поля - DevelopmentHours и TestingHours.
Эти поля были предназначены для учета фактических трудозатрат на разработку и тестирование и при создании задач автоматически устанавливались равными нулю.
Требовалось сделать так, чтобы при переходе task'а из состояния Active в Completed разработчики должны были указать задать значение поля DevelopmentHours.
Аналогично при переходе из состояния Completed в Closed или обратно в Active тестировщики должны были указать значение TestingHours.
При чем, просто добавить правило REQUIRED было бы недостаточно, потому что задача могла многократно переходить из одного состояния в другое в процессе тестирования и исправления и каждый необходимо было указывать новое значение DevelopmentHours или TestingHours, а правило REQUIRED не могло бы этого обеспечить - оно бы стало только лишь гарантировать присутствие значение как такового, даже предыдущего, а не нового.
Для решения задачи пришлось использовать правило NOTSAMEAS, которое сравнивает значение поля со значением другого поля и если они совпадают, то не позволяет сохранять задачу. В качестве второго поля должно было бы выступать предыдущее значение DevelopmentHours или TestingHours в зависимости от ситуации. Поскольку в задаче сами по себе предыдущие значения не хранятся, пришлось добавить еще два поля, которые пользователю не видны и которые используются для хранения предыдущих значений - DevelopmentHours2 и TestingHours2.
Эти поля автоматически заполняются с использованием правила COPY значениями полей DevelopmentHours и TestingHours при сохранении задачи.
Таким образом, когда у разработчика возникает необходимость изменить статус задачи с Active на Completed у него значения полей DevelopmentHours и DevelopmentHours2 совпадают и он не может сохранить задачу, пока не изменит поле DevelopmentHours. При сохранении задачи новое значение DevelopmentHours копируется в DevelopmentHours2 и они снова становятся одинаковыми, чтобы в следующий раз вновь обеспечить необходмость изменения поля DevelopmentHours.
Выглядит это так:
Для TestingHours и TestingHours2 все работает абсолютно аналогично, но только при переходе из состояния Completed в Closed или обратно в Active.
Таким образом разработчики должны каждый раз указывать новое значение поля DevelopmentHours, а тестировщики - TestingHours.
При переходе из состояние Active в Closed никаких проверок я добавлять не стал - т.е. задачу можно просто закрыть и все, если она, например, была отменена.
Учет времени по ошибкам я организовывать не стал, поскольку это, как мне кажется, стало бы отнимать слишком много времени само по себе.
Однако, для того, чтобы более точно учитывать время по задачам, я договорился с тестировщиками, что они, при проверке задач, будут всегда стараться в первую очередь зафейлить задачу, нежели создавать новый баг.
Кроме того, я договорился с архитектором, что он, при завершении архитектурного анализа будет также выставлять свое в время в поле DevelopmentHours.
Еще, было рекомендовано всем не пытаться оценить точное время, а ставить время приблизительное, при этом стараясь его несколько завышать для учета выпадающих расходов - консультаций с другими разработчиками и т.п.
Отчетность.
Для организации отчетность в TFS используется технология Reporting Services.
Открыть Диспетчер отчетов можно через портал проекта, а можно прямо из Visual Studio:
Для создания отчета пришлось использовать Visual Studio 2008 - в Visual Studio 2010 подходящего типа проекта почему-то не оказалось.
Для создания отчета необходимо создать проект типа Report Server Project, в котором создать .rdl-файл, являющийся описанием требуемого отчета.
В качестве источника данных была указана хранимая процедура, которая возвращала список work item'ов с типом task, так как только для них был организован учет трудозатрат.
При написании запроса к базе TFS было установлено следующее:
1. Все work item'ы хранятся в таблице WorkItemsAre. Тип при этом хранится в поле [Work item Type]. Т.е. если вы хотите выбрать все задачи, то можно написать такой запрос:
select *
from WorkItemsAre
where [Work item Type] = 'task'
2. Все поля (в том числе и добавляемые дополнительно) хранятся в таблице Fields. Дополнительно создаваемые поля имеют в данной таблице FldID начиная с 10 000.
При этом имя поля из таблицы WorkItemsAre составляется так - Fld + FldID поля из таблицы Fields.
Для примера, :
Поле DevelopmentHours в таблице Fields имеет FldID = 10133.
Соответственно его значение хранится в таблице WorkItemsAre в поле Fld10133.
Таким образом сначала определяем имя поля из таблицы Fields, а потом делаем составной запрос к таблице WorkItemsAre.
Т.е. примерно так:
declare @FieldName varchar (255), @q nvarchar (4000)
select @FieldName = 'Fld' + CONVERT (varchar (255), FldID)
from Fields
where ReferenceName = 'ROI.DevelopmentHours'
set @q = 'select ' + @FieldName + '
from WorkItemsAre
where [Work item Type] = ''task'''
exec sp_executesql @q
Таким образом можно определить и выбрать практически все интересующие поля.
Тип полей при этом совпадает с типом поля, заданном в TFS.
Используя хранимые процедуры можно написать практически любой запрос на получение данных из таблицы work item'ов, что и было сделано.
P.S.
Другие мои посты на тему TFS:
1. Миграция в TFS (Team Foundation Server)
2. Кто ошибку создает - тот ее и проверяет?
3. Нумерация версий продукта в TFS (Team Foundation Server)
4. Учет трудозатрат и отчетность в TFS (Team Foundation Server)
5. Как создать work item в TFS (Team Foundation Server) из письма в Outlook
6. Как поместить свой control на форму Work Item в TFS (Team Foundation Server)
7. Как настроить номер итерации по умолчанию в TFS (Team Foundation Server)
среда, 22 сентября 2010 г. - www.msmirnov.ru
Лекция Андрея Маркеева "Введение в SharePoint 2010"
В прошлую пятницу по моей просьбе Андрей Маркеев прочитал нам вводную лекцию "Введение в SharePoint 2010".
Андрей имеет большой опыт разработки под SharePoint 2007 и 2010 и за банку меда с моей пасеки он любезно согласился прочитать нам обзорную лекцию, посвященную архитектуре SharePoint 2010, способам разработки в Visual Studio 2010 для SharePoint 2010, области его применения, его достоинствам и недостаткам.
Видео лекции, которое снимал Андрей Гребенщиков, доступно здесь:
Андрей имеет большой опыт разработки под SharePoint 2007 и 2010 и за банку меда с моей пасеки он любезно согласился прочитать нам обзорную лекцию, посвященную архитектуре SharePoint 2010, способам разработки в Visual Studio 2010 для SharePoint 2010, области его применения, его достоинствам и недостаткам.
Видео лекции, которое снимал Андрей Гребенщиков, доступно здесь:
Подписаться на:
Сообщения (Atom)



