Posted on August 31st, 2006

Money magazine is running a story this morning entitled Why India will overtake China. It’s a good read, especially because I’m right in the middle of Tom Friedman’s The Word is Flat.

The real question is, with both countries getting access to better resources, better infrastructure, better engineers, and a better focus on developing math and science majors, how long will it be until they begin to outpace the US?

No Comments


Posted on August 25th, 2006

“Whatever you do, don’t touch that module of code. The guy who wrote it is no longer here, and no one knows how it works.”1 In Practices of an Agile Developer, Venkat Subramaniam and Andy Hunt put that quote as an example of something we are all afraid to hear, but probably have in our careers. They then go on to list a collection of practices which can keep you from hearing, or worse, saying that phrase. How do they do? Read the review below.

I was excited when I received this book. Having gotten the chance to meet and talk with both Venkat and Andy, I knew they were passionate about getting developers to understand how to deliver value to the customers. Both are proponents of Agile development in one form or another (XP, Scrum, Crystal, etc). But rather than try to sell you on one of the methodologies, they laid out seven goals:

  • Beginning Agility
  • Feeding Agility
  • Delivering What Users Want
  • Agile Feedback
  • Agile Coding
  • Agile Debugging
  • Agile Collaboration

In the first, Beginning Agility, they lay out the basics of becoming an Agile developer. Things like Working for Outcome (in other words, don’t blame people for bugs, find out how to fix them and fix the process that caused them) and Criticize Ideas, Not People. Or avoiding the pitfalls of making quick hacks without trying to understand why the hack was necessary (Quick Fixes Become Quicksand). They finish up the chapter with a key word I personally feel is absolutely necessary in software development – courage. They put this in the context of Damn the Torpedoes, Go Ahead. In other words, if the code you are working on is stinky, and you’d like to throw it away, don’t be afraid to bring that up. Or if code you are in the middle of building suddenly becomes the wrong direction, stand up and explain that (being sure that in both circumstances you have alternatives for getting it on the right track).

The second chapter, Feeding Agility, discusses ways to keep the flow going while being Agile. Things like Keeping Up With Change remind us to keep our skills sharp and honed. Invest in your Team shows that if you don’t bother to spread your knowledge, they’ll be unlikely to spread theirs with you, and if the goal is to deliver the best product we can to our customers, that just seems counterintuitive. Of course, it is just as important to Know When to Unlearn. Sure, that ASP solution you’ve had for 10 years works Ok, but that shouldn’t stop you from exploring other new technologies. When you don’t understand something, you should Question Until You Understand and finally Feel the Rhythm that Agile brings.

Now comes the contentious part. If our goal really is to deliver the most value to our customers that we can, then it makes sense that they should be able to drive the process. In Delivering What Users Want we hit some turbulent waters with topics like Let Customers Make Decisions, Let Design Guide, Not Dictate, and Fixed Prices are Broken Promises. But, to me, this is one of the most important chapters, and they do a good job of explaining how to accomplish all that with things like Getting Frequent Feedback, Automating Deployment Early, Integrate Early, Integrate Often, and Keep It Releasable. In addition, the use of Short Iterations and Releasing in Increments helps keep the flow going and communication with the customer high.

In order to keep up with the high level of customer communication (and confidence), you are going to need assurances your system is working properly. In Agile Feedback, Andy and Venkat discusses ways to get feedback in ways other than from your customer. At this point, if you’ve been on traditional projects, you are probably thinking the only way you could do this is with Angels on Your Shoulders, which they explain how to get with a safety net of automated unit tests. To really get a good sense of how to keep the design clean, they use techniques such as Use It Before You Build It and running it on a build machine other than your own since Different Makes a Difference. Finally, to understand how you are really doing, you have to Measure Real Progress which you can do through Automating Acceptance Testing (using something like FitNesse). Finally, you have to Listen To your Users. Similar to the way that you should treat compiler warnings as errors, customer complaints are a sign that something is wrong – especially if it is a high number of customers experiencing the problem.

Now that you are Agile with your customer, the authors begin to target the specific code you are writing in Agile Coding. This is a list of some key tenants of good development, such as Programming Intently and Expressively and Communicating in Code (and not chiefly through comments, either!). But there are some practices that are harder, but just as important like Keep It Simple, Actively Evaluate Trade-Offs and Code in Increments.

No matter how hard we try, though, defects still creep in. Or, we don’t get the chance to work with pretty Greenfield code, but are dropped in the middle of a big ball of mud. How do we get out? In Agile Debugging, Andy and Venkat cover some great techniques including Warnings Are Really Errors (mentioned above), Report All Exceptions, and Provide Useful Error Messages (not like the ones found on The Daily WTF).

