Posts tagged ‘XP’

Guidelines for the System Metaphor

Extreme Programming’s system metaphor, as traditionally presented, has a fatal flaw. It has a nudge which encourages teams to describe the system at too high a level, as one large monolithic thing. The result is nearly always the same: a generic metaphor that doesn’t really describe the software and provides next to no guidance for implementation. This has led many in the Agile community, including Kent Beck, XP’s creator, to abandon the system metaphor entirely. I have three big worries with this.

  1. While Beck may have changed his mind about many practices from XP, both versions of Extreme Programming, available in two editions of Extreme Programming Explained, are readily available and actively promoted by the publisher.  Treating both editions as equals curbs the adoption and spread of better practices.  The metaphor lives on in spite of being abandoned by its creator.
  2. Agile teams, while improving, have been generally slow to adopt now common knowledge on software architecture.  Deemphasizing the system metaphor has created a black hole in the software lifecycle around architecture and design.  Those teams that are software architecture-focused have a hard time figuring out how to remain agile while incorporating architecture best practices.
  3. Metaphors aren’t going anywhere.  They are a natural reaction to describing complex things – in literature, in life, and in software.  Ignoring the system metaphor makes it more difficult to use effectively.

So rather than fighting the metaphor as a tool for describing software architectures, we should embrace it.  It’s time to refresh the system metaphor by combining current best practices from software architecture with what we know works for metaphors in literature.

The System Metaphor, Refreshed

The ultimate goal of the system metaphor is to create a common vision and vocabulary for discussing and reasoning about a system – with all stakeholders.  This stands for the refreshed system metaphor too.  Communication is king in the abstract world of software architecture, and so communication is the ultimate metric for determining whether a system metaphor is good or bad.  Metaphors that enhance communication are better than ones that confuse or mislead the team.

To this end, there are five guidelines for evaluating metaphors to determine their fitness as aids for describing software architecture, and one corollary for sharing and using metaphors.

A good metaphor:

  1. Represents a single view.
  2. Deals with only one type of structure.
  3. Gives clear guidance concerning design decisions.
  4. Sheds light on system properties.
  5. Draws on a shared experience.

Corollary:  Even a good metaphor still requires explanation.

A good metaphor represents a single view.  It is now common practice when thinking of software architecture to describe a system using multiple views.  Views are like taking pictures of a 3D object.  While it would be nice to see the whole object, because a picture can only capture two dimensions at a time you’ll need several pictures to get a good representation of the object.  What this means for the system metaphor is that you will need more than one metaphor to adequately describe the system.

A good metaphor deals with only one type of structure.  Structures are the building blocks for an architecture and there are three basic kinds of structures in the software world.  Static structures deal with code – classes, modules, layers, and so forth.  Dynamic structures deal with running code – objects, tiers, processes, connections (e.g. a client connecting to a server) and so on.  Physical structures deal with, well, things in the real world, the hardware – computers and servers, routers and switches, as examples.

When creating a metaphor it should be a single view and deal with only one kind of structure at a time.  This aids with communication and reasoning by keeping things simple and by helping you compare apples to apples.  Use metaphors of things (i.e. nouns) to represent static structures.  Use metaphors of actions (i.e. verbs) to represent dynamic structures.  Physical structures are less abstract and are generally best served by being represented directly.

A good metaphor gives clear guidance concerning design decisions.  The metaphors you use should provide a guiderail for implementation by clearly communicating design decisions, background, and rationale.  Great metaphors will make it easy to connect higher-level, architecturally relevant design decisions and guidelines to the lower-level, implementation oriented design decisions.  Maintaining architectural integrity is, after all, a team responsibility.

A good metaphor sheds light on system properties.  One of the most important reasons to think about the architecture of a system is ensure that desired properties are promoted by the design. These properties are commonly articulated as quality attributes or quality requirements.  Having a clear understanding for why a set of structures and guidelines were chosen helps everyone to continue to support those properties in their low-level design decisions.

