Can we come up with a better name for TDD? - tdd

I keep hearing how Test Driven Development is an unfortunate name for the technique because TDD is not about Testing, it's about design.
Personally, I've never had a problem with the name simply because I've always thought about it more as a way to program to a specification. I've never had a problem with the fact that the code that is verifying that I've met the spec has the word 'test' in a class name, method name, annotation, or attribute. It's a convention I've followed in order to have test frameworks do the heavy lifting for me.
I'm not the most dogmatic about my approach, although I do try to write my tests first, I often find myself inspired to write some extra code which I then try to wrap in tests. I do tend to find that TDD outsmarts me from an API-design perspective every time I do that though (and I inevitably end up refactoring my non-tested code as soon as I start writing tests around it), but the point is I'm okay with not writing all tests up-front as long as I end up with a test harness around everything of interest when I'm done.
So, back to the question. What would be a better name for TDD? Would a name that didn't involve the word 'test' make a difference?

Test driven development is not a way of testing, it's a way of developing (including design, coding and testing). Otherwise it would be called development driven testing.
The verb of the phrase "test driven development" is development, "test-driven" is just the adverb. You should explain that to whoever is giving you grief over the term.
I have absolutely no problem with the name since it accurately reflects the intent. And you don't have to have all your tests finished before starting development but you should have them specified at least.

I think that's what Behavior-Driven Development tried to achieve (among other things).
I've stopped caring about definitive names -- it's all open to interpretation.

