Test Driven Development - what's the point?

I’ve been thinking about Test Driven Design and I’m wondering if there is any real point to writing tests for myself? I am not part of a team so when I do write tests it seems that I already have a solution in mind so I end up writing tests that will pass using my preconception of what the end result will most likely be. It feels backwards and useless.

I imagine in a real-world development team someone would write the tests and others would code to pass it. That’s where it makes sense.

Is there any real purpose to writing tests for myself?

That is very good question. I am in the same position as you. I think it is a waist of time to write tests. I much prefer DDD. But would be interesting to see what others have to say about this.

If you are coding solo, it doesn’t matter that much although writing test cases first forces you to code to the project requirements effectively.

It’s a self-correcting problem, however. A project that small enough to be managed, coded, and tested by 1 or 2 people is probably not that hard to manage, doesn’t have that many requirements, etc.

So, in theory it’s an good approach to building software, but tiny projects don’t need that kind of methodology.

That’s exactly what I was thinking. Thanks for the validation.

I think it’s much bigger than that.

TDD is one of the new RAD / Extreme Programming style of methodologies. On the one hand, it grew out of some really smart programming practices.

Plan your project around your testing. If you program an entire application (whether you’re solo or part of a massive enterprise-class team), and then finding out in QA that it fundamentally doesn’t work… you just wasted a lot of time and money finding out you’ve been wasting your time. Every piece of code should be properly tested in as close to real world conditions as possible. You never assume something works, you TEST to prove it one way or another and build from there. That’s very smart. However, I feel TDD is highly misleading.

Your application is only as good as your tests. You write a TDD application… great. You wrote tests all the way through and then wrote code to accomplish those goals. Everything should be perfect right? Wrong. If you wrote your tests poorly, you’re screwed.

More importantly, the problem is not that a test itself is faulty. The problem is usually that you planned the wrong tests for your application. I’m always trying to think outside the box to figure out what I’ve missed in the application design and construction. That’s one reason a team is great, it gives you other people to bounce ideas off of. This is a common problem in any design and forces you to design a little, code a little, design a little more, code a little more, etc. TDD however does a couple things that, in my opinion, actually make application design much harder.

In TDD, however, you write low-level test after test which takes you so far down into the app that it’s hard to see the forest for the trees. Then, as the sheer mass of tests you’re running continues to grow and as they all continue to return “successful” results, it tends to lull you into a VERY FALSE sense of security. I think these are two key flaws in TDD that for my money have sent me in other directions.

Does that mean that TDD is bad. No. I just prefer to plan out my testing checkpoints as part of my system design. This also gives me a good place in the design phase to do risk analysis and work risk mitigation plans into the design plan too. I do not find writing tests before coding to provide any particular advantage whether you’re programming solo or as part of a big team.

Bad design will kill you whether you’re writing bad code or bad tests first.

That is rather a simplistic analysis. You failed to mention the applicability of the various approaches to the site and nature of the projects to be planned and executed. Every project is different, as is each methodology.

Test driven methodologies aren’t so new - they go back to the Grady Booch days and have been discussed since the early days. They have never gained much acceptance although they seem to come in and out of favor, which we currently see in the IBM Rational and Agile communities.

All methodologies are different balances of adherence to iterative cycles, testing first, modeling first, prototyping first, etc. There is no ‘best’ way that apples to everything.

TDD helps you design your software. No matter how many people work on your project, you’ll want to design your application effectively. Tests are just a side effect of TDD.

Huh? You can use TDD when practicing DDD. They’re not mutually exclusive.

I just feel writing test is a waist of my time. I work on very large projects which are always changing as we go and come up with ideas. I have never written tests unless it was performance tests to test my code. But I really think my time is better spent coding and fixing bugs than writing tests as well.

I rather have other guys testing while I go and report any bugs, and so far that has not failed me yet. As what if the tests are designed badly? Not going to give you a proper perspective of issues.

How big is a ‘very big project’ that doesn’t benefit from writing test script?

I didnt say it does not benefit. Im just saying that writing test scripts is a waist of time considering the crazy deadlines I get

This is very true, a bad test suite can be a very painful thing and extremely counter-productive

More importantly, the problem is not that a test itself is faulty. The problem is usually that you planned the wrong tests for your application. I’m always trying to think outside the box to figure out what I’ve missed in the application design and construction. That’s one reason a team is great, it gives you other people to bounce ideas off of.