But one of the techniques was something I had not done before, and I thought was excellent – a Solutions Log (also called a Daylog). In other words, when you come across a problem, document it, and when you solve it, document it. No doubt, you’ll come across that problem again, and when you do you’ll be glad to be able to go back and figure out how you solved it – especially if you don’t have the code you fixed it in the first time. (I have a tendency to record anything I come across that I know I will see again on my blog, and I tell you that typing a question into Google and the first result being your own website is the perfect way to make you feel like a total moron).

The final section, Agile Collaboration, is my idea of a dream team. First, you have to Schedule Regular Face Time to talk about what is going on in the project – especially if you all are working on the same code base! You have to be able to practice Collective Code Ownership (meaning anyone should have the knowledge to change another part of the system), and also means that Architects Should Write Code. To help grow the team, you can Be A Mentor, but to do it effectively you have to Allow People To Figure It Out. Some final practices are around respecting your team by Sharing Code Only When It’s Ready, being available to Review Code, and Keeping Others Informed about what you’ve learned.

I enjoyed the layout of the chapters too. Each one starts with a “devil” which often times was saying something I’ve heard on one team or another. It finishes with an “angel”,a nd a section of what it feels like to be doing the practice. Andy and Venkat also pepper the text with plenty of real world situations that reinforce just how bad software development can be.

In summary, if you want to be a better developer, but think Agile is a misused buzz word, go to your local bookstore, put a small piece of masking tape over the word “Agile” in the title, and buy this book. You won’t regret it.

1Practies of an Agile Developer, pg. 17

1 Comment


Posted on August 22nd, 2006

In our first segment we got up and running with NUnit, created the foundation of our BowlingGame and got spares working. But spares aren’t what bowlers live for – it’s strikes. Let’s see if we can get that working.

Back to the problem at hand. We’ve got the tests passing for Spares, so let’s see about Strikes. The tests should be similar, except that scoring has to take into account the next 2 rolls. Here’s our first test:

[Test]
public void FirstFrameStrikeRest2sShouldScore50()
{
  game.RollStrike();
  RollFrames(2,2,9);
  Assert.AreEqual(50, game.Score, "Should have a final score of 50");
}

Which, of course, doesn’t compile. So, let’s add the RollStrike with an empty method body and run our tests:

To pass it, we’ll have to take into account strikes in our scoring method. We’ll change RollStrike() to:

public void RollStrike()
{
  Frame frame = new Frame(roll1, roll2);
  frame.IsStrike = true;
  AddFrame(frame);
}

But, that’s not entirely correct! A frame with a strike can only have one roll – the first one for 10 pins. So, let’s just create a Strike class which inherits from Frame to do the same thing:

using System;

namespace Bowling
{
  public class Strike : Frame
  {
    public Strike() : base(10,0)
    {
      this.isStrike = true;
    }
  }
}

And we’ll change isStrike, roll1 and roll2 to be protected in Frame. We’ll change isSpare to protected since I think I’m going to want to do the same thing there – but not yet, because we are on a red test!

Ok, now that we’ve got the Strike class, we’ll change BowlingGame to use it:

public void RollStrike()
{
  Strike strike = new Strike();
  AddFrame(strike);
}

And run our tests:

Closer. Now, let’s take the strike into account in Score:

if(frame.IsSpare)
{
  Frame nextFrame = (Frame)frames[currentFrame+1];
  score += nextFrame.Roll1;
}
else if (frame.IsStrike)
{
  Frame nextFrame = (Frame)frames[currentFrame+1];
  score += nextFrame.TotalRoll;
}

Since we’re on green, I’m going to refactor the Spare method to use polymorphism:

using System;

namespace Bowling
{
  public class Spare : Frame
  {
    public Spare(int roll1, int roll2) : base(roll1, roll2)
    {
      this.isSpare = true;
    }
  }
}

public void RollSpare(int roll1, int roll2)
{
  Spare spare = new Spare(roll1, roll2);
  AddFrame(spare);
}

And, all of our tests still pass! Now, let’s exercise the Strike a little more. Let’s see what happens when the first two frames are strikes.

[Test]
public void FirstTwoFramesStrikesRest2sShouldScore68()
{
  game.RollStrike();
  game.RollStrike();
  RollFrames(2,2,8);
  Assert.AreEqual(68, game.Score, "Should have a final score of 68");
}

