The Context

Lets start with two scenarios:

Jim is a diligent QA tester whose job it is to identify defects and capture faults before code is released. When Jim’s tests identify an issue that needs to be corrected, he creates a Bug workitem in TFS. This ensures that developers can see the issue and resolve it before the end of this sprint and before the new application version is deployed. Nicole is a systems administrator who supports the application. Occasionally, she and her users discover errors and faults in the application. For example, one time she noticed that the system didn’t release a resource like it was supposed to. Another time she found a security hole. When this happens, Nicole provides feedback, including repro steps, to the team by creating a Bug workitem.

The two scenarios illustrate completely different lifecycles for the same “Bug” workitem type. In Jim’s case, the Bug is a “must-fix”, to be addressed simply to meet the Story’s “Done criteria” in the current sprint. Essentially, Jim’s Bug should be added as a new task necessary to complete the story.  Nichole’s Bug may be a “won’t fix” issue, or may be considered a lower priority issue by the business owner than other needed functionality. The Bugs reported by Nichole and her customers should be evaluated, prioritized, and scheduled for the development team to address; Jim’s Bugs just need to be fixed.

In general, finding a Bug within sprint testing means that the story isn’t really “done”, so it has to be fixed to complete the sprint story; finding a Bug within released software means that new, unplanned work has been created. Unplanned work needs to be planned, planned work needs to be completed. (Of course, there are exceptions, like when a tester discovers an issue that cannot be resolved in the current sprint).

In other words, in TFS Jim’s Bugs should function like Tasks; Nichole’s Bugs should function like User Stories / Backlog Items. (In TFS, different process templates call Agile sprint stories either “User Stories” or “Product Backlog Items”. For purposes of this discussion, they are basically the same thing).

The Problem

TFS allows you to position the Bug workitem type at either backlog or task level, but not both. If you work with Bugs at the Task level, then you cannot triage, prioritize, or manage the Bug with Tasks. If you work with Bugs at the User Story / Backlog Item level, then you introduce unnecessary planning overhead just to address a simple Bug.

The Solution

The way forward is to create a second Bug workitem type; one Bug workitem functions at the Task level, and the other Bug type can be managed as a Story or Backlog Item.

The testing tools in TFS automatically create Bug workitems. We’ve already determined that the vast majority of testing-created Bugs should function as tasks, because the item should be corrected within the current sprint. Therefore, the existing Bug workitem type needs to stay at the task level; our new Bug workitem, then, will function at the story level. (In TFS 2015 or Visual Studio Team Services, this is now easy to set via the administrative control panel on the team settings page).

In my organization, coming up with a name for the second workitem (“Defect”, “Fault”, “Error”, etc.) type started Talmudic arguments about word meanings that started to appear endless. In the end, I chose “Backlog Bug” or “Bug Story” — depending upon whether the TFS project template was based upon Agile or Scrum. As it happens, I have yet to work with a team that chose to work with the TFS CMMI template, so I can provide no guidance for that.

Implementation

Implementing this change consists of creating and loading the additional workitem definition, then updating the Project’s Categories and ProcessConfig files. Things get more complicated if the template has been extensively customized.

The impact of this change depends on how the teams uses Bugs now. Teams that routinely associate Bugs with User Stories or Backlog Items will only notice that the Bugs now render on the Taskboard too. In TFS 2015, you can easily set

; teams whose Bugs have no relationship with Stories or Backlogs Items will need to create these relationship in order to get Bugs to appear on the Taskboard. More surprisingly, Bugs that have child Tasks (i.e. Bugs that are really handle as stories) will also not appear on the Backlog — although the child Tasks do. It turns out that the behavior is the same for Tasks that have child Tasks. It easy to build a query to find Bugs with child Tasks and correct the problem (or copy the Bug into a Bug Story or Backlog Bug, then move the Tasks to that workitem).

To create a Backlog Bug or Bug Story, simply export the existing bug workitem type definition, rename it, and import it back in.

Create the new Workitem Type

In a command windows (which does not need Administrator permissions), change the path to the TFS command tools. In most cases, you can use:

cd %programfiles(x86)%\microsoft visual studio 14.0\common7\ide

If Visual Studio 2015 is not installed, change the version number to “12.0”.

In the case of a TFS “Scrum” Template:

The TFS Scrum template uses “Project Backlog Items” so we are going to create a “Backlog Bug”.

Run these two witadmin commands to export the existing Bug workitem type and Product Backlog Item definition to local XML files:

witadmin exportwitd /collection:<collection> /p:<projectname> /n:bug /f:C:\<path>\<projectname>-Bug.xml
witadmin exportwitd /collection:<collection> /p:<projectname> /n:"Product Backlog Item" /f:C:\<path>\<projectname>-BacklogItem.xml