System properties are communicated through storytelling with the metaphor as the impetus for the story.  A good metaphor will make it easy to tell a story about desired (or undesired) system properties and how the design promotes (or inhibits) the properties.

Software architecture diagram showing use of the layered style as a bento box metaphor.

A good metaphor draws on a shared experience.  Shared experiences are the bedrock of any good metaphor.  Metaphors create a new vocabulary for discussing the architecture of a system and often rely on subtle nuances for sharing meaning.  For the metaphor to be effective, everyone on the team must have the background necessary to not only understand the metaphor but also understand the implications of the metaphor.  This shared experience might be technical in nature (documented architectural styles and patterns are an excellent source for a shared experience) or can be non-technical such as references to pop culture, movies, and food.

A common experience is also created through the act of choosing a metaphor and the best metaphors are those that the team arrives at together.  Metaphors bring with them a payload of information, pointers to design decisions, whiteboard discussions, arguments, code, guidelines, and many other important ideas important to a particular part of the system.  Having a relatable metaphor better facilitates communication and more easily brings to mind this history and data payload.

Corollary:  Even a good metaphor still requires explanation.  No metaphor can survive in isolation.  It is naïve to think that a metaphor, even a great one which satisfies all the other guidelines, will immediately make sense to a person who is hearing it for the first time.  Take the time to explain the metaphor to your team and create the shared experience necessary for everyone to relate to it.  Doodle on the whiteboard.  Sketch on paper.  Show them code.  Talk about quality attributes.  Once the intent and rationale behind the metaphor is commonly understood you may not need any documentation since the metaphor should immediately bring to mind all the important structures, guidelines, and properties relevant to that view of the system.

System Metaphor, a Great Addition to your Silver Toolbox

I’ve found the refreshed system metaphor to be extremely helpful, but it is not a panacea for agile architecture – it is no silver bullet.  The refreshed system metaphor is, however an excellent addition to your silver toolbox.  With this set of guidelines the system metaphor becomes, in my opinion, a viable tool for describing the architecture of a software system in many situations.  But your mileage may vary for non-collocated or especially large teams.  In these cases, metaphors will still be useful (they’ll come up naturally anyway), and you will need to supplement the metaphors your team uses with additional documentation.  A little documentation (the right documentation) never hurt anyone and even a lightweight architecture description document that assists with communication and understanding is worth its weight in gold.

Making metaphors that matter is difficult work.  It takes iteration and breakthrough insights over time to really discover the great metaphors that make sense.   With this set of guidelines in hand, knowing when you’ve discovered a good metaphor will be easy.

The system metaphor is dead!  Long live the system metaphor!

These guidelines were born from reflection on a recent project in which we used the system metaphor, as presented here, to effectively describe the architecture of our system as we built it. The guidelines, along with examples, were presented as an experience report, “Making Metaphors that Matter” (PDF), at the Agile2011 conference in Salt Lake City, UT. Slides from our talk are also available (PDF). Don’t hesitate to get in touch with questions, feedback, or insights using the comments here, email (mkeeling[at]neverletdown[dot]net), or twitter (@michaelkeeling).

See you at Agile2011 in Salt Lake City!

Here’s an introduction to my Agile2011 talk. Come hang out with me for 30 minutes on Tuesday, August 9 at 2:00pm in the LA Teton and bring your thoughts and questions about agile, architecture, and the system metaphor. And please show your interest on the conference schedule or twitter!

The system metaphor is one of the 12 key practices from XP and it is probably also the most controversial. Researchers at the Software Engineering Institute have observed that, of all the practices from Extreme Programming, the system metaphor is used the least. Other research done on graduate students at Carnegie Mellon concluded that natural language metaphors are useless for either communication or architecture design.

These are damning findings for the system metaphor, and yet on nearly every technical team with which I’ve built software, natural language metaphors were a daily part of how we communicated with each other. Maybe it has to do with the inherent abstractness of software, something that can’t be touched or tasted, only described. Maybe my teams have simply lacked the technical vocabulary needed to communicate in more precise words.

