Agile Zone is brought to you in partnership with:

Dror Helper is an experienced software developer has written and designed software in various fields including video streaming, eCommerce, performance optimization and unit testing tools. He is passionate about programming best practices and all things software development, and has been a guest presenter at several user group meetings and ALT.NET events. Dror's blog can be found at http://blog.drorhelper.com where he writes about unit testing, agile methodologies, development tools, programming languages and anything else he finds interesting. Dror is a DZone MVB and is not an employee of DZone and has posted 57 posts at DZone. You can read more from them at their website. View Full User Profile

Why you fail with TDD

01.17.2011
| 14050 views |
  • submit to reddit

I’ve been working hard the last six months teaching my teammates about unit testing, code reviews, SOLID, SCRUM and anything else I think we can benefit from. I feel lucky – for the most part they are open minded and accept my ideas and try them without prejudice, working this way has enabled better code and work for both the team and myself.
Over the last months the team’s productivity has increased, the unit tests got a lot better and the code has improved dramatically. But not all is peachy - There is one methodology that I’m having only partial success in convincing my team that they should use – namely Test Driven Development (TDD).
While some of the team use TDD exclusively others still find it too hard and/or cumbersome to use on their daily tasks. I know they’ve tried, and failed using TDD for some of their tasks and now the only reason they keep on trying is because I insist they do it – without real benefits.

Why some fail while others succeed

I wanted to investigate why TDD worked great for some while completely missing the point for others – could it be that the tasks of the developers that used TDD were easier to test? perhaps the developers that didn’t manage to apply TDD worked more with complicated legacy code that was just harder to test?
After much investigation I came to the conclusion that to some extent the success or failure of TDD depends on how easy it is to write tests for that piece of code which is effected heavily from the amount of code existing before the change and how well it was previously tested. But that’s not the whole picture, when I look at the code written by the developers that found TDD to be “just too much work” I almost always see more than one assert which indicates that they might be trying to test too much –and if you write the tests before the code means that it’s a lot harder to do that when you’re actually planning on implementing a few features at once – not very TDD at all…

The TDD way


TDD is not about the tests – it’s about design:
image
By writing the test you actually create a form of specification (singular not plural!) and by making the test pass you satisfy the requirement. By this logic multiple asserts means (more often than not) that you’re implementing multiple requirements at the same time. Another issue with trying to write a test for multiple requirements is that the test tends to be much more complicated than a test that checks only one thing.

One final thought

Multiple asserts is not necessarily a bad things, there might be a valid reason to writing multiple asserts to test a single requirement.
I have a trick to check if a test maps to more than one requirement - ask the developer “what are you testing here”, if he uses “and” in the sentence i.e. “I make sure that the username is valid and an email is send” he might be testing too many things.
References
Published at DZone with permission of Dror Helper, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Tags:

Comments

Amin Abbaspour replied on Mon, 2011/01/17 - 8:05am

"TDD is not about the tests – it’s about design"

dude! this was excellent. 

Dieter Luypaert replied on Mon, 2011/01/17 - 8:13am

Is it possible you swapped the arrows around at the second step. Otherwise I might have missed the point.

Endre Varga replied on Mon, 2011/01/17 - 9:03am

I work on research projects where getting the algorithm/design right at first (even for the most trivial pieces) is completely impossible. With TDD I end up using more time maintaining my tests due to frequent code and design changes than I am using for coding. I found that TDD slows me down with at least one magnitude. 

Sasha Arsic replied on Mon, 2011/01/17 - 9:08am

They should not try to "use TDD", they should use the Law of Demeter and the Single Responsibility Principle. Then they will "think TDD" and benefit from the tests.

Dean Schulze replied on Mon, 2011/01/17 - 10:38am

