After an intense three months of work, the training kit that my colleague Yuval Mazor, and I developed for Microsoft has finally been published! You can download it at http://www.microsoft.com/download/en/details.aspx?id=27152. The training kit is designed to take novices to level 200 knowledge, i.e. to enable users, developers and administrators to competently use the most important features and understand how the various parts work with each other.

What Does it Cover?
The training kit contains presentations about the following topics:
-
Introduction
-
Architecture
-
Project and document management
-
Using and querying against work items
-
Running reports
-
Accessing TFS from the web
-
Source control
-
Security
-
Using the power tools
Additionally there are demos and hands on labs covering the subjects of project creation, security, requirement management, running reports and queries, using the source control, and bulk editing of work items with Excel and MS Project.
Be sure to try it out! There are some gems hidden in there, including some things that I learned only when I researched the subjects for our writing.
See you at Build!
Assaf
As previously hinted by Microsoft’s Brian Harry, in a comment on his blog distributed version control (or DVCS) is on the TFS team’s backlog. Now, with last week’s announcement, the upcoming version of TFS will take a step towards distributed VCS. This change comes in the form of a new concept: Local Workspaces. What this means, in simple words, is that rather than having to make all your changes in a TFS approved environment (Visual Studio, Team Explorer, Source Control Explorer, etc.), you will be able to make all your changes (i.e. rename, move, delete and edit files) locally, and TFS will figure out what needs to be checked in, when you choose to do so!
That’s right folks! No more scenarios where you fail to check out one item, and then get hit on the head when you want to check in one or two days worth of changes (some environments will easily allow you to change files regardless of them being marked as read only).
How is that possible? Well, TFS is moving from a Checkout –> Edit –> Checkin model to the Edit –> Merge –> Commit model that is prevalent among many modern version control systems (like subversion, for example). Of course, the old way of doing things will still be available, but the new way will be the default.
In Brian Harry’s blog post, he states that with regards to the question “but did you implement DVCS?” the answer is still “No, not yet. You still can’t checkin while you are offline” (Emphasis mine). However, I believe that this will now be easily solved with a new and improved as soon as a Git-to-TFS Bridge (or mercurial, my personal favorite) will be developed!
The main problem with the various vcs-to-TFS bridges, is the fact that the changes must be applied to the workspace, and require us to checkout the items – an act that defeats the main purpose of a DVCS: Working in a manner that is disconnected, neither affecting nor being affected by other developers efforts, or the status of the server. Of course, once we no longer need to checkout files, the obstacle is removed, and we can easily work with our DVCS of choice locally and extend them (at least the open source ones) to add a command to publish to TFS. I promise to develop one as soon as I get my hands on a CTP of TFS 11.
Finally, I want you all to join me and lets give a warm hand to TFS 11, welcoming Microsoft to the 21st century! Hurray!
A client of mine came to me with the following problem: She has several server plugins that manipulate work items, one which I wrote, and another that was downloaded from codeplex. When applied to one work item, e.g. via the Team Explorer, everything works fine. However, when applying to a bulk of work items (via Excel publishing, for example), the process freezes for several minutes, until it completes and is only then freed.
I came up with the following solution: A server plugin that queues a job for the TFS Job Agent, and a Job Extension to handle the work, at its leisure.
The Server Plugin
A server plugin runs before and/or after an event, depending on the Notification Type you choose to use. It does so synchronously, so it doesn’t free the resource or the process until it completes. Therefore, like any other event you write, you will want to free it as soon as possible, and hand off any long-running work to a separate thread or process.
The template for writing a server plugin is rather simple and straight forward. This is the template I use.
First you have to add some references, and “using” statements. Most blog posts I read don’t mention them, which is a bit of a pain, in my opinion, so I’ll add them here:

- using System;
- using System.IO;
- using System.Xml;
- using Microsoft.TeamFoundation.Common;
- using Microsoft.TeamFoundation.Framework.Server;
- using Microsoft.TeamFoundation.WorkItemTracking.Server;
Next, we need to take care of a few properties. This is simple enough, and rather standard:
- namespace ServerPlugins
- {
- public class SampleWorkItemChangedServerPlugin : ISubscriber
- {
- #region Implementation of ISubscriber
-
- public Type[] SubscribedTypes()
- {
- return new[]{typeof(WorkItemChangedEvent)}; // For Example
- }
-
- public string Name
- {
- get { return "Sample WI Server Plugin"; }
- }
-
- public SubscriberPriority Priority
- {
- get { return SubscriberPriority.Low; }
- }
Finally, we’ve got the Process Event callback method – this is where we handle the event. We start by making sure that we’re handling the right event. That’s right: Every ISubscriber class gets called for every event. You want to make sure as soon as possible that you’re dealing with the right type of event:
- public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
- {
- statusCode = 0;
- properties = null;
- statusMessage = string.Empty;
-
- // Check whether the notification is what we are waiting for
- if (notificationType != NotificationType.DecisionPoint)
- {
- return EventNotificationStatus.ActionPermitted;
- }
- var notification = notificationEventArgs as WorkItemChangedEvent;
- if (notification == null)
- {
- return EventNotificationStatus.ActionPermitted;
- }
Note that since we’re queuing a job to be handled asynchronously our notification type will always be a Notification, rather than a DecisionPoint. It doesn’t make much sense to queue something that must happen before the original event occurs. You do see that, right?
I prefer to make multiple return points in my code to reduce cyclamatic complexity, rather than nesting if statements. It is purely a matter of style, but I find code easier to read if you can separate control from logic.
Next comes the interesting part. This is where you would normally place your logic. However, in order to be able to return the control as soon as possible, you will instead queue a job to handle your logic, as follows:
- try
- {
- // Prepare the data we need for handling the notification in a job
- var workItemId = notification.CoreFields.IntegerFields[0].NewValue;
- var reader = XmlReader.Create(new StringReader("<WorkItem>" + workItemId.ToString() + "</WorkItem>"));
- var xmlData = new XmlDocument().ReadNode(reader);
-
- // Handle the notification by queueing the information we need for a job
- var jobService = requestContext.GetService<TeamFoundationJobService>();
- jobService.QueueOneTimeJob(requestContext, "Sample TFS Job", "JobExtentions.SampleWorkItemJob", xmlData,
- false);
- }
In this code block we do two things: First, in lines 4-6, we prepare the data we want to pass to the job. The QueueOneTimeJob method accepts an XmlNode of data that can be passed on to the job. For my example, as I am listening to the WorkItemChangedEvent, I will pass the Work Item ID, in an XmlElement. In lines 9-11, we queue a job.
Two things need to be mentioned. First is that since we are going to queue each job with different data, we use the QueueOneTimeJob. It is used when we don’t have a known job that we wish to activate (that would require knowing its GUID), therefore each call creates a new job, and two successive calls won’t merge accidentally, causing one job to get lost. Once again, this is an implementation issue that needs to be circumvented – and luckily can be done so easily.
The other thing, is that you need to pass it the domain name and class of the job extension (see line 10). This tells the TFS Job Agent which extension to activate for each job. Unfortunately, it is passed as text, and therefore runs the risk of causing a runtime error.Double check your plugin name. Don’t say I didn’t warn you!
Another important thing to note, is that you must not throw an exception. If you do, your plugin will get disabled, and will not get restarted until you restart TFS. make sure you catch and swallow every exception your code raises. Log it, and check it, but don’t allow it to escape.
- catch (Exception exception)
- {
- TeamFoundationApplication.LogException("Sample Server Plugin failed while processing", exception);
- }
Finally, return a result. Given you won’t be handling the event here, you will always return the same status result:
- return EventNotificationStatus.ActionPermitted;
The Job Extension
Next comes the job extension. Similarly, there’s an interface to implement. Remember to make sure that the namespace and class match the one used in the server plugin when queuing the job:
As above, here are the references and “using” statements you’ll need:

- using System;
- using System.Linq;
- using System.Xml.Linq;
- using Microsoft.TeamFoundation.Client;
- using Microsoft.TeamFoundation.Framework.Server;
- using Microsoft.TeamFoundation.WorkItemTracking.Client;
Note that the Client namespaces are used because of my specific example. Yours might vary. Of course, the Linq to XML namespaces are also a matter of personal choice. If you decide to parse your XML differently, you’ll use another library. You really didn’t need me to tell you that, right?
So now you should define your class (did I mention that you should make sure you got the FQDN right?):
- namespace JobExtensions
- {
- public class SampleWorkItemJob : ITeamFoundationJobExtension
- {
- private static object _jobLock = new object();
Wait a minute! What’s that lock about in line #5? I'll get to it later.
Anyway, the ITeamFoundationJobExtension has one method to implement, conveniently named Run:
- public TeamFoundationJobExecutionResult Run(TeamFoundationRequestContext requestContext, TeamFoundationJobDefinition jobDefinition, DateTime queueTime, out string resultMessage)
- {
- resultMessage = string.Empty;
Once again, we have an out parameter so we set it up. We will change it if there’s some information we wish to log (such as an exception).
Next we write the logic to handle the job.
- try
- {
- lock (_jobLock)
- {
- var jobDataXmlNode = jobDefinition.Data;
-
- // Expects node like <WorkItem>31</WorkItem>
- var workItemIdString = (from wi in XDocument.Parse(jobDataXmlNode.OuterXml).Elements()
- select wi.Value).First();
- var workItemId = int.Parse(workItemIdString);
-
- // In this example we want to work on the work item whose ID we added to the job, so let's get it
- var tpc = new TfsTeamProjectCollection(new Uri("http://localhost:8080/tfs/defaultcollectiton"));
- var store = tpc.GetService<WorkItemStore>();
- var workItem = store.GetWorkItem(workItemId);
-
- // Do something with the work item
- }
- }
Like with the server plugin, if we let an exception slip through the cracks, so we have to surround our handler with a try..catch clause here as well. As for the lock, in order to avoid collisions such as from trying to write to the work item store 50 times at once from 50 different job extensions, you’ll need to protect your resources. Job extensions will run at the same time, each in its own thread. They will all however run in the same process, the TFS Job Agent, of which you have only one on each Application Tier. Therefore a static lock object will do the job nicely.
the rest of the code in the block is of little interest; I use Linq to parse my XML node and deserialize the work item ID, which I need for my example. Your mileage may vary.
Not much more to it – You have your exception handling:
- catch (RequestCanceledException)
- {
- return TeamFoundationJobExecutionResult.Stopped;
- }
- catch (Exception exception)
- {
- resultMessage = exception.ToString();
- return TeamFoundationJobExecutionResult.Failed;
- }
What you want to do is to return a status of failure (or stopped if the request got cancelled). Additionally, you can return the exception details in the result message.
Finally, if everything went well, you’ll return a success status:
- return TeamFoundationJobExecutionResult.Succeeded;
That’s all there is to it!
You can download the complete solution here: RobustServerPlugin.zip.
Shmulik Segal, the head of the ALM team at Sela delivered a presentation on building software with TFS 2010. With a true-to-life story about a fictitious team of developers trying to deliver a product, he took us through the steps to creating a robust automatic build infrastructure for our product: from relying on drops provided by a developer, generated on his local machine, to an automatic build on a dedicated build server.
From this point, Shmulik showed us how to make our build stronger, by adding rules and policies that must be satisfied, such as architectural decisions, coding standards and the like, we can make code-reviews easier, by relegating the validation to the build-server, and providing feedback on the quality of our code within minutes of checking it in, rather than at the end of the release (if ever).

The talk also included:
- how to customize build definitions
- how to create and customize TFS build workflows with WF 4.0
- Comparisons between xml scripts of previous versions and other build systems, and the TFS workflow-based engine
- How to create your own custom build activities
Thanks Shmulik for a deep and advanced presentation on end to end building with TFS 2010
Today Yuval Mazor and I gave the talk above in front of ~20 people, as part of the ALM day of Sela Group’s Dev Days 2011. People were quite receptive – and I believe we got them to understand not only how you do things in TFS 2010, but also why. Some of the things we talked about:
- Best practices for managing software development projects with TFS 2010
- What are work items and how to use them (including customizations and links)
- How to properly build a branching plan
- Where and how to apply automated builds and CI
Unfortunately, we didn’t have enough time to cover TFS 2010 reports in detail – which means another talk is in order!
The presentation is available online here.
Thanks to Shai Raiten for the photography:

A big thank-you to our audience – it was great having you!
If you’re using the Agile MSF process template in TFS 2010, you might be using the built in Iteration Backlog document. If not, you might really want to. It’s a nice and simple to use Excel document, backed up with some macros for calculations (.xlsm file). If you’re already using it, you may have come across the following problem: some days that you mark as planned interruptions from work do not affect your remaining days!

This problem occurs in countries where the work-week is not Monday-through-Friday. Notice that the marked Days and Remaining Days are zero. Also, note that the date (03/04/2011 – that’s in dd/mm/yyyy format) is Sunday. In Israel, for example, Sunday is a workday, and should therefore count as one day.
To fix that, you need to change the function that calculates the two fields.
The default function for Days, which applies to the U.S. and countries with a Mon-Fri work week looks like this:
=IF(AND(ISNUMBER([@[Start Date]]),ISNUMBER([@[End Date]]), [@[Start Date]]<=[@[End Date]]),NETWORKDAYS([@[Start Date]],[@[End Date]]),"")
You need to replace the NETWORKDAYS function, with NETWORKDAYS.INTL (international) which accepts an optional parameter for declaring when the weekend is, as follows:
IF(AND(ISNUMBER([@[Start Date]]),ISNUMBER([@[End Date]]), [@[Start Date]]<=[@[End Date]]),NETWORKDAYS.INTL([@[Start Date]],[@[End Date]],7),"")
The added “,7” is the enumerated value of the kind of Weekend. I’ve added the look up table from Excel’s help, for your convenience:

Likewise, you need to replace the function for Remaining Days from:
=IF(AND(ISNUMBER([@[Start Date]]),ISNUMBER([@[End Date]]), [@[Start Date]]<=[@[End Date]]),IF(OR(IterationStart>[@[End Date]],[@[Start Date]]>IterationEnd,[@[Start Date]]>[@[End Date]],TODAY()>MIN(IterationEnd,[@[End Date]])), 0, NETWORKDAYS(MAX(IterationStart,[@[Start Date]],TODAY()),MIN(IterationEnd,[@[End Date]]),Holidays[Date])),"")
to:
=IF(AND(ISNUMBER([@[Start Date]]),ISNUMBER([@[End Date]]), [@[Start Date]]<=[@[End Date]]),IF(OR(IterationStart>[@[End Date]],[@[Start Date]]>IterationEnd,[@[Start Date]]>[@[End Date]],TODAY()>MIN(IterationEnd,[@[End Date]])), 0, NETWORKDAYS.INTL(MAX(IterationStart,[@[Start Date]],TODAY()),MIN(IterationEnd,[@[End Date]]),7,Holidays[Date])),"")
That’s all there is to it! Now you can enjoy properly reported Agile development even if your country has different work habits!
Hope this helps,
Assaf.
The decision to store team projects (TPs) in separate team project collections (TPCs) has implicit security aspects to it. Separating projects into multiple collections promotes security. To understand this, one must understand TFS’s topology.
Figure 1: TFS Logical Hierarchy
In TFS 2008 all of the team projects were stored in the same database. In 2010 this has changed; team projects are stored in team project collections, and each collection is stored in its own database.
This is often stated as a disadvantage of splitting projects into multiple collections, due to the fact that application-wise, you cannot cross the collection boundary. You cannot branch or merge code, query or link work-items, share project templates (though you obviously can clone definitions from one collection to the other). Also, Visual Studio can only connect to one collection at a time.
These disadvantages have a silver lining though: Security through isolation. Each collection runs in its own sandbox, and information in one collection doesn’t run the risk of leaking into another. Say, for example, that you split your TPCs along the lines of customers (each customer has his own collection). As a client, you’d want to be sure that work items and code will not be available to other clients – imagine what would happen if a client could gain information through the web-access or SharePoint portal!
Beyond the security afforded at the application level by the aforementioned “limitations”, and the fact that each collection has its own security and permission management (as does each project), the security can be further tightened by constraining access to the data at the database level, or even storing each collection on physically separate database altogether.
To summarize, separating projects into different collections, isolates them and thus promotes the security of the information stored there.
Tags: ALM TFS Team System Architecture
In my previous post I described a VCS branching plan that will remove the need to initiate code freezes. A few of my friends pointed out that their teams do not use that or similar methodologies not because they were unaware of such simple possibilities, but because performing reverse integrations (or any kind of merge) is so difficult with TFS (their ALM tool of choice), that most developers do everything they can (e.g. initiate code freezes) to avoid having to perform a lengthy and painful merge.
My advice is twofold. First, methodology-wise: Merge often! The more often you merge, the smaller and simpler the merge will be. As a rule of thumb, and assuming you are using the simple branching plan I suggested last week, you will want to merge every time you fix a bug (remember – you only merge when doing a reverse integration from a release branch to the main branch). For more complex plans, that have the actual development done on a separate branch from Main, requiring forward integration merges (i.e. from “Main” to “Dev”), you will want to merge on a daily basis, or whenever you know that there’s something to merge (from a release branch or a different development branch).
My second advice, to which I will dedicate the rest of this post, is to replace the diff / merge tool!
It is a well known fact, to those who know it well, that Microsoft have outfitted TFS with a less-than-adequate diff/merge tool, especially when compared to those available to users of SVN, Git, and Mercurial (to name a few).
How so? The primary issue I have with TFS’ default diff tool, is that it shows me which lines are conflicting, but it’s up to me to find out just how they differ from each other.
This is how the default tool shows the difference:
Found the difference? Difficult, isn’t it? The default diff-tool provided with TFS marks the lines that are different; it doesn’t show you what the actual change is.
Here’s what it looks like in KDiff3:
See the difference now? The actual changes are marked, not just the line. Makes comparing the code with the other version much simpler. By the way, in case you are visually impaired, what I did was replace the word “TFS” with “custom”.
The second, and more important part of the tool, is the actual merging capabilities. I’ve got a major gripe with the default tool as well. TFS’ merge tool performs a 2-way merge, where as other tools (KDiff3, for one) performs a 3-way merge.
What’s the difference you ask? Basically, a 2-way merge compares two files and attempts to best-guess what the differences between them are – this is rather error-prone, and thus requires more human intervention. 2-Way merges are good enough for simple merges, like those done every time you commit (or check in) changes to your code base. When you are trying to resolve a conflict between your changes, and the changes somebody else made, you just might be in for what is (dis)affectionately known as merge-hell. This happens when two developers made changes to the same source file, especially when the changes are located close to each other (i.e. same or consecutive lines of code).
3-way merges, on the other hand, compare both versions of the file to their parent version, and therefore can focus on comparing the changes made, rather than the complete files. This allows for a more reliable automatic merge, which means that the merge will be much simpler. Even if an automatic change is not possible, the tool’s focus on the actual changes helps the developer decide whether to include one or both changes.
Okay, I’m Convinced! Give Me the Goods!
Good! Luckily, it is very easy to replace the Diff/Merge tool in TFS. This is done on the client side, from within visual studio.
Following is a step-by-step guide for how to do replace the merge tool. I know that most of you don’t need this level of detail, but for those beginning developers or those of you whose brains have been terminally damaged by long hours of merge-hell, here it is:
Open the Tools | Options menu.
This will bring up the Visual Studio configuration window.
Now select the Source Control > Visual Studio Team Foundation Server menu. At the bottom, press the Configure User Tools… button.
This will open the (surprisingly named) Configure User Tools window
Press on the Add… button to add diff and merge custom tools. Doing so will open the following window (so many windows; I hope you aren’t confused):
Filling in the information is rather simple; You add the file extensions for which you wish the tool to be used (comma separated, prefixed with a period like “.cs”). You then select the operation you wish to associate with the tool. Note that for diff/merge tools there are two commands you wish to use – Compare and Merge. Remember to do both.
Next you select the command – that’s the actual tool you are going to use. KDiff3 is a great tool, both free and powerful (not to mention popular with the Git and Mercurial crowd. If they like it must be cool), and is my tool of choice. Other popular choices include Beyond Compare (version 3 and up only, as prior versions do not support 3-way merges, and you really want that for your reverse-integration merges), DiffMerge, and TortoiseMerge (especially if you were dragged away from SVN kicking and screaming).
Finally you enter the command arguments. If you are daunted (as I often am) by having to find out what arguments you need, then fear not! I found this great post from a few years back, that lists a whole bunch of tools with the command-line arguments you need in order to use for TFS.
For KDiff3, use the following argument values:
Selecting a better diff/merge tool will greatly improve your merging experience, and hopefully alleviate most of your pain when performing those reverse integrations. Remember to merge as often as you can, so that each merge will be small and painless.
If anybody has any other ideas, experiences on how to make using TFS’ version control system easier, please share!
It never ceases to amaze me, that to this day, I come across so many development teams that still initiate code freezes every time they release software. In this post I will show you why this is wasteful and how the need can be avoided altogether!
Code Freezing is the act of temporarily stopping all new development while focusing all of the resources on maintenance of the latest release. While releasing the latest feature set is usually the highest priority, it is often the case that the development team must divide their efforts between fixing the latest version (V-latest) and developing the next version (V-next).
Development teams and managers initiate code freezes because they cannot find a good, simple way to handle both development efforts at the same time.
Code freezes waste valuable time and resources. Each code freeze means that developers working on new features must either delay checking-in their code (until the freeze is lifted), or avoid working on the features altogether. Adding up the amount of time each developer is not working, or spending on complex check-ins & merges is the total amount of time wasted for each code freeze!
Fortunately, with most modern version control systems (TFS, SVN, etc.), it is possible to solve this problem, with a proper branching plan!
The following branching plan is just the core plan, which may be refactored to allow for multiple development and testing configurations, as well as more complex release mechanisms (e.g. releases, service packs, hot-fixes, etc.):
The plan consists of (at least) the following branches:
-
Main – On this branch the latest features are developed and tested. Your nightly build or cutting-edge version is built from this branch.
-
Release / Version – Whenever it is time to release a version, or before beginning to work on a feature for the next version, a new branch is made from Main. A release branch is made for each release version.
Working with the Basic Plan
-
The development team develops new features on the Main branch.
-
When it is time to release a version (to QA, end of sprint, etc.), and before developing features for the next release / sprint, make a Release branch (branch off main).
-
From this point on, the team keeps developing new features only on Main.
-
The team fixes issues with the latest release, only on the Release branch.
-
Important fixes from the version branch are reverse-integrated (RI) – i.e. merged back – into Main.
-
This process is repeated for each new version to be released.
Simple, isn’t it? I showed a friend of mine a draft of this post, and he asked “Isn’t this trivial? Why are you talking about this?”. I had to agree. It is trivial. But too few teams do this. I personally think that most teams simply do what they always did, because that’s how their managers did it when they were developers, a long, long time ago…
If you keep this up (dare I say religiously?) you will never have to freeze your code again; new features will never affect older versions. Developers can maintain old versions and develop new ones at the same time.
I think that once you try this, you will agree that this is a simple easy win.
If you want to learn more about branching plans for version control systems, a group called the VSTS Rangers (catchy, eh?) put together a great guide for branching with TFS. This guide can be easily applied to any VCS.
As for freezing yogurt, Please make mine with strawberries. It tastes great.
Hello all,
Last week I gave a lecture at Microsoft on the subject. It was a great experience for me, and I’d like to thank everybody who was there, and gave feedback. I hope to see you all again soon and really get to dig into the subject of exploratory tests with Pex.
As promised at before, here is the presentation and code samples I showed. Leave a comment or email me, if there are any questions regarding the code or the content.
The Presentation
Basic TDD Example
Example of Dependency Injection for TDD
Example of a Nondeterministic Dependency Problem
Classic TDD Solution to Nondeterministic Dependencies
Using Pex & Moles
Thanks,
Assaf.
Test Driven Development, or TDD for short. Some developers swear by it, others – at it. Few development teams in Israel practice it, much less do so successfully. The reason is that it is a whole new way to design software. TDD is a lot more than merely writing your test-code before writing your production code. It enforces a design paradigm on its practitioners, that is often radically different from how they would normally design their software, without the constraints imposed by TDD. Chief among them is the need to fake the dependencies of the unit under test.
In order to test a unit in isolation each and every other unit it depends on must be stubbed, or faked to return a canned response, so that a single determinable path will be executed, and that if any error occurs in the test, it must be in the unit under test, because everything else simply isn’t tested. This requirement can be extremely difficult, as soon as you need to test code whose dependencies aren’t accessed through an interface, are not virtual, or are static methods. Fortunately, there are techniques to get it done. Unfortunately, they complicate the code to a seemingly unreasonable degree.
This limitation often chafes at those who are not willing to accept the requirements “just for the sake of automating a test”, especially when doing so greatly increases the complexity of the code in order to appease the Gods of Unit Tests. Subsequently, many would-be TDDers abandon the benefits granted by it, in favor of the “normal” way they always did things – test last, if ever.
But it doesn’t have to be that way! Recent developments from Microsoft Research, allow developers to eat the cake and leave it whole. Enter Microsoft Moles. A mole is a piece of code – a method, or a getter/setter for a property – that replaces another, similar piece of code, in runtime, for the duration of the test, without affecting the production code. This technique works with the same ease regardless of the nature of the code that needs to be “dug under” (virtual or not, static or not, abstract or concrete).
The result is, that developers can go back to writing code as they would, regardless of their decision to use TDD, and still enjoy the benefit of an automated suite of tests guiding their efforts.
On May 10th, at the next session of the ALM User Group at Microsoft’s offices in Ra’anana, I will demonstrate this, and other techniques to alleviate the pains usually associated with test driven development. Check it out here, and register today. It’s free.