In my (subjective) opinion, I believe that the reason some people started the campaign against the word 'Test' in Test-Driven Development was because of bad experience with explaining the concept to certain types of developers.
There are developers who, as soon as they hear the word 'Test', stop listening - they think it's not their job, so why should they care? That attitude is obviously detrimental if you need people to adopt the practice of TDD. If one solution to that problem is to rename TDD into something that does not include the word 'Test', then fine by me, but for the rest of us, let's just continue to call it TDD.
I've seen at least the following terms suggested:
Test-Driven Development (the original term)
Test-Driven Design (because it's more about design)
Example-Driven Design (because tests could be viewed as examples of how the code is supposed to work)
Design-by-Example (just another phrase for EDD)
Behavior-Driven Design (the declared intent was different, but most attempts so far has looked a lot like TDD with some extra verbosity added)
Even though 'Design' is very important to me, I still think the tests provide value. Sure, they are not QA tests, but the entire mass of tests as a by-product of TDD still provide the safety net that allow you to refactor with confidence. In fact, Refactoring has an entire section on unit testing, because Fowler viewed it to be very dangerous to attempt refactoring without a regression test suite.
Anyone really, truly believing that the tests are of no importance in TDD should put their money where their mouth is and delete the unit tests when their code is done.
For me, TDD makes sense. Yes, it is first and foremost about Development and Design, but the Tests are important artifacts too.

I think Test Driven Development is fine. That's what it is. Yes, it affects the design. Yes, it improves the quality. Yes, it improves the overall maintainability and ability to refactor. Yes it's faster. Etc.
I think of BDD as a different, more specific practice. But maybe it's more in line with the original intent of TDD than tools like JUnit promoted.
Is it a bad name because it speaks more towards the process than the benefits? Maybe.
Other ideas:
responsible develoment
test first development
holistic develompent
not hacking

I think "Code-By-Example" is the best name for what we do. I think that's what Dan North calls it. Code By Example is then a part of BDD (so BDD is larger/more specific that TDD).
The concept of "Context Specifications" is also quite similar, promoted by people like Scott Bellware.
I agree that using the word "test" makes it difficult to communicate the technique to new developers.

Related

Does BDD replace or augment TDD?

Does BDD replace TDD, or are both used together? I've been reading that BDD should only test for things that the user can see. If that is the case, does that mean one would need to use TDD for service methods that the user wouldn't see?
BDD is a replacement for both TDD and ATDD (and derived from them).
The first ever tool for BDD, JBehave, actually started as a replacement for the unit-testing framework JUnit. The intention was that it would allow you to describe the behaviour of your (not-yet-written) system and provide examples, without using the word "test", since really at that stage it's analysis, not testing. That word, "test", was causing all kinds of confusion!
The difference is that example and behaviour and specification are all problem-space language, whereas the word test is solution-space. It tends to make people think they understand the problem, and are testing a solution, which is a problem, if they really don't!
It turns out that avoiding the word test helps people to explore the problem more fully. You can read about this in Dan North's original article.
While Dan was exploring BDD in 2003/4, he explained it to Chris Matts, who was working at the time as a Business Analyst. Chris said, "But that's just like analysis!" And so they started exploring how Chris did analysis on whole systems, and how examples of that worked, and Chris realised that it wasn't just about behaviour and outcomes, it was about behaviour and outcomes in a context. That formed the whole "Given, When, Then" syntax that we now know today (it wasn't called Gherkin back then because Cucumber didn't exist).
So Dan started writing a scenario-running framework on top of the unit-"testing" tool, and then ported it to Ruby as RBehave, which then got turned into plain text and became Cucumber. At that point, BDD became a replacement for ATDD (which was normally done back then with incredibly procedural scripts using unit-testing tools).
It doesn't really matter whether you're using JUnit, NUnit, or any other kind of unit-testing framework at a low-level. If you're thinking in terms of examples of behaviour, and talking through those examples, then you're doing BDD. Writing the examples down is useful, and automating them is useful too, and that's why there are BDD tools like JBehave and Cucumber which work at a system level.
We don't really need specific BDD tools at a lower level, because it's pretty easy for developers and testers to map "test" to "example" or "should" without worrying about it.
The difference is in the ease with which people can have conversations, without using the word "test".
When you're writing BDD for a class, the "user" of that class is usually another class. So, in the same way you write scenarios based on what the user of a system can see, you write lower-level examples based on what another class can see. The tests that come out of BDD are a very nice by-product, but the conversation is the most important aspect, even if that conversation has to happen with a rubber duck.
BDD doesn’t replace TDD, I would argue that it complements BDD.
It all depends on the question, will the business care about this or not?
You want to use the right tool for the job. That is, some stuff fits very well for BDD and some other things fit better with TDD. When done properly, the line between BDD and TDD is very blurred. If it even exists.
I wrote a blog post where I discuss a concept called “Testing Iceberg”, http://www.thinkcode.se/blog/2016/07/25/the-right-tool-for-the-job
It may share some additional light to your question.
And I agree with #Lunivore that the choice of tool is less important compared with the understanding of the problem that you get from conversations.

Does TDD preclude designing first?

I've been reading about TDD lately, and it is advocated because it supposedly results in code that is more testable and less coupled (and a bunch of other reasons).
I haven't been able to find much in the way of practical examples, except for a Roman numeral conversion and a number-to-English converter.
Observing these two examples, I observed the typical red-green-refactor cycles typical of TDD, as well as the application of the rules of TDD. However, this seemed like a big waste of time when normally I would observe a pattern and implement it in code, and then write tests for it after. Or possibly write a stub for the code, write the unit tests, and then write the implementation - which might arguably be TDD - but not this continuous case-by-case refactoring.
TDD appears to incite developers to jump right into the code and build their implementation inductively rather than designing a proper architecture. My opinion so far is that the benefits of TDD can be achieved by a proper architectural design, although admittedly not everyone can do this reasonably well.
So here I have two questions:
Am I right in understanding that using TDD pretty much doesn't allow you to design first (see the rules of TDD)?
Is there anything that TDD gives you that you can't get from doing proper design before you start coding?
well, I was in your shoes some time ago and had the same questions. Since then I have done quite some reading about TDD and decided to mess with it a little.
I can summarize my experience about TDD in these points:
TDD is unit testing done right, ATDD/BDD is TDD done right.
Whether you design beforehand or not is totally up to you. Just make sure you don't do BDUF. Believe me you will end up changing most of it midways because you can never fully understand the requirements until your hands get dirty.
OTOH, you can do enough design to get you started. Class diagrams, sequence diagrams, domain models, actors and collaborators are perfectly fine as long as you don't get hung up in the design phase trying to figure everything out.
Some people don't do any design at all. They just let the code talk and concentrate on refactoring.
IMHO, balance your approach. Do some design till you get the hang of it then start testing. When you reach a dead end then go back to the white board.
One more thing, some things can't be solved by TDD like figuring out an algorithm. This is a very interesting post that shows that some things just need to be designed first.
Unit testing is hard when you have the code already. TDD forces you to think from your API users perspective. This way you can early on decide if the public interface from your API is usable or not. If you decide to do unit testing after implementing everything you will find it tedious and most probably it will be only for some cases and I know some people who will right only passing test cases just to get the feature done. I mean who wants to break his own code after all that work?
TDD breaks this mentality. Tests are first class citizens. You aren't allowed to skip tests. You aren't allowed to postpone some tests till the next release because we don't have enough time.
Finally to answer your question if there anything that TDD gives you that you can't get from doing proper design before you start coding, I would say commitment.
As long as your doing TDD you are committed to apply good OO principles, so that your code is testable.
To answer your questions:
"Test Driven Development" (TDD) is often referred to as "Test Driven Design", in that this practice will result in a good design of the code. When you have written a failing unit test, you are forced into a test driven design approach, so that you can implement just what is needed to make the test pass i.e. you have to consider the design of the code you are writing to make the test pass.
When using a TDD approach a developer will implement the minimum amount of code required to pass the test. Doing proper design beforehand usually results in waste if the requirements change once the project has started.
You say "TDD appears to incite developers to jump right into the code and build their implementation inductively rather than designing a proper architecture" - If you are following an Agile approach to your software development, then you do still need to do some up front architectural investigation (e.g. if you were using the Scrum methodology you would create a development "Spike" at the start of a project) to ascertain what the minimum amount of architecture needed to start the project. At this stage you make decisions based on what you know now e.g. if you had to work with a small dataset you'd choose to use a regular DB, if you have a huge DB you might to choose to use a NoSQL big data DB etc.
However, once you have a general idea of the architecture, you should let the design evolve as the project progresses leaving further architectural decisions as late in the process as possible; Invariably as a project progresses the architecture and requirements will change.
Further more this rather popular post on SO will give you even more reasons why TDD is definetly worth the effort.

Test-Driven Development "Barriers to Entry"?

I'm in the process of doing a study on Test-Driven Development and one of the discussion points is the "Barrier to Entry" associated with TDD. Does anyone have any experience around this area, on any projects you've worked on that decided not to use TDD because the barrier to entry was too high?
From what I can tell the only barrier to entry is knowledge (and as such experience) of individual developers, with most not being entirely accustomed to the process and it being slightly alien. Financially it seems to be very appealing given most of the market leading tools are open source, freely available, well documented and well supported.
Thoughts/feelings appreciated.
Thanks,
EDIT - does anyone know of any high profile quotes of people advocating TDD? Would love to see how high it goes up the chain. Cheers.
Some barriers include:
An existing code base which doesn't lend itself to unit testing.
A problem domain that is hard to unit test meaningfully, such as GUI work or integrations with third party systems.
A perception of integration problems over unit problems (in other words, if it doesn't work end to end it doesn't do anything, so what is the point of testing the unit).
A mindset that wants to design ahead of time and have a clear system design rather than have tests drive design
A political culture where design is done by a different person/group than development, and that design is not unit-test friendly.
An inability to get over the fact that TDD is not about testing for conformance (arguments like "the one who writes the tests shouldn't be the one who codes it, they will be too lenient on themselves" and such variants).
It isn't they way they have coded until now, so the shift is harder.
Sometimes a certain test can be hard to set up, so the method will get abandoned because it "feels" slower.
Design requirements that don't lend themselves to evolving design well or at all (think Nuclear Plant control software or other systems were actual lives depend on their functioning correctly).
If everyone isn't running the test before checking in code, tests start to break often for wrong reasons (that is the intended behavior of the code changed, but the test didn't keep up, so the test is wrong, not the code) so they can be perceived as a drag.
In terms of barriers to entry, effectively, because you are explicitly writing tests that must pass before code is considered to be complete, the lead time in the dev cycle involved in getting functional code is longer. Now, when using TDD, you're effectively guaranteeing a certain level of quality on the code (whatever level of quality you choose to test against) and so that is generally more than enough compensation for the lag in lead time, but strictly speaking, there IS a greater lead time to getting functional code using TDD.
Effectively, if you have coders that write bug-free code, TDD will be a drag on your development cycle. The value of TDD, of course, is that there aren't any coders who can always write bug-free code, and so the cost of fixing bugs has to be factored in somewhere; in TDD, the cost of the test infrastructure is front-loaded.
Note that this is not in any way a negative thing about TDD; I'm just saying, that front-loading COULD be considered to be a "barrier to entry". Personally, as a coder, I would say that the Return on Investment is more than worth the effort, and I think most experienced dev managers would as well.
Team and/or management buy-in is the biggest obstacle in some companies. If you're the lone developer trying to use TDD and you can't get others on the project interested, it can be very frustrating.
Of course that's not a financial barrier at all. The biggest perceived financial barrier is probably time. If you have a large code base that you need to write unit tests for, it can seem quite daunting. Your manager (or someone above them) will question why you want to spend time writing code that will not add features/functionality to the code. Many people don't realize that writing the tests up front (as you do in TDD) can actually save you time, both immediately and in the long run when you're maintaining that code.
I think one major barrier is how it requires you to change the way you think.
Before I tried TDD, I would create a class, say Employee, then I would stub in things like FirstName, LastName, Email, etc. Then I would write some logic and forget that I missed a few fields or something else. And before I knew it I had a pretty complex class without knowing if those fields were ever necessary.
Also, it's a complete change from how we are used to writing software. We are used to writing software as we receive features from the guys who sign our checks. We are not used to writing code which doesn't compile, making it compile, then making it work to make our tests pass.
The first time you do this, you feel a bit.. well silly and stupid. Why am I making my code intentionally fail? It seems illogical to the "make it work" philosophy we've all been taught for so long.
A few reasons why it has failed so far where I work:
Most of the project at work on are older apps. Not pre-.NET but, .NET 2.0 and in some cases .NET 1.0.
Some of these projects are not well factored, either because the technology wasn't there in 1.0, or it was built quickly because they needed something NOW..
As Jon pointed out, some things are still a PIA (pain-in-the-***) to unit test, UI, database, etc.
Expensive tools. If you are only allowed to Microsoft tools, it's a high price tag to do this the "right way". We use resharper, so it really isn't a problem.
Time. I'm in a team of three guys supporting a department of 30 people. We are considered overhead, and many of our development consists of interfacing systems together
Yes the main barrier to entry is in your head or in the head of other programmers.
In the beginning you don't know what to srite in your tests.
The trick is to think about how your code will be used instead of focusing on how you re going to write it. Easier said than done ...
When you start to "get it", it's a bit hard to know where to stop writing tests.
You have to remember that tests prove nothing so you just can't write tests to covers all cases, you have to select the most useful ones ... and that's already a lot !
I've certainly seen plenty of resistance. The barriers I've encountered are:
Unit testing user interfaces (web or thick client) is tricky. I know there are lots of attempts to solve the problem, but I don't think any of them have made it really simple - because it's a naturally hard problem.
At the other end, although there are various ways of making it easier to test the code involved with the database, it's still tricky and time-consuming.
While good tests definitely speed up development overall, testing is a skill - and while you suck at it, unit testing may well be more trouble than it's worth, which means you never build up the skill...
Managers often see it as an optional extra to development - a nice to have rather than critical. This means it's the first thing to go when the project inevitably has a resource squeeze.
I wrote a long-ish article about this a few weeks back, "Why I write tests first".
I think the biggest barrier is building the discipline to start with tests first, but I don't believe the TDD (or any practice for that matter) should be approached as an always, absolutely, 100% of the time solution.
TDD is a tool in each developer's arsenal. I tend to think it works well for me most of the time. A developer that isn't as accustomed to writing tests (first or otherwise) may it difficult to get anything done if TDD is forced on them because they can't think in terms of writing the test first.
I consider myself an experienced test-writer, but I can't always think in terms of tests. Some problems don't lend themselves well to it, or at least my head doesn't get wrapped around it some days. And some types of code (such as UI and client-side code) doesn't lend itself well to always writing tests.
If you have a team of developers that do not write tests as a matter of habit, I'd push that first. I have no problem requiring that all new code have accompanying unit tests where possible/practical. Once testing is a discipline, converting developers to TDD individually or as a team is much easier.
One non-obvious barrier (non-obvious to me, at least) is the build infrastructure. If developers don't have control over the build process, or if the infrastructure is too baroque to be manageable, then integrating tests into the build process is going to be shunted to the side in the name of "efficiency". (Of course, in these situations it's the build infrastructure that should be shunted aside in the name of efficiency.)