In spite of this nearly all of these projects were successful. Certainly there must be some merit in using natural language metaphors to describe a software system?

This got us thinking. Metaphors frequently come up in our everyday lives quite naturally and they are used effectively in books and movies. Is there something special about software that makes metaphors not work? Why would folks have such a hard time applying the system metaphor in practice when it’s obvious that metaphors in general are so effective in other places throughout our lives?

The simple answer is that we’ve been doing it wrong this whole time.

There’s nothing wrong with the system metaphor. It’s our application of the technique that has been wrong.

What’s missing from the prevailing literature on the System Metaphor is clear guidance that shows what a good metaphor should look like. Without this guidance, and without the background in software architecture to backfill this knowledge, teams are left alone to cobble together our own metaphors based on the limited information available on the Internet; a web of information that is largely an echo chamber of the same few sentences from the XP book. It should be no wonder that the system metaphor is unsuccessful in many cases.

What does a good metaphor look like? How do you know if you’ve created an effective metaphor? When should you create or update a metaphor? Why is one metaphor better or worse than another metaphor?

In looking for answers to these questions we combined what we knew about literary metaphors and software architecture practices to come up with a clear set of guidelines for the System Metaphor. These guidelines completed the System Metaphor definition and provided us with the guidance we needed to effectively design, analyze, and communicate the architecture of the software system we were building. We were no longer fighting our natural tendencies to create metaphors but instead were embracing them. And we created a more solid architecture as a result.

Interested in hearing more? If you’re going to Agile2011, why don’t you come to hear my talk? During this session I will explore our six guidelines for making better metaphors and walk through examples from our project. In only 30 minutes you’ll learn how to make metaphors that matter to your project, your team, and the system you are building in a way that improves team communication and encourages architectural thinking. This is a session you won’t want to miss!

I am speaking at Agile2011 in Salt Lake City, UT

Lightweight Experiments for Process Improvement

[This post is a recap on the second talk I gave at XP2010. This was the big one, the experience report talk, one of 15 experience reports published at XP2010. You can download the slides (pdf) or the full paper (pdf) from this website or from XP2010.org.]

Process improvement is important for nearly all teams but it can sometimes be difficult for a team to know what is working, what isn’t working, and what techniques or methods to try when attempting to improve. Performing a scientific experiment is one way help overcome these problems but as academic research has shown us, while experimentation can yield interesting results, running an experiment is time consuming, expensive, and requires some serious thinking and control to pull off. From a practitioner’s standpoint this means that experimentation is a non-starter.

Of course, that’s only if you run experiments like an academic.

Banner from the XP2010 conference in front to the hotel.

Back Story

Just over a year ago, my MSE studio team at Carnegie Mellon had a problem. We had decided we would use Extreme Programming for the construction phase of our project but some team members had doubts concerning pair programming. We had decided that we would use some kind of peer review, having already seen the many benefits of inspection when reviewing other artifacts. The dispute arose over whether pair programming would give similar enough results. Also, not all team members had experience with pair programming but everyone on the team knew and enjoyed solo programming.

The number one concern was whether pair programming would allow us to meet our very strict deadline. We had just over three months to complete the construction phase of the project. According to our threshold of success this meant implementing all “must have” requirements with a minimum level of quality. Did we really have time to waste by having two people working on the same code at the same time? Wouldn’t working independently and inspecting code on an as needed basis allow us to get more work done faster?

At the time it just so happened that I was taking a reading class with Mary Shaw and in that class we discussed some research findings that might help settle this debate. Research from Laurie Williams, Ward Cunningham, Barry Boehm, and many others showed that pair programming requires more effort (although never double the effort) but is faster than programming alone (pdf). Also pair programming creates code of about the same quality as coding alone with inspection (pdf). Of course, the research may not apply to us since Square Root is closer to a professional team working on a large project with a real client, not undergrads working on short term toy projects.

