Making TDD easier


Chris Garty asks what tools are availble to help Test-First development.  He says:


it would be great if my development tool could automatically create empty implementations of the classes and methods I am testing though simple ‘right-click to implement unknown class/method/property’ functionality.


This is something we’ve thought about before for Visual Studio.  I’m going to describe our assessment of this kind of feature, and I want to hear if you think we’re on track or not.


1. Intellisense interferes with this style of coding.  Suppose you’re in this situation:


    class C


    {


        [TestFixture]


        class Tests


        {


 


            [Test] void ATest()


            {


                C c = new C();


                c.  // about to write a method call here


            }


        }


    }


You’re writing an app to manipulate Everquest, so you want an EQ property on the class. You’re hoping to write c.EQ and want the tool to generate a stub for C.EQ for you.


But when you hit the DOT, a completion list pops up.  You ignore it and keep going.  When you hit space, semicolon, or whatever, the editor completes to c.Equals for you. This will get annoying pretty quickly.


The behavior I’ve described is wonderful when you misspell a member name, or just type the prefix & want the editor to finish up for you.  But in a pure unit-test-first scenario, it’s not what you want at all.  (By “pure” I mean you write the call before you write the method). 


If you do this a lot, you could go to Tools.Options.TextEditor.C# and turn off Auto List Members, but I’d hate to give up that feature in other cases.


I find myself writing method stubs first.  Then I get to use Parameter Help when I write the call.


I suspect you’re in the habit of hitting ESC when the completion list appears & you’re typing a new name.


2. This is most important for methods. 


Methods have signatures, so there’s more opportunity for a tool to help you out.


Generating a property in this way isn’t a very big win.  Especially when:


a)      The prop and propg expansions are available to insert one quickly


b)      A public readonly field has the semantics I’m usually looking for, in 1/6th as much code.


c)      The Encapsulate Field Refactoring is available, too.


d)      Property signatures are so simple.


Generating a class is even less valuable.  Classes have only a name.  You don’t generate classes nearly as often as you generate methods.  We also don’t have good ways to guess where the class should live.


3. Even though getting the signature 100% right isn’t always possible, the feature is still nice to have.


Just generating with the correct number of parameters, all of type object, and named p1, p2, p3, … is the most important.  Discerning the parameter types, return type, and names is gravy.



4. This is a productivity feature. 


It helps you go faster, but it doesn’t help you do things you couldn’t do before.  Compare to, say, Reorder Method Parameters Refactoring, which you probably wouldn’t do without a tool, since fixing every reference is so tedious.


Does that sound about right?


 


We definitely want to support folks doing Refactoring & TDD, and this feature is part of that story. I’m sure this feature will make it into Visual Studio at some point, but I can say when.

Comments (11)

  1. Louis Zelus says:

    Eclipse has a nice feature thats worth looking at. You write a test, using the method as you want it someday to work. The IDE show’s an error because the method doesn’t exist. Right click gives an option to "correct it", one of the methods is to create a stub matching this interface on your class.

    The result: Much faster time to reb bar, meaning you write you test, it won’t compile, right click, add stub and the test compiles (and fails). Then when you’re trying to make it pass you can write the method content and fine tune the method signiture.

  2. Louis: yep, that’s the kind of thing we’re talking about.

  3. Thomas Eyde says:

    I want productivity, so give me all those features. Let the IDE create the class, you are providing refactoring tools so we can easily move it later, right?

    Why not let the IDE create methods like this:

    //test

    xmlDoc.LoadXml(xml);

    //new method created by IDE

    public void LoadXml(string xml) {…}

  4. Kirk Marple says:

    My ping didn’t seem to work from my blog entry, so i’ve linked it here. I’d be interested in your feedback on the feature suggestion. Thx!

  5. Chris Garty says:

    Excellent… you have already thought about it!

    By the way, my friend Marty Andrews tells me that the folks that make IntelliJ IDEA (JetBrains) commonly refer to this functionality as "Intention Actions" (See: http://www.sdtimes.com/cols/firstlook_072.htm)

    I’ll just run through your points briefly:

    1. Correct. I just hit ESC when intellisense isn’t wanted. IMO this is fine since I appreciate intellisense and would rather have it on all the time than off all the time.

    2. Correct. Methods are more important (i.e. higher priority)… but then the creation of a class or an interface would be easier (i.e. lower difficulty/time) wouldn’t it?

    3. Correct. A. Create method with parameters that allows test to compile. B. Create method with parameter types as specified in ‘unknown usage’. A is the low-hanging fruit and higher priority. B is the end goal.

    4. Correct. But I’d add that when you are doing TDD, you are more likely to use this ‘intention action’ ability than any single refactoring.

    I just found out that the Resharper plugin will be supporting this by mid-April. And judging by what that team did in building up IntelliJ IDEA for the Java IDE space… VS is in for some competition.

    http://www.jetbrains.net/confluence/display/ReSharper/Home

  6. Chris Garty says:

    Hey,

    I thought I’d come all the way back to this post and let you know that you got this spot on… the "Generate Method Stub" functionality works beautifully.

    It puts in the types nicely and the thing I love the most is that the default implementation includes an exception throw to remind those forgetful souls :).

    My team and I are using it constantly. It makes TDD much easier and in doing so eliminates another perceived barrier to entry.

    Great job! Keep up the good work!

    – Chris

  7. Chris Garty says:

    Oh… and keyboard shortcuts would just be icing on an already sweet cake 😉

    – Chris

Skip to main content