Should I start using TDD on a project that doesn't use it already

I have a project that I have been working on for a while, just one of those little pet projects that I would like to one day release to open source.
Now I started the project about 12 months ago but I was only working on it lightly, I have just started to concentrate a lot more of my time on it(almost every night).
Because it is a framework like application I sometimes struggle with a sense of direction due to the fact I don't have anything driving my design decisions and I sometimes end up making features that are hard to use or even find. I have been reading about how to do TDD and thought maybe this will help me with some of the problems that I am having.
So the question is do you think it's a good idea to start using TDD on a project that doesn't already use it.
EDIT: I have just added a bit to clarify what I mean by struggle with a "sense of direction", it properly wasn't the best thing to say without clarification.
In my opinion, it's never too late to adopt a better practice - or to drop a worse one - so I'd say "Yes, you should start".
However ... (there's always a "but") ...
... one of the biggest gains of TDD is that it impacts on your design, encouraging you to keep reponsibilties separate, interactions clean and so on.
At this point in your project, you may find it difficult to get tests written for some aspects of your framework. Don't give up though, even if you can't test some areas, your quality will be the better for the areas you can test, and your skills will improve for the experience.
Yes.
Basically, you can't do any harm by adding TDD for any new code you write, and any changes you make to existing code. Obviously it would be tricky to go back and retro-fit accurate tests to existing code, but it certainly couldn't hurt to cover the primary use-cases.
Maybe consider having a look at Brownfield Application Development in .NET? It is full of pragmatic and practical advice for exactly this scenario (one of the definitions offered for "Brownfield" is "without proper unit tests").
Yes, absolutely a good idea to start doing TDD.
You will pay a start-up cost for at least two reasons:
Learning a new skill TDD/unit testing.
Retrofitting your code to be testable.
You'll need to do some of both, but as you work if you find yourself struggling think of which of those two is the source of the effort.
But the end result is worth it. From what you describe this is a project you intend to live with for quite a while. Remember that when you lose an hour here or there. In a year you'll be very happy that you made this investment both in your skill set and the code base.
At worse, you can just do TDD on new stuff, while you slowly create tests for your existing code base.
Yes, it's never too late to start using TDD. I have introduced TDD to a commercial project that was already running for five years when I joined, and it was definitely a good decision.
While you are new to the technique, you should probably concentrate on using it for the code that you are writing from a clean slate - new classes, new methods etc. Once you got a hang on it, start writing tests for code that you change.
For some of the code, the latter might prove to be difficult, because the code you have written until now is unlikely to be written with testability in mind. There are some techniques to deal with that, but it's probably too early to care about them.
If you are missing a sense of direction, though, I doubt that TDD will help you a lot. You might want to look into Acceptance Testing instead, which is at least as important as unit testing, and will help you focus on the functionality of the system instead of single units of code. The TDD book by Lasse Koskela is a good introduction to both techniques.
Another technique that might help you is the Extreme Programming planning game, where you put pieces of functionality on index cards and prioritize them. I typically notice that getting ideas out of my head and in prioritized order helps me a lot in understanding where I want to go next.
As others have said, TDD shouldn't hurt a project in progress, but think carefully if you're tempted to do large-scale refactoring just to allow testing. Make sure the benefits justify the cost.
I'm a little concerned that you "struggle with a sense of direction." I don't know that TDD will help you there. I find it's a great help for low-level design decisions, but not so great for architecture decisions. Adding TDD to a directionless project sounds a bit like having a baby to save a marriage - unwise. Hopefully I misread your intention.
Yes.
TDD makes it easier for other people to understand the code, as well as it gives the application a better design over time
In theory you were supposed to test first, but you didn't. In this scenario, contrary to others opinion, I wouldn't start with new features.
Take advantage of the 80:20 rule, run a profiler, and put the test cases to the most frequently called piece of code.
Put tests around the house jewel, gut, most-important code.
Put tests around the annoying, always-breaking, recurrent déjà vu buggy code.
Put tests around all bugs you come across before fixing the bug for failing test.
Warning: Putting test cases will require refactoring, which means you must fix something that's not breaking.
If you still love unit tests at this point, you'd be Red, Green, Refactoring on your own.
Absolutely.
Introduce TDD to new code and if time allows, introduce "Comment Driven Design" with your existing code if it's not already tested.
Comment out the block of existing code you need to test
Write your test
Uncomment your original code one statement at a time (if you have an if block, uncomment the entire block)
Determine if your original code ultimately passes your test and if not, re-write to pass your tests accordingly
Writing tests for existing, working code that you don't plan to change doesn't fit with the thrust of TDD, which is to write tests that teach you about the system you're building.
My approach to bringing in TDD mid-stream has been to:
write tests for all new features, and
when changing a piece of code, write a test that covers the existing functionality (to make sure I understand it), then change the test before changing the code.
It can also be beneficial to write tests for code related to code you're changing - e.g., if you're altering a parent class, you may want to build tests around child classes first to protect yourself from potential damage.
Yes, you should. I'm currently working on a project that until recently wasn't covered with unit tests, but we decided that we should start testing our code, so we started writing them now. Unfortunately, I'm the only developer that practices TDD, others just write tests after writing their code.
Still, I found that practicing TDD helps me write better code, and I write it faster than before. Now that I learned how to do TDD, I just don't want to go back to writing code the way I used to.

What are some common misunderstandings about TDD?

Reading over the responses to this question Disadvantages of Test Driven Development? I got the impression there is alot of misunderstanding on what TDD is and how it should be conducted. It may prove useful to address these issues here.
I feel the accepted answer was one of the weakest (Disadvantages of Test Driven Development?), and the most up-modded answer smells of someone who might be writing over specified tests.
Big time investment: for the simple
case you lose about 20% of the actual
implementation, but for complicated
cases you lose much more.
TDD is an investment. I've found that once I was fully into TDD, the time I lost is very very little, and what time I did lose was more than made up when it came to maintence time.
For complex cases your test cases are
harder to calculate, I'd suggest in
cases like that to try and use
automatic reference code that will run
in parallel in the debug version /
test run, instead of the unit test of
simplest cases.
If your test are becoming very complex, it might be time to review your design. TDD should lead you down the path smaller, less complex units of code working together
Sometimes you the design is not clear at the start and evolves as you go along - this will force you to redo your test which will generate a big time lose. I would suggest postponing unit tests in this case until you have some grasp of the design in mind.
This is the worst point of them all! TDD should really be "Test Driven Design". TDD is about design, not testing. To fully realise the value of benefits of TDD, you have toy drive your design from your tests. So you should be redoing your production code to make your tests pass, not the other way round as this point suggests
Now the currently most upmodded: Disadvantages of Test Driven Development?
When you get to the point where you have a large number of tests, changing the system might require re-writing some or all of your tests, depending on which ones got invalidated by the changes. This could turn a relatively quick modification into a very time-consuming one.
Like the accepted answers first point, this seems like over specification in the tests and a general lack of understanding of the TDD process. When making changes, start from your test. Change the test for what the new code should do, and make the change. If that change breaks other tests, then your tests are doing what their supposed to do, failing. Unit Tests, for me, are designed to fail, hence why the RED stage is first, and should never be missed.
IMHO The biggest misconception about TDD is that: time spent writing and refactoring tests would be time lost. The thinking goes like "yeah, a test suite is nice, but the feature would be complete much faster if we just coded it".
When done properly, time spend writing and maintaining tests is saved multiple times over the life of the project in time not spent debugging and fixing regressions. Since the testing cost is up-front and the payoff is over time, it is easy to overlook.
Other big misconceptions include ignoring the impact of TDD on the design process, and not realizing that "painful tests" is a serious code smell that needs fixing quickly.
I see a lot of people misunderstanding what tests actually are usefull to TDD. People write big acceptance tests instead of small unit tests and then spend far too much time maintaining their tests and then conclude that TDD doesn't work. I think the BDD people have a point in avoiding the use of the word test entirely.
The other extreme is that people stop doing acceptance testing and think that because they do unit testing their code is tested. This is again a misunderstanding of the function of a unit test. You still need acceptance tests of some sort.
The misconception that I often see is that TDD ensures good results.
Often times tests are written off of flawed requirements, and therefore, the developers produce a product that does not do what the user is expecting. Key to TDD is, in my opinion, working with the users to define requirements while helping manage their expectations.
These are the issues that in my opinion are quite controversial and hence prone to misunderstanding:
In my experience the biggest advantage is producing far better code at the cost of a lot of time spent writing tests. So it's really worthwhile for projects that require high quality, but on some other, less quality centric sites, the extra time will not be worth the effort.
People seem to think that only a major subset of the features must be tested, but that is actually wrong IMHO. You need to test everything in order for your test to be valid after refactoring.
The big drawback of TDD is the false sense of security given by incomplete tests: I've seen sites go down because people assumed that Unit Testing was enough to trigger a deployment.
There is no need of mocking frameworks to do TDD. It's just a tool for testing some cases in an easier way. The best unit tests though are fired high in the stack and should be agnostic on the layers in the code. Testing one layer at a time is meaningless in this context.
Just chucking another answer in the pot.
One of the most common misunderstandings is that your code is fixed, ie. I have this code, now how on earth will I test it? If it's hard to write a test, we should ask the question: how can I change this code to make it easier to test?
Why..?
Well The sort of code that's easy to test is:
Modular - each method does one thing.
Parameterised - each method accepts everything it needs and outputs everything it should.
Well Specified - each method does exactly what it should, no more, no less.
If we write code like this, testing is a doddle. The interesting thing is that code that is easy to test is, coincidentally, better code.
Better as in easier to read, easier to test, easier to understand, easier to debug. This is why TDD is often described as a design exercise.

Resources