After an iteration where some teammates used pair programming and others refused, we decided to try an experiment to see which practice actually worked better. The original idea was that we might be able to validate some of the research but decided instead that it was more important just to resolve our own internal conflicts and figure out which processes worked better.

Conducting a Lightweight Experiment

With the scientific method as our guide we planned and executed a lightweight experiment which pitted programming alone against pair programming. The results were amazing (and you can find the raw data in our project archive). In conducting the experiment we used a set of novel techniques which I think can be useful in conducting other lightweight experiments. There’s more background in the experience report so I’m only putting the meaty stuff in this post.

Focus narrowly on a single question – The essential key to keeping an experiment light is to only tackle one thing at a time. In this case we focused on comparing and contrasting a single technique, pair programming, rather than multiple techniques or an entire process (such XP vs. TSP).

Divide work, not teams – If I were comparing pair programming to programming alone in an academic setting, I would put together two teams of about the same experience and have them each build their own version of the same software, one team using pair programming, the other programming alone. In a business setting this is a complete waste and few companies can afford to have two teams duplicating effort. By dividing work instead of teams you may lose some control over variables in the experiment but in most cases isolating more variables doesn’t add any further clarity to helping answer the narrowly focused question. To divide work successfully you need to have some way of estimating work units for division. We used use case points as shown in the figure depicting our modified planning game.

Steps in modified planning game for dividing work into experiment groups

Continue making releases – Since we still needed to make a comparison, rather than dividing into teams and duplicating effort we divided the features that were released each iteration. In this way we built about half the features released during an iteration using each technique. Working on about half the features using pair programming meant that at least some features were being built by individuals. At the time this was a risk reduction decision to make sure that if pair programming completely failed we’d still have something to ship at the end of the iteration. Explicitly managing risks is the only way to know if the lightweight experiment may cause problems for making releases. Also, we had a strictly defined cut-off for stopping the experiment if it ever stopped us from shipping to our client.

Use the data you have – In almost all cases we were able to get the data we needed to evaluate our hypothesis from our current process. When we couldn’t, we only had to make minor modifications to our data collection practices, for example adding a check box to our SharePoint server for indicating whether a task was paired or individual.

One of the more interesting things we did was to create a “tally sheet” for collecting pair programming issue detection statistics in real time, as the issues were discovered. Given the near instantaneous code-inspect-fix cycle when programming in pairs, this was the only way to collect similar data for comparing pair programming to inspection.

Example of a real time tally sheet used for tracking issues discovered while pair programming.

Statistical significance is overrated – The whole point of running a lightweight experiment is to collect just enough data to help you make a better decision or validate your gut feeling. This technique is not meant for uncovering universal truths or proving something to the rest of the world. In exchange for keeping the experiment light, the results will only apply to your team. Over the course of an iteration or two, 4-6 weeks, you’ll only get enough data to start to see trends. In our case the results were not statistically significant using individual T-tests but that didn’t matter. The most important thing is that we had data that could be used for comparison, data that everyone felt good about and that helped us gain clarity into what we did and how well it worked.

Retrospectives get immediate value – The whole reason the experiment is light is to reduce cost and decrease the lag time to providing value to the team. Just to give you a little perspective, it took us 6 weeks to run the experiment and had enough data and casual observations to make a decision during the retrospective when the analyzed data was shared. That event occurred in early August of 2009. This experience report required almost nine full months of gestation from the paper proposal to the talk I gave at the conference. The gestation period on “universal truth” research can be even longer. We, as practitioners, don’t have to wait for those universal truths to be born to get value from research. By running your own quick and dirty, lightweight experiments, you can get results in a timely fashion that you know will apply to your team because your team was the subject of the experiment. It’s all about closing the gaps between research and practice and taking the information you need now instead of waiting for academic research to catch up.

Overall Conclusions

For the Square Root team it turned out that pair programming was faster, cheaper, and produced code that had more predictable albeit slightly worse quality. The more important lesson is that we discovered a technique, lightweight experimentation, for learning other interesting things about our team and about software engineering in general.

