views:

558

answers:

11

Let me first come out of closet. I'm a TDD believer. I'm trying to practice Test Driven Development as much as I can.

Some developers at my work refuse to even try it. I myself started TDD by trying to prove to one of my peers that Test Driven Development is a bad idea. The arguments are:

  • Why? I was pretty successful developer so far.
  • It's going to slow me down.

What's the best pro TDD argument did hear or used?


See also: What is the best reason for unit testing?

+1  A: 

The arguments you listed are not rational, logical arguments. They have no reasoning behind them (unless you've actually just summarized much longer real arguments.)

As such, I don't think that you will be able to convince anyone who makes those claims with rational arguments of your own. The best way will be to appeal to the source of their arguments; experience. Either get them to use TDD for a while on a provisional basis to see what they think of it, or else do TDD work yourself that is clearly very good work, and present it as an example to them.

(I'm not a TDD believer. This is a practical way you could convince me that it was a good idea.)

mquander
+15  A: 

No amount of argument will convince anyone to use TDD.

You have to SHOW them, and demonstrate the benefits. It's easier to make someones 'light go on' by showing rather than telling.

Mitch Wheat
+1 to Mitch. This isn't an exercise in philosophy, it's software development. If you can't show the benefits, maybe they don't exist. And if you can, and your advice ignored, you may have bigger issues than convincing people to adopt TDD.
micahtan
While I'm not on the TDD boat, I totally agree about the value of personal example. Showing a stackoverflow thread comments and asking your team mates to switch to TDD based on that will get the OP a well deserved boot :)
Remus Rusanu
This must be true! becuase we dont use TDD and personally am still not convinced. I do still read threads to see if I can get some insight. We use code generation, a lot!, and find that spending the time maintaining that reduces a lot of future work and a lot of bugs, in in some casses, fixes a lot of bugs in one go. Not sure if its worth writing generated test code?
Mark Redman
A: 

As a professional developer for 10+ years, the best argument I can put forward is that even I found my bugs before I got to a point of actually being able to "run" the application.

I also found that the design of my code was more robust and easier to change, and it gave me greater confidence to refactor.

"Pretty successful" doesn't equal "Really successful".

The other great advantage is that I don't have to write test harnesses anymore as the Unit Test runners effectively become my test harness.

David McEwing
David, the reasons you've listed are definitely valid. However, these are advantages of unit testing, and not specific to TDD.
Igor Krivokon
Unit testing is different from a create a test before you write. While two out of three maybe unit testing the "DESIGN OF MY CODE" is not a result of Unit Testing but a more TDD approach of building the test before writing the code.
David McEwing
A: 

Show them this presentation. It sold me.

http://www.slideshare.net/sebastian_bergmann/testing-with-phpunit-and-selenium-156187

Any programmer who's ever been faced with a really complex task with a lot of edge conditions should be able to see the value of TDD. When it comes to something like making sure a search engine will match certain strings, TDD is the only way you'll be able to stay sane during maintenance -- the only way to be sure you've fixed one case without breaking a few others is with automated testing.

Frank Farmer
I agree that automated testing is very useful when designing complicated systems like that with output that you can evaluate objectively (sorry, I haven't watched your presentation, I hope I'm not missing context) -- but that's not really test-driven development, is it? That's just testing. Test-driven development would involve testing both those systems and all the simpler ones too.
mquander
I agree with mquander. In my experience I've been able to convince people who have never even seen unit tests before to adopt unit tests within a few days. However I've had no luck convincing them to switch to TDD. TDD is a total shift in how you approach coding. Also many programmers consider test code to be third class citizens. The idea of starting with tests? That's just too crazy :)
Praveen Angyan
+3  A: 

Different people will be convinced (or not) in different ways, so the only honest answer is "it depends".

One way I've seen work several times is to sit with someone after they've been struggling with a chunk of code, and recreate it using TDD. The resulting code is usually smaller and clearer.

Dave W. Smith
+3  A: 

I don't practice TDD. Although I see how it is good if you have complex projects in which you have many different test cases to test, I don't see a great benefit in using it in, say, a simple web application.

One way someone could convince me to use TDD would be if we took the same project and did them side by side, see who comes up with better results and who completes the task faster.

metanaito
+21  A: 

Perhaps they know better.

Unit testing by developers is an extremely useful practice and I cannot overemphasize its benefits, not only during initial development but also during refactoring when unit tests can catch early not only ordinary code defects but also the break of assumptions made by developers that were never captured in formal documentation and thus are likely lost by the time refactoring occurs.

That being said, TDD is no magic pixie dust:

  1. the 'just write enough code to pass the test' approach gives false positives. There are often known fallacies and problems that the 'just enough' approach fails to address. Quick examples that come to mind are distributed systems fallacies or NUMA performance problems. Just capturing those requirements into simply expressing those test cases for TDD would turn into a full time job in itself.
  2. the explosion of moqs goes out of control for any serious size project. mocks are code like any other code, they need to be maintained and just don't write themselves out of the blue.
  3. TDD is often used as an excuse to eliminate QA testing. 'our developer have already written tested id, lets ship it' neglects completely the end-to-end feature oriented testing QA should cover
  4. I don't trust the fox guarding the hen house. A wrong algorithm can still pass TDD with flying colors if the same mistakes are made in both the test and in the implementation.
  5. All methodologies in the end try to use process to substitute talent.

My main quarrel with TDD is that is presented as a magic solution to most development problems but its cost is kept under the table by its advocates. Doubling or tripling your code base with moqs does not come for free. I much rather see a few comprehensive unit tests written during development. The test-first TDD approach, I'm yet to see its benefits in a real size project.

I understand I'll be egg-ed to death now for posting this, but what the heck, who cares...

Remus Rusanu
Agreed. Silver bullets do not exist.
Loren Pechtel
Agreed. But writing a test first, forces you (the developer) to think about how your code/API/library/whatever will be consumed. You stop thinking about the internal details and start thinking about how it will be used. This oftens leads to cleaner interfaces and more useful code.
Mitch Wheat
True. You should absolutely write test for your component 'public gate' interface, and this way u eat ur own dogfood in the process, hopefully ending with an interface humans can actually use. Is TDD the only way to accomplish this? Will TDD adoption guarantee this result?
Remus Rusanu
If you include a mocking framework such as Moq or RhinoMocks you can keep all your mock objects under control. But don't confuse your mocks with your fakes or your mother objects.
David McEwing
I agree, especially on issues such as distributed and concurrent programming. To do certain tasks correctly requires proving that the code is correct, not testing that you get the expected results. You can't prove that code is thread-safe by running tests any more than you can prove that all sheep are white by going into fields and counting white sheep.
Kylotan
+2  A: 

Pair with them. You don't have to call it "pair programming" - that's scary to someone who's reluctant to even consider "radical" techniques like TDD - but if the two of you sit at a desk and work together on the same problem, it's easy to demonstrate the value of TDD. That can't be the end of the conversation, but it's one hell of a start. Gives you credibility for the rest of the conversation, and gives you something real as a basis for further discussion.

Carl Manaster
A: 

Thorough unit tests reduce bugs occurrences, but they also reduce recidivation or the scope of damage caused by recidivation.

plinth
+2  A: 

The "aha" moment for me was reading chapter 2 of "Test-Driven Development in Microsoft.Net" by James Newkirk. (Not that the rest of the book wasn't important...he dedicates several chapters to building a multi-tiered application in TDD).

He builds a simple stack, but you get to see the code "evolve" its complexity instead of starting out complex.

Even then, you will still have trouble convincing nay-sayers because it appears that TDD requires a lot more work than traditional programming. Most anti-TDD developers, however, forget to factor in the development time for unit tests at the end, at least in my experience.

SergioL
+9  A: 

TDD is a "pay me now or pay me later" tradeoff. If you only count the time from starting coding to checking in your code then TDD often does take longer, especially when first learning TDD. The payoff comes later during the testing phase, and also in future rounds of coding.

For the testing phase, I found that with TDD:

  1. I had substantially fewer bugs. My last TDD code I had bugs only due to requirements misunderstandings (or changes) or in the areas where I wasn't able to bring the code under test (PHP code in that case).
  2. The bugs I had were generally easier to reproduce under test, because I had already gotten the system under test.
  3. Fixing the bugs was faster, and with the tests I could have a greater belief that I didn't introduce new bugs.

The code itself had the following properties:

  1. As I started out thinking like a client of the code, the code tended to be easier to use. (This is one of the benefits of writing tests first).

  2. The code is easier to test.

  3. Writing unit tests is easier (and in many cases more fun) just before rather than after, so more tests are written.

  4. The code is easier to refactor and clean up. This was particularly true with Python, where automatic refactoring tools have a harder time.

Because of that, when it came time to revisit the code, it was easier to understand and easier to change, plus we had at least some regression tests already in place.

What this means is that the payback for TDD time may be months later. Furthermore, starting TDD with legacy code is particularly hard. Then there is time needed to both learn how to write good tests (a bad test set can either be insufficient or worse be brittle making it harder, not easier, to do refactorings) and how to get a complex system under test.

I have to admit I haven't been really able to get too many other people to switch to TDD. I think I switched largely because I wanted an easier way of testing and also I had the opportunity to learn how with a small code base and personal project.

Kathy Van Stone
I like the "four properties" you have mentioned. They are pretty much what I have seen .. especially the fact that the resulting code ended up being easier to use.
StudioEvoque
I've handled the legacy code aspect by writing test code that can also be linked in with the executable. The disadvantage is that you have to "assume" that the rest of the system is working correctly, and then you only use TDD for your "new code".
Richard Corden