At my day job we use Team Foundation Server 2008 (TFS) for our automated builds, iteration management, and source control. TFS may not be the most ideal way to manage these processes but in our MS environment it has helped us communicate with our non-technical team members and customers. In order to enhance our feedback loop we’ve been looking into ways to add bugs automatically when automated tests fail or when errors occur in our production applications. (see Creating a TFS Work Item from ClojureCLR)
This morning I had a little time to do some research on how to programmatically create a new bug work item. My goal was to write code that would create a new work item bug with an image attached to it. Why an image? When our automated tests fail we capture what the browser looked like when it fails. Before we get into the code let me describe a TFS Work Item.
A TFS Bug Work Item
In TFS work items are a way to track work that needs to be done. There are five different types of work items available but in our projects we typically only use three: Task, Scenario, and Bug. Each work item type has its own UI with different fields. Since I am creating bugs in this example I thought I’d show you what the UI looks like for a Bug Work Item.
In this example we will create a new bug and enter text into the highlighted fields plus attach an image file. In order for me to create the bug I need to do a little setup.
There are three assemblies needed to create a TFS Bug Work Item. The are : Microsoft.TeamFoundation.dll, Microsoft.TeamFoundation.Client.dll, and Microsoft.TeamFoundation.WorkItemTracking.Client. All three of these DLLs can be found in the C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies directory. I copied the three Dlls into the project’s libs directory.
The first step is to load the TFS assemblies from libs directory using require statements. Once the assemblies have been loaded I can start working on the main method. The main method's sole purpose is to drive the WorkItem creation process. In the main method the first few lines are responsible for creating the necessary objects for WorkItem creation.
First I need a TFS server object which is created by making a call to the static method TeamFoundationServerFactory.GetServer. GetServer takes a single parameter which is the name of the server I want to work with. After the server object is created I can use it to create a WorkItemStore object. The WorkItemStore encapsulates the data store that contains all work items on a particular server. The next line grabs the particular Project object that I want to work with by using a method I wrote called find_item. The last setup line uses the Project object to retrieve the WorkItemType object that represents a Bug WorkItem. After that call the prep work is done and I am ready to create thew new Bug WorkItem.
Creating the Bug WorkItem
The create_work_item method is responsible for creating a new 'bare bones' WorkItem object. Creating a minimal WorkItem object allows for more flexibility down the line. Some times I may want to add a new bug with an attachment and some times I may not. The method is straight forward, just create the WorkItem object by passing in the WorkItemType object followed by setting the Title, Description, AreaPath and IterationPath properties. When everything has been set the new WorkItem object is returned.
Adding the Attachment
Now that I have my WorkItem object its time to add my image file attachment. I wrote another small method to create the Attachment object and add it to the WorkItem’s Attachments collection. It takes three parameters, the WorkItem object, the path to the file to be attached and a description of the file. First, I use the path and desc parameters to create the Attachment object. After the Attachment object has been created I add it to the WorkItem.Attachments collection by calling its Add method passing in the Attachment object.
At this point I have a WorkItem object with an Attachment in memory. That’s nice and all but the WorkItem has not been stored in the WorkItem data set yet. In order to add it to the data set I need to save the object. Surprisingly enough all I need to do is call the WorkItem’s save method.
Now when I look at the Pending Bugs report in TFS I will see my newly created bug in the list.
In this post I showed you how easy it is to use .NET Assemblies in an IronRuby script. I walked you through the simple process of creating a Bug WorkItem in TFS. Having the ability to programmatically create and report bugs from our IronRuby scripts will help us close the loop on bug reporting in our automated testing environment. Having an image attached to the bug will help us figure out why the test failed speeding up bug fix times.
In The Future
We long since switched away from the MSBuild approach to our builds in favor of using Rake and Albacore. The switch has removed some of the built in integration with TFS that MSBuild provided. I will be investigating the build and source control TFS APIs to see if we can enhance our Rake code in hopes of totally removing XML files from our build kick offs. As my investigation progresses I will be writing posts about my progress.
My Source (this blog’s code is the 0-Create-TFS-Work-Item): https://github.com/rippinrobr/My-Programming-Adventure-Blog/zipball/master