My paper and this blog post were all about trying to describe the technique, using our experiment as an example. I think it would be awesome if teams around the world conducted lightweight experiments on a variety of topics. If enough folks share what they learn, we might start to see trends emerge across teams that could lead to universal truths, validate research, or at least discover some great rules of thumb.

What else might make for a great experiment? Anything you’ve got a question about on your team!

  • What is the clearer way to write requirements, user stories or use cases?
  • Which estimation technique is more accurate of X and Y?
  • Can we skip unit testing if we use inspection (looking at quality, knowledge sharing)?
  • Is UML a better design notation than the one we made up as a team?
  • What else…?

If you do a lightweight experiment, let me know! Share what you learn as a blog post or whitepaper. Let others know what you’ve learned! Even if the specific results only apply to your team and the way you’ve executed your project, your experiences help form a baseline, a sort of shared understanding for how software development works, how some of these practices work. And there’s so much about software engineering that we have yet to learn.

Acknowledgements

This paper was my first experience report and it was an awesome journey. Naturally a lot of folks helped me along the way and I would like to take a moment to make sure they know that I appreciate their influences and support. The Square Root team: Marco Len, Yi-Ru Liao, Abin Shahab, and especially my fellow experiment co-champion Sneader Sequeira for having the guts to go along with this idea in the first place. Some of the faculty at Carnegie Mellon: Dave Root and John Robert (my studio mentors) for bringing up the idea of writing a paper, and Jonathan Aldrich for helping review my proposal. Artem Marchenko was my XP2010 paper shepherd after the proposal was accepted, and the quality of each draft only improved because of his inputs. A group of my fellow employees at Net Health Systems sat through an early draft of the presentation I gave and shared valuable feedback for improving it. And finally I thank, Marie, my wife, who was with me from start to finish and read more drafts and sat through more practice talks than anyone else. She’s probably as much an expert on this subject by now as I.

A Final Aside

I wrote the initial draft of this paper as my final reflection paper for my Master of Software Engineering degree (pdf). That draft has a very different tone, approach, conclusion, and direction than what I eventually published for XP2010. This is half due to there not being a hard page limit but also I had a lot more time to think about what was really important when writing for XP2010. There’s some interesting information, mostly in the lessons learned, that might prove interesting to those who are interested. You should check out my Square Root teammates’ reflection papers as well since they are all interesting and well written.

See you at XP2010 in Trondheim, Norway!

As I’m writing this I am making final preparations to leave for Trondheim, Norway to present an experience report at the 11th International Conference on Agile Software Development and Extreme Programming, or XP2010. After my experience report was accepted, the conference organizers opened up a second round for lightning talk proposals, and in a moment of whimsy I decided to propose another talk. That was accepted as well. So I’ll be giving two talks at XP210.

If you’re at the conference I would very much like to meet you! This is my first time presenting at a conference and only my second conference attended (my first was OOPSLA this past October) so I’m a little nervous and unsure what to expect. Above all I hope that I’m able to share some information that is useful, interesting, and inspirational. I think I have some interesting insights and perspectives that can help make the way we build software just a little bit better and I want to hear your opinions, your thoughts and experiences too. If you can’t make it to my talks, come find me, I’d be glad to discuss any ideas with you. I plan to have a copy of the paper and slide decks available on this website along with a brief synopsis of the talks shortly after the conference. And of course I’ll be looking for people to eat meals with and hang out while I’m here on Wednesday and Thursday. I’m here to present, to learn, and to discuss cool ideas with other practitioners.

Here’s a summary of the two talks I’m giving along with some background information. The background isn’t necessary but just interesting information and context related to the talks.

Put it to the Test: Using Lightweight Experiments to Drive Process Improvement

This experience report tells the story of how my team ran a lightweight experiment to figure out whether we should use pair programming or program alone and review our code with Fagan inspection. With only a few hours of work and only a few weeks time we discovered that pair programming was instrumental to our eventual success.