Looks like we’re off by 2. Aha! Look at our scoring code:

else if (frame.IsStrike)
{
  Frame nextFrame = (Frame)frames[currentFrame+1];
  score += nextFrame.TotalRoll;
}

To score a strike, you take 10 and add the next 2 rolls. In this case, if the next roll is a strike, there is only one roll, so we are missing the second roll (really the first roll of the third frame). Let’s change that:

else if (frame.IsStrike)
{
  Frame nextFrame = (Frame)frames[currentFrame+1];
  score += nextFrame.Roll1;
  if(nextFrame.IsStrike)
  {
    Frame thirdFrame = (Frame)frames[currentFrame+2];
    score += thirdFrame.Roll1;
  }
}

And run our tests:

Woah! Not only did that not pass our strike test, we now have a second test that is failing. Let’s see – Ah! I missed a step:

else if (frame.IsStrike)
{
  Frame nextFrame = (Frame)frames[currentFrame+1];
  score += nextFrame.Roll1;
  if(nextFrame.IsStrike)
  {
    Frame thirdFrame = (Frame)frames[currentFrame+2];
    score += thirdFrame.Roll1;
  }
  else
  {
    score += nextFrame.Roll2;
  }
}

Much better. Although I don’t like the Score “Property” any more because it is doing a lot of work. Let’s see if we can clean that up. First, we seem to do a lot of work to figure out the next frame. If we made the frames a simple LinkedList, we could just ask a frame for the one after that. First, we’ll modify our Frame class:

protected Frame nextFrame = null;

public Frame NextFrame
{
  get{return nextFrame;}
  set{nextFrame = value;}
}

Next, we’ll modify our BowlingGame to hold on to the first frame and last frame bowled, and then modify AddFrame to use that:

private void AddFrame(Frame frame)
{
  if(firstFrame == null)
  {
    firstFrame = frame;
    lastFrame = frame;
  }
  else
  {
    lastFrame.NextFrame = frame;
    lastFrame = frame;
  }

  if(frames.Count == 10)
  {
    throw new OutOfFramesException();
  }
  frames.Add(frame);
}

Note that our tests should still be passing since we’ve only added code. Let’s see if they are:

Good. Now, let’s modify score to use this:

public int Score
{
get
{
  int score = 0;
  Frame currentFrame = firstFrame;
  while(currentFrame != null)
  {
    score += currentFrame.TotalRoll;
    if(currentFrame.IsSpare)
    {
      score += currentFrame.NextFrame.Roll1;
    }
    else if (currentFrame.IsStrike)
    {
      score += currentFrame.NextFrame.Roll1;
      if(currentFrame.NextFrame.IsStrike)
      {
        score += currentFrame.NextFrame.NextFrame.Roll1;
 
     }
      else
      {
        score += currentFrame.NextFrame.Roll2;
      }
    }

    currentFrame = currentFrame.NextFrame;
  }

  return score;
}
}

Ok, let’s see if our tests still pass:

And they do! We can now remove the ArrayList code, and run our tests to make sure we don’t break anything:

As you can see, our OutOfFramesException is now failing. We can clean that up by numbering our frames. First we’ll add a property to our Frame class for Number:

public int Number
{
  get{return frameNumber;}
  set{frameNumber = value;}
}

Then we’ll modify our AddFrame method in BowlingGame to set the Frame number:

private void AddFrame(Frame frame)
{
  if(firstFrame == null)
  {
    frame.Number = 1;
    firstFrame = frame;
    lastFrame = frame;
  }
  else
  {
    if(lastFrame.Number == 10)
    {
      throw new OutOfFramesException();
    }
    frame.Number = lastFrame.Number + 1;
    lastFrame.NextFrame = frame;
    lastFrame = frame;
  }
}

And that gets us back to green. (But, did it really help? I’m not so sure…)

So now we have strikes and spares working, but we haven’t given any attention to the 10th frame rule. I can think of one test case which will force us to exercise that – the perfect game:

[Test]
public void PerfectGameShouldTotal300()
{
  for(int i = 1; i <=10; i++)
  {
    game.RollStrike();
  }
  Assert.AreEqual(300, game.Score, "Perfect game should equal 300");
}

Running that gives us a null reference exception, something I was expecting:

The problem is this line from our Score in BowlingGame:

score += currentFrame.NextFrame.NextFrame.Roll1;

When we are on the 9th frame, the NextFrame would be the 10th, and the NextFrame would be null. One way we can fix this would be to do a check to see if the NextFrame of the NextFrame is null, but that wouldn’t help when we got to the 10th frame, saw we were a strike, and tried to get the next frame.