Of course, you'll want to replace the values in brackets with actual values relevant to your environment. Like this:

witadmin exportwitd /collection:http://TFSSERVER:8080/DefaultCollection /p:MyProject /n:bug /f:C:\TfsExports\MyProject-Bug.xml
itadmin exportwitd /collection:http://TFSSERVER:8080/Defaultcollection /p:MyProject /:"Project Backlog Item" /f:C:\TfsExports\MyProject-BacklogItem.xml

Leave the command window open, as we’ll be using it further.

Open the output XML file for the Bug workitem type. You can use an XML editor or notepad for these quick changes. The beginning of the file should start out something like this:

<?xml version="1.0" encoding="utf-8"?>
<witd:WITD application="Work...
<WORKITEMTYPE name="Bug">
<DESCRIPTION>Describes a divergence between required and actual behavior, and tracks the work done to correct the defect and verify the correction.</DESCRIPTION>
<FIELDS>
...

Change these same two elements (WorkitemType and Description):

<?xml version="1.0" encoding="utf-8"?>
<witd:WITD application="Work...
<WORKITEMTYPE name="Backlog Bug">
<DESCRIPTION>Describes a divergence between desired and actual behavior, and uses the Product Backlog to schedule and track the work done to correct the defect and verify the correction.</DESCRIPTION>
<FIELDS>
...

Because we want this new Backlog Bug to behave as a Product Backlog Item, it should have the same workflow states and transitions. In a second editor, open the other XML file (the Product Backlog Item). Copy the XML text between the <STATES>...</STATES> nodes in the Backlog Item document and replace the text between the <STATES> nodes in the Backlog Bug. Likewise, copy the text between the Backlog Item's <TRANSITIONS>...</TRANSITIONS> nodes and replace the transitions in the Bug XML.

Save the Bug XML file with a new name, like “MyProject-BacklogBug.xml”.

Now import the new workitem definition into TFS.

witadmin importwitd /collection:<collection> /p:<projectname> /f:C:\<path>\<projectname>-BacklogBug.xml

At this point, the Backlog Bug exists in TFS, but to use it you would have to query for it explicitly.

In the case of a TFS “Agile” Template:

The TFS Scrum template uses “User Stories” so we are going to create a “Bug Story”.

Run these two witadmin commands to export the existing Bug workitem type and Product Backlog Item definition to local XML files:

witadmin exportwitd /collection:<collection> /p:<projectname> /n:bug /f:C:\<path>\<projectname>-Bug.xml
witadmin exportwitd /collection:<collection> /p:<projectname> /n:"User Story" /f:C:\<path>\<projectname>-UserStory.xml

Of course, you'll want to replace the values in brackets with actual values relevant to your environment. Like this:

witadmin exportwitd /collection:http://TFSSERVER:8080/DefaultCollection /p:MyProject /n:bug /f:C:\TfsExports\MyProject-Bug.xml
itadmin exportwitd /collection:http://TFSSERVER:8080/Defaultcollection /p:MyProject /:"User Story" /f:C:\TfsExports\MyProject-UserStory.xml

Leave the command window open, as we’ll be using it further.

Open the output XML file for the Bug workitem type. You can use an XML editor or notepad for these quick changes. The beginning of the file should start out something like this:

<?xml version="1.0" encoding="utf-8"?>
<witd:WITD application="Work...
<WORKITEMTYPE name="Bug">
<DESCRIPTION>Describes a divergence between required and actual behavior, and tracks the work done to correct the defect and verify the correction.</DESCRIPTION>
<FIELDS>
...

Change these same two elements (WorkitemType and Description):

<?xml version="1.0" encoding="utf-8"?>
<witd:WITD application="Work...
<WORKITEMTYPE name="Bug Story">
<DESCRIPTION>Describes a divergence between desired and actual behavior, and uses the Product Backlog to schedule and track the work done to correct the defect and verify the correction.</DESCRIPTION>
<FIELDS>
...

Because we want this new Bug Story to behave as a User Story, it should have the same workflow states and transitions. In a second editor, open the other XML file (the User Story). Copy the XML text between the <STATES>...</STATES> nodes in the User Story document and replace the text between the <STATES> nodes in the Bug Story. Likewise, copy the text between the User Story's <TRANSITIONS>...</TRANSITIONS> nodes and replace the transitions in the Bug XML.

Save the Bug XML file with a new name, like “MyProject-BugStory.xml”.

Now import the new workitem definition into TFS.

witadmin importwitd /collection:<collection> /p:<projectname> /f:C:\<path>\<projectname>-BugStory.xml

At this point, the Backlog Bug exists in TFS, but to use it you would have to query for it explicitly.

Tell TFS How to Use the new Workitem Type