Endre,

 Your comment reminds me of this attempt by Ron Jeffries to TDD his way to a Sudoku solver, compared to Peter Norvig's solution:

   http://xprogramming.com/xpmag/OkSudoku

   http://ravimohan.blogspot.com/2007/04/learning-from-sudoku-solvers.htm

 (Tags aren't working in this thing, again.)

 I think the real lesson from this fiasco is that Agile zealots won't admit when their methods don't work.

 

 

Dean Schulze replied on Mon, 2011/01/17 - 10:40am

I've heard TDD referred to as "Big Test Up Front", and the diagram reminds me of the waterfall diagram.  Has agile taken us from BDUF to BTUF?

 

 

Nicolas Bousquet replied on Mon, 2011/01/17 - 10:56am

The thing is TDD alone give you nothing.

The fact is for TDD, you have to already perfectly know the solution and work in an environment where there is good code coverage.

When dealing with any existing code (even code written last week by your teammate), problem is that you do not master it. So basically you don't really know what it really do, what to expect, and what to do to add this new small functionnality or how to correct this bug.

 You know challenge is not to make a unit test that check you correctly load the new parameter from the configuration file or the database. The problem is not to write this simple if depending of whether the parameter evaluate to true of false. It is really trivial.

The problem is figuring where to put this test in thoses 13 millions lines of code (my case at work). What are the real inputs, and what output are expected.

You can "try" and of course you try. But this is not Unit Test that will give tell you what is the good output. It is not even the specification. What give you the solution is running the damn software, debug, inspect the variables, inputs and output. Insert thoses 2 or 3 lignes of code. Run again, verify. Check that you was wrong... try again...

Basically what you use is a debugger together with the real application with production data (not to say it run on production system !!!).

When you have finally corrected the bug, if the code you modification is based on is already well tested, designed for testing, you can add a new unit test losing only a few minute for it.If it is not designed for testing, just testing the trivial addition you made could require a day of coding and you will not do it because you want to correct a bug per hour, not a bug per day.

 This is not to say TDD is bad. This is to say TDD is not the silver bullet some try to convince you it is.

Josh Marotti replied on Mon, 2011/01/17 - 2:20pm in response to: Dieter Luypaert

Dieter, look at the graph again.  If the tests succeed BEFORE you write code, then you have bad tests ;)

Step one assumes no code is written.  You write tests first, then write code to pass the test.

Sivaprasadreddy... replied on Mon, 2011/01/17 - 8:41pm

Hi,

Nice post. IMHO TDD will succeed if the team is technically good, committed to write good code, otherwise project will end up with unmaintainable code and useless outdated unit tests.

Why i explicitely said "committed to write good code" is i have seen lot of developers who just think we can write in any way if it works for now, they don't worry if its not a good practice, or it is a bad design.

Martin Groenhof replied on Tue, 2011/01/18 - 8:45am

TDD, is like putting the Cart in front of the Horse, it does not work because it breaks the whole mentality of development, make something work -> see if it solves the problem -> repeat if necessary -> solution -> test it

TDD does not offer you the flexibility of trying out 100 different solutions, you HAVE to get it right the 1st time, who in their right mind would write 100 different test cases 1st and than try wrting code to fill them, bonkers

 Test yes, but only when you're satisfied with what you got and think it works

 

TDD was invented because the Evangelists needed a new product to sell

Cedric Beust replied on Tue, 2011/01/18 - 1:29pm

If the team is good and committed to writing good code, the project will probably succeed, whether they use TDD or not. And I agree that TDD basically kills serendipity and experimentation. It also forces you to write tests for throwaway code, hence a big amount of churn. I know it usually takes me 2-3 attempts before I am satisfied with an initial version of my code, so writing tests for these early attempts is just a waste of time.

Andy Leung replied on Tue, 2011/01/18 - 6:41pm

I agree with everybody who thinks TDD is not very helpful in many cases. I think people are confused with TDD and PoC (Proof-of-Concept). If you know how things work in high level or conceptually, you know what syntax you are going to put in, you write all pseudo code, everything looks fine, but you still wanna make sure if this meets the requirement, yeah you should spend time on testing this whole concept before you actually do detail design.

BTW, the TDD you have in the drawing is more of a Unit Testing to me than TDD. So if developers are doing Unit Testing on all "units" they build, isn't that best practice that is applicable to waterfall, Agile or any other approach? So really there is no TDD such thing?!

Stephanie Gacho replied on Tue, 2012/05/29 - 9:18am

Failing is not a big issue. No one is perfect, right guys? We need to encourage them to strive more to finally perfect the TDD. For those who know how to do it, give them some advices so that next time they will finally make it perfect. Don’t let them down just because of one mistake. -essay writing service reviews

Kookee Gacho replied on Mon, 2012/06/11 - 10:36pm

In test-driven development, each new feature begins with writing a test. This test must inevitably fail because it is written before the feature has been implemented. - Arthur van der Vant

Carla Brian replied on Sat, 2012/06/30 - 11:03am

This is interesting. I want to learn more on this one. I am not familiar with this one yet. - Mercy Ministries

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.