I spiked some different things, which all led to some not-so-good code. I looked at our rolls, and realized that we have RollFrame, RollSpare and RollStrike, so why not RollTenthFrame, since it is specialized?

[Test]
public void PerfectGameShouldTotal300()
{
  for(int i = 1; i <=9; i++)
  {
    game.RollStrike();
  }
  game.RollTenthFrame(10,10,10);
  Assert.AreEqual(300, game.Score, "Perfect game should equal 300");
}

To make it compile, I put in a RollTenthFrame method:

public void RollTenthFrame(int roll1, int roll2, int roll3)
{
  Frame frame = new Frame(roll1, roll2);
  AddFrame(frame);
}

And ran my tests:

Wow! That’s pretty close. I realize now that the problem before was because I was marking the tenth frame as a strike, which it sort of isn’t (from a scoring perspective, at least). So, I wager that if that tenth frame returned all 3 rolls in the TotalScore, this test would pass. To do that, I’m going to add a bonusRoll field to my Frame class, and have TotalScore take it into account:

public class Frame
{
  //...
  protected int bonusRoll;

  //...
  public int BonusRoll
  {
    get { return bonusRoll; }
    set { bonusRoll = value; }
  }

  //...
  public int TotalRoll { get { return roll1 + roll2 + bonusRoll; } }
}

And then modify my RollTenthFrame to set the BonusRoll:

public void RollTenthFrame(int roll1, int roll2, int roll3)
{
  Frame frame = new Frame(roll1, roll2);
  frame.BonusRoll = roll3;
  AddFrame(frame);
}

Finally, let’s run our tests:

And we’re all green! There’s one more test I want to run that I heard about from Ron’s site. An alternating Strike/Spare game adds up to 200:

[Test]
public void AlternatingStrikesAndSparesShouldTotal200()
{
  for(int i = 1; i <= 4; i++)
  {
    game.RollStrike();
    game.RollSpare(4,6);
  }
  game.RollStrike();
  game.RollTenthFrame(4,6,10);
  Assert.AreEqual(200, game.Score, "Alternating Spares and Strikes should equal 200");
}

And…(Drum roll please)

Well, that’s all for now. We’ve bult a system, Test-First, which can calculate the scores of a bowling game. We ran into some snags along the way, but by keeping our tests green and taking small steps, we succeeded!

I have put up the full source for download, so feel free to open it up and play with it. Happy TDDing!

No Comments


Posted on August 22nd, 2006

A friend of mine, Tony, recently put up a blog post entitled Developers Considered as Obstacle to Agility, detailing some of the challenges he’s faced getting some of the XP practices adopted in his workplace. I had already been thinking about motivation and teams, based on a post on the XP mailing list by Kevin Lawrence:

I don’t know anyone who has chosen to learn TDD who has not become test-infected. Quite a few have reverted to test-after, but none have reverted to not testing at all.

Recently I’ve been reading a book called Understanding Motivation and Emotion by John Reeve. In it, he says that there are 2 main types of motivation – internal and external, and that the external motivation breaks down into 3 categories, giving us four types of motivation:

  • Intrinsic Motivation – “The innate propensity to engage one’s interests and exercise one’s capacities, and in doing so, seek out and master optimal challenges” [1]
  • Identified Regulation – Represents an external motivation that is fully internalized. The difference between this and intrinsic motivation is that the person asks if the thing is important, versus enjoyable.
  • Introjected Regulation – “…the person, /acting as a proxy for the environment/, emotionally rewards himself for performing other-defined good behavior and emotionally punishes himself for performing bad behavior” [1]
  • External Regulation – the prototype of external motivation, people are not motivated without the presence of external factors. For example, choosing not to study until a test is upon you.

[1] Reeve, John Marshall /Understanding Motivation and Emotion/ 122-123

I thought about this in the context of the two main ways agile is introduced at companies – as a top-down process, or as a grass-roots effort from the developers. From a top down, it becomes very easy to get people to do the practices – you have External Regulation, or “Do this, or you don’t have a job”. Unfortunately, as the book goes on to talk about, this generally kills the internal motivation, and people never really adopt it.

Contrast this to a developer starting a grass-roots effort. This lone ranger sees the value of XP and how it can help the teams. However, she doesn’t get the benefit of having the authority to externally regulate or even set up a situation where people can introject regulation. She must convince the developers to either become internally motivated, or and least internalize the external motivation for doing it (i.e. One may not fully understand the philosophy of TDD, but they do it because they understand they get better code out of it).