To get either the Backlog Bug or Bug Story workitem type to appear in the TFS backlog, we have to tell TFS to how to use it.

Again using the witadmin command, export the project Categories data to a local XML file:

witadmin exportcategories /collection:<collection> /p:<projectname> /f:C:\<path>\<projectname>-Categories.xml

We need to make three changes to the Categories XML. Open the file in an XML editor, or notepad.

1. Add the new workitem to the Bug category

First, find the <CATEGORY> element with the refname attribute of “Microsoft.BugCategory”. The section should look like this:

<CATEGORY refname="Microsoft.BugCategory" name="Bug Category">
<DEFAULTWORKITEMTYPE name="Bug" />
</CATEGORY>

We need to add our new workitem type to this. This will be a “Backlog Bug” or “Bug Story”, depending upon what you did earlier.

If your Project uses the Scrum template, add the Backlog Bug reference:

<CATEGORY refname="Microsoft.BugCategory" name="Bug Category">
<DEFAULTWORKITEMTYPE name="Bug" />
<WORKITEMTYPE name="Backlog Bug" />
</CATEGORY>

If your Project uses the Agile template, add the Backlog Bug reference:

<CATEGORY refname="Microsoft.BugCategory" name="Bug Category">
<DEFAULTWORKITEMTYPE name="Bug" />
<WORKITEMTYPE name="Bug Story" />
</CATEGORY>

2. Add the new workitem to the Requirement category

Next, find the <CATEGORY> element with the refname of “Microsoft.RequirementCategory”. The section should look like:

<CATEGORY refname="Microsoft.RequirementCategory" name="Requirement Category">
<DEFAULTWORKITEMTYPE name="..." />
</CATEGORY>

Again, the default workitem type will be either User Story or Product Backlog Item, depending upon your base template. To add our new workitem to the backlog, we need to include our new workitem.

If your Project uses the Scrum template, add the Backlog Bug reference:

<CATEGORY refname="Microsoft.RequirementCategory" name="Requirement Category">
<DEFAULTWORKITEMTYPE name="Product Backlog Item" />
<WORKITEMTYPE name="Backlog Bug" />
</CATEGORY>

If your Project uses the Agile template, add the Bug Story reference:

<CATEGORY refname="Microsoft.RequirementCategory" name="Requirement Category">
<DEFAULTWORKITEMTYPE name="User Story" />
<WORKITEMTYPE name="Bug Story" />
</CATEGORY>

3. Add the old Bug workitem to the Task category (TFS 2013 only)

In TFS 2015, you can assign the old Bug workitem type to function as a task through the Team setting control panel. In TFS 2013, you can do this by changing one more category.

Find the <CATEGORY> element with the refname of “Microsoft.TaskCategory”. The section should look like:

<CATEGORY refname="Microsoft.TaskCategory" name="Task Category">
<DEFAULTWORKITEMTYPE name="Task" />
<WORKITEMTYPE name="PCI Compliance Review" />
</CATEGORY>

To manage the existing Bug as a Task, add the workitem to the backlog:

<CATEGORY refname="Microsoft.TaskCategory" name="Task Category">
<DEFAULTWORKITEMTYPE name="Task" />
<WORKITEMTYPE name="PCI Compliance Review" />
<WORKITEMTYPE name="Bug" />
</CATEGORY>

If you haven’t processed my other blog post about create a PCI Compliance Review workitem, then you probably won’t see that entry in this category.

Save the XML file and import it back into the Project. You can use the following command:

witadmin importcategories /collection:<collection> /p:<projectname> /f:C:\<path>\<projectname>-Categories.xml

Verify the new Bug Type

Open a TFS project and go to the "WORK" tab.

If everything worked successfully, you should see a new “Bug Story” or “Backlog Bug” as options when you create a new item.

On the Kanban board, you may see an error message saying that workitem mapping is required. Just open the state mapping window and map the new bug type exactly the same as the Backlog Item or User Story.

Final Thoughts

Several teams have been using this pretty successfully, and I suspect that those teams do not even realize that a Bug Story or Backlog Bug are not a part of the default TFS templates.

If it is determined that a (task-level) Bug is really too big for the current sprint, you can easily escalate it to a Bug Story/Backlog Bug. Technically, you can’t convert a workitem from one type to another (i.e. you can’t make a Bug become a Bug Story), but you can easily copy values from one workitem type to another.

1. Open the Bug workitem

Find the TFS Bug workitem that needs to be converted to a Bug Story/Backlog Bug. Open the workitem for editing.

2. Click the Copy Workitem command

In the editor toolbar, click on the copy item toolbar command.

3. Select the Bug Story or Backlog Item Workitem Type

In the popup dialog, select the corresponding backlog-level workitem type.

The values of the task-level Bug will be copied to a new Bug Story or Backlog Bug.

Simple!