I am a big fan of TDD -- and I agree with sfink's post. In particular,

I then discover that some fundamental piece of my design needs to be changed slightly. Theoretically, this should be no big deal since I have the test cases to allow me to change things drastically without worrying about breaking something subtle. In practice, that is true -- but I end up spending far too much time making the change, fixing things up so that all the old tests work, then making use of the change to implement the new tests.

Right on.

The refactoring and XP folks make a big distinction between refactoring (improving the design of existing code) and adding new functionality. And often it is claimed you can refactor safely because 'your tests protect you'. Agreed, but like sfink, I find refactoring requires you to recode (often nearly all) the tests as well.

This recoding is well worth it, of course. And TDD as a whole is very much worth it. But still, the tests -- necessarily so -- are very dependent on the specifics of the code tested.
I find my tests break and need rebuilding (not just fail, and require the module to be changed) when the module goes through large revision.

My current testing challenge is adding application or user tests -- so far I've been living the easier world of unit tests.... app tests (particularly in a web environment) take more effort. I'm plan is to continue using extensive unit testing to confirm each module behaves as it should, then confine my app tests to one or two simple basic run-thrus of the web app's main funtion. I've noticed when the apps break, it is no longer due to the objects (which are well tested), but to the thin (Mason) glue holding them together.
That said, I've not done much app test writing yet, and (unklike unit tests), can't seem to get into the rythm of writing app tests.