In other words, a developer trying to introduce agile has to jump 2-3 levels above the motivational techniques management has at their disposal. However, the reward for all of that work is that the developrs internalize the concepts, and therefore become more passionate about it. They truly “get it”, and are less likely to be pushed over by the wind.

Unfortunately, the amount of work can be daunting and slow. You have to fight a lot of battles, and even if you think you are winning the war, you have lots of people saying you aren’t.

So, to those of you fighting the XP grass-roots battle, doing XP For One and working your tail off, be encouraged that the way you are introducing the practices is the best way to introduce new ideas if you want people to truly understand them. It will be a long road, and it will be a tough one, but the payoff at the end is truly worth it (“Hey, I get this TDD thing now!”).

1 Comment


Posted on August 18th, 2006

One of the canonical examples of Test Driven Development is Ron Jeffries‘ Bowling Game. It’s been done many times, and Ron has done several articles about various methods and outcomes from his experiences in doing the game for groups.

A couple of months ago, I found out I was going to be speaking at a Code Camp in Tampa, FL. One of my sessions was on TDD, and I decided what better example then the bowling game? Except – I’ve never actually gone through the bowling game example, or fully read through Ron’s articles on it. So I decided to give it a go and do the bowling game to see what path it led me down.

I fired up Visual Studio and created two projects – Bowling and BowlingTests. I then created a new class in BowlingTests called GameTests and created my first test method:

using System;
using NUnit.Framework;

namespace BowlingTests
{
  [TestFixture]
  public class GameTests
  {
    [Test]
    public void ThisWorks()
    {
      Assert.IsTrue(true);
    }
  }
}

I built the project, fired up NUnit, and pointed it at my newly minted BowlingTests dll. Running it got me:

Great! Everything is hooked up, and I’m ready to get down to business. Now, I know that a regular bowling game consists of 10 frames with up to 2 tries for each frame, except for the last frame when you can roll 3 times if the first roll was a strike or the second was a spare. Whew! That sounds like it could get complex, so let’s think of a case which wouldn’t require us to invoke that last frame rule – I know, all gutter balls!

[Test]
public void AllGutterBallsShouldScore0()
{
  BowlingGame game = new BowlingGame();
  for(int frame=1; frame<=10; frame++)
  {
    game.RollFrame(0,0);
  }
  Assert.AreEqual(0, game.Score, "All gutters should have a final score of 0");
}

Ok. Well, compiling this fails, since we don’t have a BowlingGame class, much less all of those methods. Let’s create just enough to get this to compile. So over in the Bowling assembly, I create a BowlingGame class:

using System;

namespace Bowling
{
  public class BowlingGame
  {
    public BowlingGame(){}
    public void RollFrame(int roll1, int roll2){}
    public int Score
    {
      get{return 0;}
    }
  }
}

And…everything compiles! Let’s run our tests to see what we need to do next:

Wow! All our tests pass. How is that possible? Well, if we look at our test, we are expecting after all the rolls for the score to be 0. Since we stuck in a 0 to make the compiler happy in our Score property, it made our test pass as well. The lesson here is that you should always run your tests – you never know when one might pass unexpectedly.

Ok, enough of that, let’s get a real test under our belts. The next thing I can think of is a game where we roll all 2s, or a total of 4 per frame, giving us a total of 40. Let’s create that test:

[Test]
public void All2sShouldScore40()
{
  BowlingGame game = new BowlingGame();
  for(int frame=1; frame<=10; frame++)
  {
    game.RollFrame(2,2);
  }
  Assert.AreEqual(40, game.Score, "All 2s should have a final score of 40");
}

And let’s run that:

Aha! A failing test. Let’s get it passing by doing some scoring in our BowlingGame. The class now looks like:

public class BowlingGame
{
  private int score = 0;

  public BowlingGame(){}

  public void RollFrame(int roll1, int roll2)
  {
    score += (roll1 + roll2);
  }

  public int Score
  {
    get{return score;}
  }
}

Pretty easy, we just keep adding the frames to the score, and return it. Let’s see if it passes our tests:

Now that we have a green test, let’s look at our code. TDD is a cycle which goes Red->Green->Refactor. In other words, write a failing test, write the code to make it pass, and refactor duplication. Looking in our BowlingGame class, we don’t see much duplication, but in our tests we do. Since our tests are code like anything else, we can using refactoring techniques like extract method to help clean it up. The main difference is that readability is key in tests, so be careful not to refactor so much that it becomes difficult to understand what is going on in the tests.

