PDA

Click to See Complete Forum and Search --> : TDD is such a burden - am I doing something wrong?


Cybis
Jun 2nd, 2008, 01:37 PM
I've tried TDD on two projects so far. These are relatively small projects I've done myself over a few weeks, just to practice TDD.

Anyway, TDD is supposed to make refactoring simpler because you can see right away if you broke anything. However, if I so much as add a parameter to a function - perhaps one or two dozen unit tests need to be changed, for a function that is used only in a few places. Without unit tests I could just make that change, fix the couple of spots in my code that use that function, manually test a little, and I'm done. With a unit test framework, I spend far more time writing and maintaining tests than I do on the code itself (unit tests also constitute well over half of the total code). I know that I'm supposed to somehow reduce redundancy in the unit test framework - trying to make them share the same setUp code for example - but each unit test requires a slightly different setup because they each test slightly different things. Also, trying to set up some way for unit tests to share code to the fullest extent possble somehow makes the test framework seem sloppy and overly complex (like when I use mock objects).

Is it that TDD is simply unsuitable for such small projects? Or is it only beneficial when working in a team (although these difficulties make it seem it would be harder with a team)? Is a good TDD book going to address these issues? (I haven't found anything through google about people having similar difficulties).

Hack
Jun 2nd, 2008, 01:40 PM
Moved to General Developer

alex_read
Jun 3rd, 2008, 06:12 AM
The idea of TDD is that you spot most of the bugs in your testing rather than in beta mode, that's why the concentration's so much on the unit and test harness tests.

Typically unit tests look at an individual method, and they can call one another, so I'm not too sure why when you change your method you have to edit so many tests - perhaps look at your design here.

Which leads to the next point really - the overall design of your project. Sit down (with your team, architect or on your own, whatever it may be as TDD is meant to cope with all sized projects if the time can be afforded) and design the overall solution in more detail - your classes first then down to the skeleton of the methods and parameters. Once you have this skeleton framework all put down you can then have a review on it, to see if there's anything missing. In this way you'll be spending a little longer getting it out the door, but less time altering the design at all, or bugfixing when the customer has a play.

You'll be coding as though you were writing the .Net framework - mainly adding new method features as the design's been thought out well, rather than altering existing methods and their parameters.

Now if I could only follow my advice....:p :cool:

Cybis
Jun 3rd, 2008, 04:22 PM
Thanks for the input.

The main reason I need lots of tests for each function is because many of the functions I'm testing are relatively complex algorithms with lots of boundary conditions (typical hobby project for me might be, say, a regex engine, which requires extensively testing string parsing code and making sure several data structures are properly built up). Perhaps instead of working directly with the classes being tested, each test could go through some sort of adapter class to help reduce coupling. I did sorta try that on my first TDD project, but it became a little messy. Maybe I just need more practice.

I'm a little surprised at the process you've outlined. Are you suggesting building up sort of a skeleton - classes and method stubs - to be filled in later? And that I won't need to change the design much after I already have this skeleton in place? That sounds a little waterfall-ish to me. I certainly understand the need for some upfront design (which actually goes against pure TDD, oddly enough), but agile development in general seems to focus on using frequent refactoring to evolve an elegant design, rather than expecting an elegant design up front which, in my experience, is rarely achieved.

alex_read
Jun 4th, 2008, 01:02 AM
Ok I guess I kind of went off on one there :p sorry, let me try to explain myself.

#1, From what I've seen in mags and on the net and have used myself, unit tests have usually comprised of not really more than 1 class of unit tests to test the coding methods of 1 class in most cases.

When I write mine I have a single unit test method for a single code method - I might fire off and output a hundred different values at that method, checking null arguments being passed in and a range of different correct values to see the output. I'm not saying this is 100% the proper way to do unit tests, but on the most part, it makes the unit test classes more maintainable and easier for others to pickup (using collapse-expand options I can just go straight to the test of the method I'm looking at and concentrate on just that). I then write test harness, short exe programs to test the methods in unison usually, to see how they work together to produce a result. I'm not sure on the TDD and recoupling, perhaps I have a bit more to read on it then, but the above seems to work for me.

#2 was a general comment - I was trying to look at your issue and suggest the planning to help you, this I guess was more a personal opinion and I was looking at your problem from more a general programming aspect rather than TDD one there :) :rolleyes: however I still think it's of relevance. TDD is a methodology, and whilst good initial design and documentation go somewhat against TDD, they are usually put in to some extent, and I still personally believe there's no real substitute for those 2 - it would certainly help in your situation here to map out the methods if you are finding you have to rewrite a ton of unit tests.

#3 which it looks like I didn't mention before - in typical TDD, the amount of time spent writing the code against the amount of time writing the tests should roughly be on par / be a 1:1 ratio to give you some idea.