OK, let’s say you’re on a Scrum team that’s planning its next iteration. You pull a story to implement Feature X for the next release of Application Y. You review the specs, maybe have a conversation or two with the product owner to clarify a few details, and discuss implementation details with your team lead. Cool. Now, you design the feature, code it up, build it and tweak it until its working to your satisfaction. Then you check it into the source control system and move on to the next feature. Done, right? Not necessarily so! Sure, you can stand in front of the users at Sprint Review and watch them salivate as you demonstrate Feature X in action. But, can they walk out of the review and begin using it right away? Most likely not. If not, is it really done? “Code complete” is just one milestone on the yellow brick road to Emerald City, where users are happily whistling away while using your excellent Feature X in their Application Y. There is so much more to consider. What about unit testing? Integration testing? Acceptance testing? Documentation? Packaging? Deployment? Getting an application successfully delivered involves much more than working code. Failure to take this into account, and considering “code complete” to mean the same thing as “done”, inevitably causes a development team to fall behind schedule as they scramble to deliver what was already considered done. This is a form of technical debt, a topic I’ll explore in a future post. For more information on the meaning of “done”, check out this excellent podcast on HanselMinutes.com: What is Done? – A Conversation with Scrum Co-Creater Ken Schwaber
A bug is a bug is a bug, right? Not so! Most development shops treat a bug as a task. That seems reasonable - it's a bit of work that needs to be done. Unfortunately, it's not so easy. If a bug is discovered in a feature that is currently under development, and it will be fixed in the current Sprint (iteration), then the bug can and should be treated as a task. It would be considered a new Sprint Backlog Item that must be closed before the feature can be considered "Done". However, if the bug is not fixed before the feature is considered "Done" (yes this really happens), or the bug is discovered after the feature has be deemed "Done", then the bug becomes a bit of work to be scheduled into a future Sprint. In other words, the bug should be treated as a Product Backlog Item. The rule of thumb is rather easy really. If the bug is going to be fixed in the current iteration, then treat it as a task. If not, then the bug needs to go on the product backlog and be prioritized right along with all the other Product Backlog Items. Of course, this raises the question: What does "Done" mean exactly? Many dev teams grapple with this deceptively simple question. I'll explore this question in a future post.
In the process improvement goal setting post a few days back, I stressed the importance of making your goals specific (and thus measurable). Randy Eppinger made a good comment, and I felt to make it a bit more public, I'd copy that comment to a new post.
That's good advice. I find it helpful to do both. We create high-level objectives of the sort you listed like, "Reduce the number of bugs being released", "Assimilate new team members more easily". Then we create a list of milestones related to one or more high-level objectives. One or more team members takes ownership of achieving milestones which are more specific like, "Research and purchase a good book on unit testing techniques", "Create a Continuous Integration build for all code branches", "Create the Visual Studio 2005 section of the coding conventions document".
His comment reveals something that I missed. It's definitely possible to have both types of goal statements! In fact, setting concise, specific milestones is an excellent approach. As long as there is a visible, specific, MOTIVATING goal to move toward, you'll have more success in your process improvement. Thanks, Randy!
"Reduce rework", "Hit scheduled release dates", "Improve developer productivity"... We see these all the time as we work with companies on their process improvement initiatives. Unfortunately, they all lack specificity and measurability. Thus, they're both difficult to measure, and make lousy motivators. Instead, make your goals specific. TFS can help make the measurement of those goals easier or possible. For instance, replace "Reduce rework" to "Reduce time spent on bug fixes to 25% of total effort.". You could also use something such as "Reduce bug count to 15 per Scenario". Now, even though some scenarios are larger than others, you have an average target you can hit. Specific values are also motivating. When you are trying to limit the number of bugs to 15 per scenario, as the number of bugs increases, there is psychological pressure (and motivation) to ensure that further scenario development is conducted more carefully (possibly with the introduction of unit testing).
I've posted about this before, however, it's so important I'll repost. If you're trying to create a listener web service for TFS events, don't start from scratch! Use Howard van Rooijen's VS2005 template. It will create the web services, along with the appropriate signatures, as well as convert the events to an object, so that you can effectively use it.
One of the best things software development shops can do to improve productivity is to set Outlook to only check email once every hour (or 30 minutes at least). This is because people tend to take quite a bit of time to get back to difficult tasks. Email, and IMs, are difficult to ignore when that little "pellet dispenser" pops up on the lower left hand side of your screen. And once your mind strays it's hard to get back on task. A recent research project reported in the New York Times ( link - free registration required), bears this out. Here's the money quote:
In a recent study, a group of Microsoft workers took, on average, 15 minutes to return to serious mental tasks, like writing reports or computer code, after responding to incoming e-mail or instant messages. They strayed off to reply to other messages or browse news, sports or entertainment Web sites.
“I was surprised by how easily people were distracted and how long it took them to get back to the task,” said Eric Horvitz, a Microsoft research scientist and co-author, with Shamsi Iqbal of the University of Illinois, of a paper on the study that will be presented next month.
“If it’s this bad at Microsoft,” Mr. Horvitz added, “it has to be bad at other companies, too.”
So, turn off that email while you're coding! (And driving!)
Last year, at PDC, I sat down with Adam Cogan, of SSW, during an MSDN magazine party. Feeling the guilty pleasure of totally geeking out while a decent party was going on, Adam led a group of geeks through some of his very cool software tools. Somewhere during the discussion, he mentioned that he deploys his unit test, along with a test runner, with his shrinkwrapped application. That got my attention, since I'd never thought of them like that. I called him on it, and he explained. Now, there seems to be a visceral reaction from folks against the idea. Here's WHY it makes sense to deploy unit tests and a test runner with you application:
- Customer - "Your stupid app lost all my contact data!"
- Help Desk - "Maybe I can help. Go to Help -> Analyze"
- Customer - "OK. I see this list of green and red dots with text."
- Help Desk - "Can you read me the line next to the first red dot?"
- Customer - "It says 'Can't find database at C:\myapp\contacts.mdb'"
- Help Desk - "Hmm... Can you browse to that directory?"
- Customer - "No, I deleted it to have room for more mp3's"
- Help Desk - "Oh... That's a file required for our app to run. Did you subscribe to our backup service?"
- Customer - "Yes."
- Help Desk "Good, go to Tools -> Options -> Restore Contact..."
You get the idea. It rocks for troubleshooting those pesky support calls from customers. For a lot more information, and a very nice screenshot, see Adam Cogan's original posting on this topic! You can find the specific recommendation in his menu unit tests best practice. (While you're there, check out the rest of his best practices, he has a huge number of great ideas.)
Unfortunately, you cannot ship your Team System unit tests with your application. I know there's an NUnit to VSTS Unit Test converter. Does anyone know if VSTS Unit Tests can be converted to NUnit or MbUnit unit tests, so that all of us using VSTS Unit Tests can implement this best practice?
UPDATE: Adam Cogan claims he got the idea from James Newkirk (of NUnit fame). That may be the case, but I'll have to credit Adam. He's got so many best practices on his site (see this rule that covers shipping unit tests for an example) that if he didn't get the idea from Newkirk, he likely would have thought of it himself!
UPDATE TWO: This IS Adam's idea! James simply wanted a distributable test harness for developers to use! I misunderstood his first comment to me! (By the way, if you have comments on this post, or any other, please send email to steve+comments[at]accentient.com. We've had to disable comments until we find a way to more effectively eliminate comment spam.)
Here's a great tool for agile development that was mentioned in a blog post below. Go get a stack of these! Shuffle them, pass them around, put your use stories on them, and slap them up on the board when you're ready! Here's one more link.
 |