The first duplication is around the setup of the BowlingGame. We can make that an instance variable, and create it before our tests are run. NUnit helps us out by providing a [SetUp] attribute we can tag a method with. So, we now have something like:

BowlingGame game = null;

[SetUp]
public void SetUp()
{
  game = new BowlingGame();
}

SetUp will be run before every test, reinitializing our game variable. In addition, you can have a [TearDown] method to do any cleanup.

Now our test methods look like:

[Test]
public void AllGutterBallsShouldScore0()
{
  for(int frame=1; frame<=10; frame++)
  {
    game.RollFrame(0,0);
  }
  Assert.AreEqual(0, game.Score, "All gutters should have a final score of 0");
}

I compile and run the tests to make sure nothing breaks, and all is green. But I still see some more duplication, in the rolls. So, let’s extract out a method called RollFrames which takes in a pin count for roll 1 and 2, and does that for the specified number of frames:

private void RollFrames(int roll1, int roll2, int numberOfFrames)
{
  for(int frame=0; frame < numberOfFrames; frame++)
  {
    game.RollFrame(roll1, roll2);
  }
}

And now our test methods look like:

[Test]
public void AllGutterBallsShouldScore0()
{
  RollFrames(0,0,10);
  Assert.AreEqual(0, game.Score, "All gutters should have a final score of 0");
}

And again I run the tests, and they stay green. It is important to run your tests after every change, and to keep them running fast enough that you can do that.

Well enough about that, let’s get some spares going! In bowling, you score a spare by knocking down all remaining pins during your second roll of a frame. To score it, you get 10 points, plus whatever your next roll is. Rather than explain some scenarios, let’s write some!

In our first case, our first roll is a spare, and the remaining rolls are 2s:

[Test]
public void FirstFrameSpare
Rest2sShouldScore48()
{
  game.RollSpare(2,8);
  RollFrames(2,2,9);
  Assert.AreEqual(48, game.Score, "Should have a final score of 48");
}

Why 48? Well, because our first frame is a spare, and the first roll of the next frame is a 2, the score for frame 1 is 12. We then add that to the remaining 9 frames which are each 4 points (2 for each roll).

We would run the tests, but our code isn’t compiling, because RollSpare isn’t valid. Let’s add it to our BowlingGame class:

public void RollSpare(int roll1, int roll2) {}

Ah, much better. Now, let’s run our tests:

Which makes sense, because we aren’t actually doing anything inside the RollSpare method, so Frame 1 isn’t being added to the total score. However, now we are at a design point. In order to score Frame 1, we have to know what Frame 2’s first roll is, which also means we need to know what each roll for a frame was.

There are a couple of directions, but I’m going to create a small Frame class which holds two variables, Roll1 and Roll2, and a flag to say if that frame was a spare. So, in my Bowling assembly, I create Frame.cs:

using System;

namespace Bowling
{
  public class Frame
  {
    private int roll1;
    private int roll2;

    public Frame(int roll1, int roll2)
    {
      this.roll1 = roll1;
      this.roll2 = roll2;
    }

    public int Roll1 { get { return roll1; } }
    public int Roll2 { get { return roll2; } }
  }
}

and switch BowlingGame to use this:

using System;
using System.Collections;

namespace Bowling
{
  public class BowlingGame
  {
    private int score = 0;
    private ArrayList frames;

    public BowlingGame()
    {
      frames = new ArrayList();
    }

    public void RollFrame(int roll1, int roll2)
    {
      frames.Add(new Frame(roll1, roll2));
    }

    public void RollSpare(int roll1, int roll2)
    {

    }

    public int Score
    {
    get
    {
      foreach(Frame frame in frames)
      {
        score += (frame.Roll1 + frame.Roll2);
      }
      return score;
    }
    }
  }
}

So we see that Score is now responsible for calculating the score from the Frames. Notice also that we still haven’t done anything with RollSpare mainly because I felt this was a bigger step and wanted to make sure we didn’t break anything. So, we should be able to rerun our tests and still see the Spare test failing:

Whew. I didn’t really like doing that on the fly, but it seems to be Ok. So, let’s get that spare test passing. I change RollSpare to look like:

public void RollSpare(int roll1, int roll2)
{
  Frame frame = new Frame(roll1, roll2);
  frame.IsSpare = true;
  frames.Add(frame);
}

and also change the Frame class to be aware of the IsSpare property:

public bool IsSpare
{
  get{return isSpare;}
  set{isSpare = value;}
}

Running our tests shows that we are closer…