In this talk I will discuss what we learned about setting up and running the experiment so you can run lightweight experiments of your own on whatever topics your team finds most interesting or pressing. Experimentation doesn’t have to be this overbearing, lofty, academic thing that it has become. My hope is that teams around the world will use this technique to discover just a little more about how software engineering works and that they’ll share what they learn in white papers, blog posts, and future experience reports. We can help close the gap between research and industry with just a sprinkling of scientific thinking.

Background Information

Lessons from a Software Engineering Dojo: The MSE at Carnegie Mellon University

At OOPSLA in Orlando, Florida this past October I heard proclamations like this more than a few times: “The only way to teach software engineering is through experience. What we really need is a software engineering program that uses a capstone project, a non-trivial, long term project that lets you practice what you learn. No university programs currently have such a project in their curriculum.” I agree. In fact, I agree so much that I attended the only university in the world in which a long-term, realistic (in both scope and complexity), team-based capstone project is an essential part of the software engineering curriculum.

I have two goals with this lightning talk. First, I aim to spread the word about the existence of the Master of Software Engineering program at Carnegie Mellon University. Carnegie Mellon is on the forefront of software engineering education research and the Master of Software Engineering program has been teaching professional software engineers to become true masters in the field for over 20 years. Second, since the studio component (the capstone project) of the MSE degree is so similar to an industrial setting, there’s a lot industry teams can use for training and educating software engineers as you work. There are tons of lessons that can be taken from the MSE in the form of both research and battle tested experiences. This second goal will be the greater emphasis of the talk.

Background Information

Tracking Bugs Better

Most software processes are light in two areas: quality assurance and process improvement. Most processes prescribe specific techniques for ensuring the production of quality code. XP for example advocates unit testing with TDD, continuous integration with smoke tests, pair programming, and acceptance tests written by the customer (using something like FIT so you can run automated regressions). Process improvement in XP is accomplished in a ’round the campfire, Kumbaya singing, get in touch with your feelings brainstorming session. Assumptions abound and there is no systematic way of ensuring that either testing or process improvement is handled adequately.  As we know, assumptions are never good enough.

The biggest assumption in XP (and indeed most software processes) is about bug tracking. Common sense dictates that you will create some kind of bug database. Hopefully it will at least be some kind of third party bug tracker such as Bugzilla or Bug Genie. Excel will work in a pinch but quickly becomes unsuitable for teams larger than one developer.  But how does the bug tracking actually work? What bugs get reported? Will you record issues from inspections in your bug tracker or only “true” bugs? What is the process for fixing a bug? What is the process for closing a bug? Who has access to the bug tracker? What information is required in your bug database and what information is optional? How do you determine defect priorities? Or the severity of bugs?

The majority of software processes provide answers for almost none of these questions. You are largely on your own to make up whatever you think makes the most sense for your development environment based on the best practices for your software process and your understanding of “good” software quality assurance practices.

No matter what quality process you follow, you will need a defect control philosophy. Once again, in absence of guidance I turn to the Team Software Process, one of the few processes to define what it means to track defects. In the Team Software Process, defects are treated as blight, a horrific mistake injected through the ineptitude of a developer. To remove these blights, the TSP relies on a series of filters in the form of code reviews, code inspections, unit tests, function tests, and so on. XP has a similar, though somewhat less rigorous set of filters in the form of pair programming, TDD, continuous integration, and acceptance tests. Each filter is meant to remove more and more defects, until finally “all” defects are removed from the system by the time the software has passed through all the filters. Generally each filter is intended to remove different types of defects, though it is conceivable to capture escaped defects from a previous filter in a later filter.

Just as water passing through layers of sand and rock will remove debris, so too will code passing through layers of unit tests and inspections sift out injected defects.

Water filter relying on a series of layers made of grass, sand, and charcoal to remove impurities from water.

Defect Data