This exactly who we do it here. We have high level discussion of how a feature is going to be designed, usually with some throw away diagrams on the white board.

This is a common problem in any design and forces you to design a little, code a little, design a little more, code a little more, etc. TDD however does a couple things that, in my opinion, actually make application design much harder.

I think having a design constantly evolving with a simplified means to dog-food if is one of the pluses of TDD. Would you care to share that couple of things that you think that TDD does that makes application design harder?

In TDD, however, you write low-level test after test which takes you so far down into the app that it’s hard to see the forest for the trees.

You can write TDD at any level of abstraction that suites you, and the CI server is designed to increase the awareness of the the health of the application team wide. If you not seeing the forest for the trees, then I think you might have bigger issues that TDD.

Then, as the sheer mass of tests you’re running continues to grow and as they all continue to return “successful” results, it tends to lull you into a VERY FALSE sense of security. I think these are two key flaws in TDD that for my money have sent me in other directions.

You have to lean to trust your test suite, if you don’t then your not going to the your ROI in it. The tests you wrote have to be testing the right thing and should constantly be refactored. If you have no faith or trust in your test suite, then you need the reasses your competency at writing tests. Blaming it on TDD with looking at how your writing tests isn’t going to help. We have a lot of tests, and I trust them when the are green and I know somerthing is broken when a test fails.

Does that mean that TDD is bad. No. I just prefer to plan out my testing checkpoints as part of my system design. This also gives me a good place in the design phase to do risk analysis and work risk mitigation plans into the design plan too. I do not find writing tests before coding to provide any particular advantage whether you’re programming solo or as part of a big team.

Just because you are practicing TDD does not mean you do no upfront design! We have a design phase, but its shorter and the resulting code is generally a fair bit different, but we have daily standups to discuss how we’re getting on, and are constantly reviewing each others code. TDD makes this process easier as a team mate can view code in isolation and use the unit tests generated by TDD as up-to-date documentation.

Bad design will kill you whether you’re writing bad code or bad tests first.
I think it’s easier to identify a bad design with TDD. If your tests are becoming difficult to write and maintain, your design is bad. Simple. TDD is easy, your designing your code with yours tests, nothing should be complicated or difficult. If it is, it’s time to review

I’ve worked on very large applications that where constantly changing with and without TDD over the years, and I have to say the applications written with TDD have generally been far easier to work with.

I have never written tests unless it was performance tests to test my code. But I really think my time is better spent coding and fixing bugs than writing tests as well.

I would rather spend my time writing tests and code. Bugs, pah! I honestly can’t remember the last time I had to kick up the debugger or deal with a bug report! Chasing bugs is no fun!

I rather have other guys testing while I go and report any bugs, and so far that has not failed me yet.

I would rather have every release of my code bug free, nothing to be reported and we can all get on with producing new code instead of fixing old code.

As what if the tests are designed badly? Not going to give you a proper perspective of issues.
This is a valid point, but its not a failing of TDD, its a problem with your ability to correctly do it. I had this problem too and have written many bad tests. To get better, I practiced a lot, forced myself to stick with it and read lots of articles about it and loads of OSS code.

Since I’ve really gotten my head around it, I’m far more productive, my bug count is just about 0 on every project I’ve worked on and when I do get bugs they are usually caught very early and never make it to production and it’s usually to do with the UI or areas that I haven’t correctly or lazily tested.

I used to think that too, but once you balance the time spent writing tests getting the code done and releasing, against writing the code, fixing the bugs and, and releasing, you’ll realise that TDD is actually quicker. Sure, without TDD you can get code in front of people quicker, but you spend more time after debugging. With TDD, you take a little more time to get it in front of someone, but when you do, thats generally it.

@dhtmlgod. You have some very good points, however I do just not have the time to get into it and write bad tests to start learning. As we are only 2 developers and always have about 5 running projects with strict deadlines.

I never release code into the wild with bugs. But I get it to the test guys and clients as quick as possible so they can test for bugs. They prefer to see something quicker with bugs than not. (Strange i know)

And by bug fixing I mean broken links or something not functioning as it should. But yes, I would love to get into TDD. But my problem is the learning curve. Not writing test that is gona cause more harm than good, is impossible atm. And that is what I mean about wasting my time.