…but no cigar. That’s because our score method doesn’t know about Spares, so it is just blindly adding together scores. Let’s fix that:

public int Score
{
  get
  {
    for(int currentFrame = 0; currentFrame < frames.Count; currentFrame++)
    {
      Frame frame = (Frame)frames[currentFrame];
      score += (frame.Roll1 + frame.Roll2);
      if(frame.IsSpare)
      {
        Frame nextFrame = (Frame)frames[currentFrame+1];
        score += nextFrame.Roll1;
      }
    }
    return score;
  }
}

And let’s run our tests:

Yay, they’re green! So let’s look at our code. The first thing I notice is that Score is returning the variable score, but isn’t declaring it. Ah, it was declared as a field instead of as a local variable. We fix that and run our tests. Still green! Secondly, I don’t like the casting, as I know we can use generics, but since I have control over the Array, I’m not going to worry about it for right now. I also see the following line:

score += (frame.Roll1 + frame.Roll2);

Surely we can just ask the frame for the total roll, so let’s modify Frame:

public int TotalRoll { get { return roll1 + roll2; } }

And modify our Score:

score += frame.TotalRoll;

A quick compile and run of the tests – yep, we’re still green!

Ok, now that we seem to have Spares working, let’s make sure. First, let’s do a game with the first 2 frames as spares, and the rest as 2s:

[Test]
public void FirstTwoFramesSpareRest2sShouldScore52()
{
  game.RollSpare(2,8);
  game.RollSpare(2,8);
  RollFrames(2,2,9);
  Assert.AreEqual(52, game.Score, "Should have a final score of 52");
}

A quick compile and run of the tests:

Egads! 60? Hmm, maybe my math was off, let me see. Aha! I see the problem. I copied the test from the above one, and added in the second Roll Spare. I forgot, however, to change the RollFrames from 9 to 8. Let me fix that and then we can clean it up…

Egads! Ok, this time my math was off. The first two frames equal 24, leaving 8 remaining frames, giving us a total of 56. Let’s fix that:

[Test]
public void FirstTwoFramesSpareRest2sShouldScore56()
{
  game.RollSpare(2,8);
  game.RollSpare(2,8);
  RollFrames(2,2,9);
  Assert.AreEqual(56, game.Score, "Should have a final score of 56");
}

And…

All green! Now I feel a little more confident in the scoring capabilities (and less confident in my addition skills).

Let’s go back to the problem we had above. A game should never have mor
e than 10 frames (unless you are Ishmael Boorg). So, let’s write a test that ensures that:

[Test]
[ExpectedException(typeof(OutOfFramesException))]
public void TryingToBowlMoreThan10FramesThrowsOutOfFramesException()
{
  RollFrames(2,2,11);
}

We’re using another handy feature of NUnit – ExpectedException. This test will fail if the exception declared does not get thrown. Of course, this test isn’t compiling, so we’ll add the exception to our Bowling assembly and recompile. Now, let’s run our tests:

We’ll make this pass by tracking all frame adds through a method called AddFrame:

private void AddFrame(Frame frame)
{
  if(frames.Count == 10)
  {
    throw new OutOfFramesException();
  }
  frames.Add(frame);
}

This is probably not the best solution, since we are relying on convention to enforce a business constraint. But since our public contract controls access to the frames array through RollFrame and RollSpare, it should be fine for now.

Actually, we don’t know if it is a solution, because I haven’t run the tests yet! Let’s see if it is:

And, it looks like it is! That should help keep us from making silly mistakes in our tests. And it should help guide us when we come back to finish up strikes and the infamous 10th frame in the next article. Until then, happy bowling!

2 Comments


Posted on August 17th, 2006

In an XP project, you figure out what you are doing by looking at your backlog, or list of stories, for the current iteration (or sprint if you are into the Scrum thing). One key question your team has to figure out is where the stories will be listed. For example, many XP teams are collocated in a “war room” and have all the stories taped to the wall. This is great, because you can see at a glance what stories are left, and who is working on what. It’s not so great for anyone not in that room – which is why many teams turn to an electronic card tracking tool. Currently, we use a tool called ProjectCards, because our Product Manager is several states away. I’m also working on a personal project where we are using BaseCamp.

However, generally speaking, it is recommended that XP teams stay away from electronic tools wherever possible, as this quote from Ron Jeffries on the XP mailing list shows:

I do not recommend an “e-tool” to track stories, especially not within the team. The team’s focus should be in the room, on the work, not on some external computer gadget. Cards on the wall, stories on the whiteboard, that’s my preference.

