I basically have the gist of TDD. I'm sold that it's useful and I've got a reasonable command of the MSTEST framework. However, to date I have not been able to graduate to using it as a primary development method. Mostly, I use it as a surrogate for writing console apps as test drivers (my traditional approach).

The most useful thing about it for me is the way it absorbs the role of regression testing.

I have not yet built anything yet that specifically isolates various testable behaviors, which is another big part of the picture I know.

So this question is to ask for pointers on what the first test(s) I might write for the following development task: I want to produce code that encapsulates task execution in the fashion of producer/consumer.

I stopped and decided to write this question after I wrote this code (wondering if I could actually use TDD for real this time)

1 Answer
1

Starting with this concept:
1) Start with the behavior that you desire. Write a test for it. See test fail.
2) Write enough code to get the test to pass. See all tests pass.
3) Look for redundant / sloppy code -> refactor. See tests still pass. Goto 1

So on #1, let's say that you want to create a new command (I'm stretching to how the command would work, so bear with me). (Also, I'll be a bit pragmatic rather than extreme TDD)

The new command is called MakeMyLunch, so you first create a test to instantiate it and get the command name:

This fails, forcing you to create the new command class and have it return its name (purist would say this is two rounds of TDD, not 1). So you create the class and have it implement the ICommand interface, including returning the command name. Running all tests now shows all pass, so you proceed to look for refactoring opportunities. Probably none.

So next you want it to implement execute. So you have to ask: how do I know that "MakeMyLunch" successfully "made my lunch". What changes in the system because of this operation? Can I test for this?

Other times, this is more difficult, and what you really want to do is test the responsibilities of the subject-under-test (MakeMyLunchCommand). Perhaps the responsibility of MakeMyLunchCommand is to interact with Fridge and Microwave. So to test it you can use a mock Fridge and mock Microwave. [two sample mock frameworks are Mockito and nMock or look here.]

The purist says test the responsibility of your class - its interactions with other classes (did the command open the fridge and turn on the microwave?).

The pragmatist says test for a group of classes and test for the outcome (is your lunch ready?).

Find the right balance that works for your system.

(Note: consider that perhaps you arrived at your interface structure too early. Perhaps you can let this evolve as you write your unit tests and implementations, and in step #3 you "notice" the common interface opportunity).

if i hadn't pre written my interface, what question would have led to the creation of the Execute() method - some of my initial attempts to TDD stalled when I didn't have a "step" to stimulate additional functionality - i get the feeling theres a latent chicken/egg issue that has to be sidestepped
–
Aaron AnodideApr 11 '12 at 22:11

1

Good question! If the only command that you made was "MakeMyLunchCommand" the method may have started with ".makeMyLunch()". Which would have been fine. Then you make another command ("NapCommand.takeNap()"). Still no issue with different methods. Then you start to use it in your ecosystem, which is likely where you are forced to generalize into the ICommand interface. In general, you often delay generalization until the last responsible moment, because YAGNI [en.wikipedia.org/wiki/You_ain't_gonna_need_it ] =) Other times, you know you are going to get there so you start with it.
–
jayraynetApr 11 '12 at 22:15

(Also of assumption here is that you are using a modern IDE that makes refactoring things like method names trivial)
–
jayraynetApr 11 '12 at 22:19

1

thanks again for the advice, it's kind of a milestone for me to finally see all the pieces and how they fit - and yes, quick refactor is in my toolbox
–
Aaron AnodideApr 11 '12 at 22:24