With these ideas in mind, bug tracking has three basic goals.

  1. Record defects so they can be analyzed and fixed.
  2. Identify the means by which defects are injected.
  3. Identify the means by which defects are removed.

We write down bugs so we can go back and fix them later. This is obvious. But bug data can be used to measure process improvement also.

Since many parts of a software process are dedicated to filtering out the defects we’ve injected, understanding how defects are injected is essential to preventing similar defects from being seen in the future. The idea is that we want to learn from our mistakes. To achieve this, record the type of defect and the reason it was injected. The TSP gives us a good starting point for each of these, shown in the tables below. You should feel free to modify the types and reasons so they make sense for you, your team, and your project.

The defect type characterizes what kind of defect is injected and captures the essence of what is needed to fix the defect.

Defect Type Description
Documentation Problems with documentation, documents, comments, or messages
Syntax/Static This usually is a compile error. These days, this is most applicable to dynamically interpreted languages such as JavaScript or Python since compilation is basically free.
Build/Package Errors due to incompatible versions or problems with packages (e.g. Java).
Assignment Incorrectly assigning a variable or method, for example an incorrect expression or object assignment, calling the wrong method, or missing an assignment or method call.
Interface These are design problems, for example class interface issues or function parameter issues (e.g. order, type, or missing parameters).
Checking Problems arising from incorrectly handling errors. For example, an if-statement or loop invariant does not work as expected.
Data Defects involving data representations within the software.
Function Algorithmic or functional defects, usually involves more than a few lines of code.
System Issues that result from outside the software, for example hardware timing issues or network problems.
Environment This is development environment can is used to categorize problems in the environment such as compilers, frameworks, or support systems.

The defect’s reason characterizes why the defect was inject.

Reason Description
Education You didn’t really know how to accomplish something.
Communication You were misinformed through either documentation or personal communications.
Oversight You forgot to do something that you knew needed to be done.
Transcription You understood what to do but you simply made a mistake. (The Personal Software Process advocates writing down code, reviewing it, and transcribing it to the computer before compiling. This is a bit of a throwback and I’m not sure that it really makes sense these days. You might interpret this more loosely to be problems in translation from architecture or design to implementation).
Process The process you are using led you astray by encouraging you to make a mistake.

Assigning the reason can be a little tricky. I have found it is best if the person who injected the bug assigns the reason. On small teams (or if you’re following the PSP), this is generally pretty easy. It’s not about rubbing their nose in the problem – well, actually it is. Ok, it’s not about embarrassing or punishing the person but creating an opportunity for learning from our mistakes. If you can understand the reason why a defect was injected, it’s possible to prevent the defect from occurring again. For example, if there seems to be a rash of education related defects in a particular module, perhaps some training is in order.

Ideally we’d also like to know when the defect was injected, as in at what phase of development. It is possible to realize this information with additional analysis but I’ve found the return to be rather diminutive. Basically, you’ll learn what we’ve known all along – that the longer a defect is in the system, the harder it is to get out and that the most expensive defects are injected during the earlier phases of development (e.g. design defects are costly). Rather than track when things were injected I think it makes more sense to track when defects are detected. The point is to gain an understanding of how well the quality process filters out defects. To accomplish this, simply write down what you were doing when you found the bug. If you’re using XP, the list might include designing, writing new code (in a pair), writing new code (alone), refactoring, unit testing, integration, and acceptance testing. With this information you should be able to determine how effective each activity filters defects and over time whether the quality process is having issues. For example, I would expect interface defects to be detected during integration. If they are being detected earlier, say during unit testing, or later, say during acceptance testing, then my continuous integration and smoke test suite might not be as robust as it should be.

Better Bug Tracking

The strategies I’ve outlined here are a little more sophisticated than your average bug tracker, but add a lot of punch for very little effort. Tracking defect type, reason injected, and phase detected allow you to get a better handle not only on how defects are being injected into the software, but also how they are being detected. Both these chunks of information are necessary for understanding how defects are making their way into the system and how your process is helping you ferret them out of your system.