So, why does it matter? Electronic, whiteboard, it’s all the same, right?

Today, I was talking with another team member about cards on the wall versus cards in ProjectCards, and the most wonderful example of the difference between the two happened. At our company, we have these things called Stars. Basically team members can “star” other team members who they feel have done an excellent job in some area. On the home page of our intranet, we have a list of the current stars, with their names hyperlinked to the description the nominator gave.

But, in our breakroom, we have a big Plasma TV. It cycles through various things, like new marketing materials, testimonials from our customers, and, most importantly, the current stars. However, instead of just listing all the names, it shows each one, displaying who was nominated, who nominated them, and the description of why they were nominated. Going into the break room to get a soda or some ice, one can’t help but glance up at the TV, and most times there is a star nominee on the screen, so you read through it. In the process, you get to learn something about the company you may not have otherwise.

And I think that is the key difference between the cards on the wall, and cards in a tool. Anything that requires work to look at, probably won’t be looked at without a good reason. Imagine this scenario. Let’s say we have the following user story:

Title: Financial Institution logs into their account and receives an inventory report
Description: When Financial Institution logs in, they should receive a list of widgets from their inventory that were recently updated. We already have a query, spShowInventory, we can reuse from the Frooble project.

Now, you were a developer on the Frooble project, who happened to write spShowInventory. Unfortunately, spShowInventory has the side effect of updating the view_count field in a certain table every time it is used, since that was the requirement of Frooble. However, the developers on this project don’t realize that view_count is going to be updated, and that when they release this to 1 million plus customers a day, contention for the table could seriously hinder performance.

In our first scenario, you see the card through your tracking tool. You see something like:

Upcoming Stories

  • Banking customer logs in and sees balance
  • Dealer clicks on report and gets charged standard price
  • Financial Institution logs into their account and receives an inventory report

You are working on the Dealer project, so you see the other stories, but none of them interest you enough to actually open them to see what they are.

In the second scenario, you walk up to the board to get your next story, and glance at the other stories that are up there. While scanning, you happen to see spShowInventory on a card, and look up to see what it is about. You immediately grab the card and find the team working on it, helping to avert serious disaster and perhaps the end of the world as we know it.

Ok, so perhaps that is a little extreme. But my coworker and I did comment that if they weren’t putting the nominations up on the TV, we probably wouldn’t have any idea what these other people were doing. One vote for Card Wall in my book!

No Comments


Posted on August 16th, 2006

At about 7:50 am EST this morning, the main fiber line to the datacenter that hosts my website and mail was severed by some construction people. Unfortunately, this meant that my site and mail were down all day, which was slightly nerve-wracking.

In the midst of it all, the hosting company I use – HostMySite – was able to get up an emergency page on their site (which was also affected) giving updates throughout the incident. In addition, they posted a photo gallery of what was going on, including the poor fiber cut (which looks like an OC-3).

I’ve been with HMS about 4 years now, and this was the first outage I have ever experienced. Kudos to the great job the company did. The best part was a letter they posted on the above page from a dedicated hosting customer which said in part:

I drove over this afternoon and spent quite a while watching from a distance. There were about 20 guys (from various utilities and contractors) all working purposefully around (and in) the trench. I initially looked for someone I could get a “true” update from and then noticed Lou (one of HostMySite’s owners) in the middle of them… encouraging, coordinating and passing out water to the workers. He also looked at his watch every 30 seconds or so.

Again, great job!

2 Comments


Posted on August 16th, 2006

Just a quick note to you racing fans that my employer is sponsoring a NASCAR Busch Series race (and driver!) this Saturday – the CARFAX 250, at Michigan International Speedway. There’s been a lot of excitement around it, and if it is anything like last weekend’s race at Watkins Glen, it should be a lot of fun to watch!

No Comments


Posted on August 10th, 2006

One site I read quite regularly is Damn Interesting, a site I found through my friend Brady. They usually have some great articles, but this one is just amazing.

During the early 1900s, a Russian photographer figured out a way to create color photographs from black and white film by using special plates and a filter process. Using this, he was able to take pictures like:


From: http://www.loc.gov/exhibits/empire/

The Library of Congress bought the pictures, and now has an exhibit online about them. I highly recommend checking it out!

No Comments


Posted on August 8th, 2006

Michael Feathers just posted a new tool he wrote called Vise. Basically it snapshots the values of your variables that you want to track, so if you rerun it it will catch anything that has changed or is missing. It’s still pretty Alpha stuff, but is definately worth a look.

No Comments