Acceptance Tests Keep You On Track

May 8th, 2006

We've been switching pairs a lot in an effort to try to share knowledge between team members before and it's been working really well. The downside to it though is that since the team owns the tasks and people swap between tasks so much (which is what gives the shared knowledge), there's always the danger that you will get off track and start wasting time writing code that isn't actually needed for the user story.

That's where acceptance tests should help out. You should be able to sit down to work on a story and decide to work on getting a specific acceptance test to pass. List out the steps required for that acceptance test and then start working on them. If you wind up changing pairs before the acceptance test passes, leave the todo list with whoever picks up the task and they will know where to pick up from. The new pair should still check that the tasks you've listed make progress towards the acceptance test. In true XP style the hand-over is a conversation between the old pair and the new pair explaining what they were doing and why.

None of that of course precludes one person from the old pair staying with the task - indeed it's much better if you only switch out one person from the task at a time, but the hand-over and acceptance tests are still beneficial just as a sanity check to make sure you're on track.

So acceptance tests do more than just tell you when you're done, they also tell you where you're going, where you're up to and what you should do next. We need to get more disciplined and write acceptance tests up front so that we can use them as our roadmap while we work. Get back to the acceptance driven development we had going when we first starting with XP.

Testing Your Setup Code

May 8th, 2006

In order to write atomic tests for classes I've gotten into the habit of injecting dependencies instead of creating them inside the class. This makes it simple to mock the dependencies but means that those dependencies are now externally visible instead of being neatly encapsulated and it means that somewhere in your code, there has to be a place that actually creates all these instances and passes them in.

I have no idea how to test that bit of code.

This pops up in a couple of places I've been working on lately, firstly the main method of a program. How do you atomically test a main method that by definition has to setup all the different objects and initialize everything. I suppose I could use a factory pattern but it seems like overkill. How are people testing these things?

The other problem area is in creating dialogs. I can separate out all the business logic and atomically test that, I can even use JFCUnit to test the GUI code for accessibility etc, but at some point my business code has to create the dialog and show it - how do I test that? I'd really like to keep my business code with 100% code coverage to avoid the slippery slope of just saying "oh I can't test that" (which we've been sliding down a bit). I do need to make sure my atomic tests run really fast though.

Maybe I just have to live with no atomic tests for that bit of my code and leave the testing to integration tests but it opens up a whole in our TDD atomic test coverage which I'd like to avoid if I can.

Has anyone found a way to play with class loaders so that a call to new MyObject() actually creates a mock object/stub instead? Is that so ridiculously complex to do that you'd have no confidence in the resulting tests anyway?