Post-it® Sortable Cards only stick when you want them to! Now you have the flexibility to visualize and organize when and how you want on many different surfaces. Cards also easily sort, shuffle and stack together so you can use them again, or store them for later. |
Bottom line up front: Create a 'root' branch directly under the source control branch associated with a new Team Project.I see this all the time... Someone creates a new source control branch in TFS and starts creating solutions underneath the default project branch. In other words, they end up with this: $/ProjectName /SolutionName1 /ProjectName1 /ProjectName2 /SolutionName2 /ProjectName3 /ProjectName4 Now, the difficult comes when the shop needs to create a second version of the application. Code branches directly under the root (i.e., $/ProjectName) can only be created when a new Team Project is created. If, in the above example, SolutionName1 and SolutionName2 both belong to the current version of the application, then creating a new version of the application will require either the creation of a new team project (with a branch from the $/ProjectName), or a wildly unweildly structure where each solution is branched, resulting in something like: $/ProjectName /SolutionName1 /ProjectName1 /ProjectName2 /SolutionName2 /ProjectName3 /ProjectName4 /SolutionName1_v2 /ProjectName1 /ProjectName2 /SolutionName2_v2 /ProjectName3 /ProjectName4 A MUCH cleaner approach is so simple, yet requires a bit of forethought. Immediately after creating the Team Project, simply go in an create a new directory called 'root' (or 'edge' or whatever you'd like). You can then create a full branch of the V1 off the application by simply branching 'root'. This allows This resulting in the following structure, even after creating a v2 of the project. $/ProjectName /root <-- Create this branch! /SolutionName1 /ProjectName1 /ProjectName2 /SolutionName2 /ProjectName3 /ProjectName4 /ProjectName_v2 <-- This is the branch of 'root' /SolutionName1 /ProjectName1 /ProjectName2 /SolutionName2 /ProjectName3 /ProjectName4 Now, whether you should have your projects under your solution directories... that's for another post...
How many build scripts do you need? There seems to be some massive confusion around TFS Build Scripts, namely, how many a single project needs. If your answer is one, you too have a misunderstanding!  In my experience, one build script is not nearly enough, in fact, I encourage several. Here's the why and how. Why: Visual Studio Team System (VSTS) and Team Foundation Server (TFS) is absolutely brilliant at tracking information related to a series of builds. That information is archived, analyzed and reported in a very useful fashion. BUT, it it reported by the NAME of the build. Thus, if you only have one build type, you can only have one set of reports! And that's no good! You need more. The primary reason for having more than one build type is to get good, easily understandable, accurate metrics.
- First, you need a build script for your continuous integration builds. This script runs every time someone checks in code (with certain restrictions). You likely won't want an aggregate report on these builds, except for rare cases -- there are just too many of them. This build is optional. I'm a fan of CI, but if it's a bridge too far, don't worry. The critical build is the nightly build...
- A TFS Build for your daily / nightly builds. This build runs every night at a set time. This build shows you what was accomplished during that entire day, including quality metrics, code churn, etc. This is one of the most valuable builds, since its reporting is clearly segmented by time -- one build per day. This allows a team to see what is being accomplished on a day to day basis.
- A TFS Build for weekly builds. This runs every weekend. Like the daily build, it will allow the reporting engine to show you what was accomplished that week, and how quality changes from week to week. This allows you to see aggregate changes over a chunkier time sequence, namely weeks.
- An end-of-iteration build. I've found you don't need to go any longer than weeks this for most projects, as far as reporting is concerned. However, you may choose to create a build that runs at the end of every iteration. This gives you metrics on what was accomplished during the entire iteration.
- An on-demand build. This one is used for folks who just need to trigger a build whenever. Unless it's necessary or useful, you may choose to have this build not report anything back to the data warehouse.
How: It's easy! The reason for all these builds was stricktly for the reporting. That means that each of these builds is likely going to be nearly identical! So, all you need to do is create the first build (the hard part), and copy it several times, giving it a different name each time. That's all there is to it! So, go forth and replicate those builds!
|