As I am sure it will be more productive once I know what I am doing. It is just the getting to that point which is preventing me from getting into it atm.

As a methodology specialist, this kind of thread always interests me. There is a certainly reason to consider the size of a project when determining the methodology, but the ‘size’ of a project is ambiguous. Adding a complicated methodology to a small project brings wasteful overhead, for sure.

For me, a project that would be considered huge by any standard would be something like the one I’m working with now - a team of 80 developers working in J2EE, Siebel, and Maximo to produce an application to support a public housing organization that managed hundreds of thousands of properties. We have collected over 800 complex use cases and 2400 functional requirements and there are over 20 external integrations (which is killing us). The project should take about 2.5 years and we hope to bring it in at around 55 million.

That’s a big one.

But what about the 50k project? At what point do you forgo all process and just go for it. It’s an interesting question.

By big project I not only mean complexity, but also deadline. We also work with very largre projects. Sure, not on that scale, as we are 2 developers and 2 designers and our current project is about the management of books and authors, etc. There are over 4million authors and 3 times that books. And a typical deadline for something like that would be little over a month. With social functionality as well. It is a big project in a little time for our team size, as it is also not the only project on our plate at the same time.

And as soon as we done we have other projects waiting for us. I would love to explore new methodologies like I did in the past when we where client. But dnt find the time at the moment.

I think the methodology question is better answer by deadline/experience with said methodology and complexity. As you write, small projects could get to complicated using some methodologies

It’s probalby important to calrify, that TDD is not the same as writing unit tests. TDD is a methodology, that suggests writing tests first (which is what I believe you are experieicng issues with?). Writing unit tests can be done at anytime, before, during or after the implementation of a ‘unit’ of functionality.

That being said, writing tests first to assist in influencing your design (making sure it’s easily testable implementation, etc) is only part of TDD and effective unit testing.

Unit tests (I hate that word more and more as BDD advocates will tell you ‘unit’ is extremely vague) also have the benefit of telling you useful information about a codebase bigger than a few classes. When you change something, wouldnt’ it be nice to know instantly (without having to re-test everything from a user standpoint; system testing?)???

That is the beauty of having automated tests, whether they comply with everything TDD advocates will only make your testing efforts easier.

If you refactor your code (which everyone does) testing proves to be invaluable especially as the applicaiton grows in complexity. Not to mention, it gives new developers a starting point in learning exactly how APIs work, etc (documentation).

Depending on what tools you use, technologies, etc…unit testing can also let you know about dead code, etc.

Testing is a large subject, unit testing is what is popular amongst most professional developers. BDD is an interesting step in the evolution of testing, as opposed to classical testing defined by Fowler (Mocks aren’t stubs). Some dislike it, because it’s more closely coupled with the implementation details as opposed to result or state of a method or object under test.

Lastly (and perhaps not finally) is the ability to dictate more standard practices as a manager of a project. API is everything I care much less about interface. I usually know with some degree of certainty what an API should normally look like, so it’s easier to write tests first and let other developers go hog wild implementing the code, which I can then use as an object to solve certain problems I have. As I said above, for personal projects I do not bother writing tests first, however in a commercial environment where someone is paying me to effectively manage other developers writing tests first is very effective and keeping some control of the direction of the project without having the project result in some massive mess.

Cheers,
Alex

Some very good points. I think this sums everything up very well. I have to agree with you on this. I see how it could be very beneficial doing tests first to manage a team, but here where there is only 2 its not that important to write the tests first.

I think the is a lot of misconception around TDD which also makes it tough for people to get their heads around the methodology itself.

the other thing to remember about TDD is that the tests represent the desired functionality you want the code to produce, and not just examining “broken” code.

for example: you will write a test for a piece of functionality. The functionality doesn’t exist yet, so it has to fail. then you write the method to support said functionality and the test passes. When its time to add more functionality, then the test has to be updated and by nature has to fail. If the test passes, then either the functionality already exists, the test is broken, or the code is outputting an incorrect value.

i have a video presentation on it by robert martin that may be interesting to watch.

it mostly deals with the ethics of software craftsmanship, but there is a portion on TDD and he explains it quite well and why its necessary.

The video is broken.

I really don’t have a problem with understanding why people think TDD is important, I have a problem with understanding why it isn’t redundant.