51

My team at work is moving to Scrum and other teams are starting to do test-driven development using unit tests and user acceptance tests. I like the UATs, but I'm not sold on unit testing for test-driven development or test-driven development in general.

It seems like writing tests is extra work, gives people a crutch when they write the real code, and might not be effective very often.

I understand how unit tests work and how to write them, but can anyone make the case that it's really a good idea and worth the effort and time?

Also, is there anything that makes TDD especially good for Scrum?

EDIT 12 years later:

Although there is an initial learning curve, writing tests before your code will guide you in writing that code. You'll write less code, and it'll be higher quality because you find many of your mistakes sooner. It'll give you confidence to refactor with a chance that you'll immediately know you are breaking things. And the tests will explain weird stuff you might have been asked to do.

When I asked this question, I was naively asking in earnest. Today, I stumbled on my own question and now I honestly can't imagine starting a new project without doing some sort of test-first workflow.

11
  • 28
    If you would like to make sure that your software breaks down frequently, is more-or-less completely unmaintainable, and is due for replacement before it's actually ready for production; then I would suggest you dispense with unit testing entirely, and never take the time to learn TDD. Commented Mar 17, 2012 at 8:17
  • 3
    Think about the wish/need for a refactor. Would you be more confident in actually doing the refactoring (of any magnitude) with or without a comprehensive set of unit tests to catch you when you have inadvertently broken something? Commented Mar 17, 2012 at 9:53
  • 2
    "Gives people a crutch when they write real code"? Can't most best practices be described this way?
    – user16764
    Commented Mar 20, 2012 at 17:15
  • 4
    @DavidWallace: This is the problem of incompetent developers, not a lack of TDD. Moreover, even when TDD is used extensively, it gives zero guarantees that the change you made doesn't break anything.
    – Coder
    Commented Mar 20, 2012 at 18:11
  • 7
    @NimChimpsky: I don't have any negativity towards TDD, I'm just not following the hype. It has it's positive sides, and negatives as well. False sense of security being one of them.
    – Coder
    Commented Mar 21, 2012 at 14:52

9 Answers 9

69

Short Answer: Absolutely positively.

Long Answer: Unit tests are one of the most important practices I try and influence at my place of work (large bank, fx trading). Yes they are extra work, but it's work that pays back again and again. Automated unit tests not only help you actually execute code you're writing and of course verify your expectations but they also act as a kind of watch dog for future changes that you or someone else might make. Test breakage will result when someone changes the code in undesirable ways. I think the relative value of unit tests declines in correlation with the level of expected change and growth in a code base, but initial verification of what the code does make it worthwhile even where the expected change is low. Unit test value also depends on the cost of defects. If the cost (where cost is loss of time/money/reputation/future effort) of a defect is zero, then the relative value of a test is also zero; however this is almost never the case in a commercial environment.

We generally don't hire people anymore who don't routinely create unit tests as part of their work - it's just something we expect, like turning up every day. I've not seen a pure cost benefit analysis of having unit tests (someone feel free to point me to one), however I can say from experience that in a commercial environment, being able to prove code works in a large important system is worthwhile. It also lets me sleep better at night knowing that the code I've written provably works (to a certain level), and if it changes someone will be alerted to any unexpected side effects by a broken build.

Test driven development, in my mind is not a testing approach. It's actually a design approach/practice with the output being the working system and a set of unit tests. I'm less religious about this practice as it's a skill that is quite difficult to develop and perfect. Personally if I'm building a system and I don't have a clear idea of how it will work I will employ TDD to help me find my way in the dark. However if I'm applying an existing pattern/solution, I typically won't.

In the absence of mathematical proof to you that it makes sense to write unit tests, I encourage you to try it over an extended period and experience the benefits yourself.

8
  • 7
    What I'd like to add, is that unit testing also makes you think about your interface design. When you get to a part where you think "how do I unit test private methods?", you know it's probably your interface that's wrong.
    – TC1
    Commented Mar 17, 2012 at 12:29
  • 1
    " I encourage you to try it over an extended period and experience the benefits yourself." Just trying it once was enough for me, the benefits seemed obvious. Commented Mar 21, 2012 at 13:10
  • 1
    +1 for "We generally don't hire people anymore who don't routinely create unit tests as part of their work". I recently had to reject a candidate who among other shortcomings strongly proclaimed that he does not like to write automatic tests because they're a waste of time and he could test the code himself.
    – ftr
    Commented Mar 21, 2012 at 13:14
  • 5
    you can't prove that a nontrivial code works in any relevant way just by using automated tests. With automated tests, you can only prove that the code passes the tests - if the tests cover 100% of your use cases, you have your "certain level" probably, but that still doesn't mean that the code "provably works". To have a real provability, you'd need en.wikipedia.org/wiki/Formal_verification - as such, you're using the term "provably" wrong here.
    – user88637
    Commented Oct 14, 2015 at 13:00
  • 1
    @vaxquis yes, you're strictly correct about the use of the term proof. But I'd wager that the presence of tests (or the practice of TDD) is better evidence of a working system than the absence of tests is.
    – rupjones
    Commented Nov 30, 2016 at 11:26
18

Errors found earlier is less costly to fix than errors found later. TDD helps you verify the correctness of your system. You invest a little more up-front, but get it back later. The graph is a bit exaggerated , but it shows the idea well.

enter image description here

Image Source

2
  • What do you mean by traditional? Anything that is not TDD?
    – Giorgio
    Commented Jan 4, 2018 at 8:55
  • It does not seem this graph is based on some real statistics, it only represents the experience of a single person who wrote this Blog entry in 2006. Not that I am saying it is utterly wrong, but the reality is far more complicated.
    – Doc Brown
    Commented Jan 4, 2018 at 8:59
9

Is unit testing or test-driven development worth while?

Yes it does. Uncle Bob(Robert C Martin) told in a in a presentation;

For a developer to prove that his code is working better to write a test and pass it than shouting , singing or dancing about it.

And since you are not going to delete the test, as long as the test is a pass you are sure that functionality is working - regression issues are solved.

There are a lot of stuff written on it,

  1. You are responsible for making that feature work. Write a test. Just do it.
  2. When to replace Unit Tests with Integration Test

Are SCRUM, Unit testing and TDD related?

Shortly, When you are a master at Unit testing you will be near to TDD. SCRUM has nothing to do with this, but as they say, great things mix up well, these techniques of developing a software adds up into an excellent stack, if you have not tried it yet give it a try.

Is there anything that makes TDD especially good for SCRUM?

As I told above they make a good combination; If you add some automation testing to it, then it is more special.

8

It seems like writing tests is extra work, gives people a crutch when they write the real code, and might not be effective very often.

Unit testing has value as a crutch. It supports your development efforts, allowing you to change your implementation without fearing that your application will cease to work as required. Unit tests are also much more than a crutch, as they give you a tool with which you can validate that your implementation matches the requirements.

All testing, whether unit tests, acceptance tests, integration tests, and so on, is only as effective as the people using them. If you approach your work sloppily, your tests will be sloppy, and your implementation will have problems. So why bother? You bother testing because you need to prove to yourself and your customers that your software works, and hasn't any problems that could prevent the software from being used. Yes, tests are definitely extra work, but how you go about testing will determine how much effort you will need to put in fixing bugs after release, and how much effort your code will require to change and maintain.

I understand how unit tests work and how to write them, but can anyone make the case that it's really a good idea and worth the effort and time?

TDD, and really any method that requires you to write tests before you code takes the approach that you put in an effort early as a down payment on future technical debt. As you work through the project, anything that gets missed, or is not implemented well will incur more technical debt in the form of increased difficulty of maintenance, which directly affects future costs and resourcing requirements. Testing up front ensures that not only have you made an effort to address future technical debt, but also ensures that you encode your requirements in such a way that they can be verified simply by running your code. Test first also gives you the opportunity to validate your understanding of the problem domain before you commit to solving the problem in code, and it validates your implementation efforts.

It really comes down to attempting to maximize the business value of your code. Code that is largely untested and difficult to maintain is generally cheap and fast to create, and very costly to maintain over the lifetime of the product after release. Code that has been tested thoroughly at the unit level is generally more expensive to create, but costs comparatively little to maintain over the lifetime of the product after release.

Also, is there anything that makes TDD especially good for SCRUM?

TDD is not specifically good for any particular methodology. It is simply a tool. A practice that you can integrate into your development processes in order to help you to achieve your specific outcomes. So to answer your question, TDD is complimentary to your method, whether it is SCRUM, or any other approach.

6

People think it is extra effort because it is an up front activity. What you lose in time now you gain back later on.

My reasons for unit testing also include:

Gives you a target: You can't write a test if you don't know what the software should do. This helps weed out issues in specifications earlier rather than later.

Gives you a sense of progress.

Warns you if a code change alters the output of other areas of code. That makes refactoring easier.

Provides an additional layer of documentation (especially if you comment your tests properly).

Encourages all sorts of good practices. Because tests should run fast, it encourages you to write code that is decoupled and supports mocking. This all aids refactoring.

There are others as well covered in other posts in this thread. It is worth it.

2

All of the code you write needs to be tested at some point. You don't want to write the whole thing all in one go and then hit the compile button and cross your fingers. You write and compile small blocks and send carefully-crafted input at your code to verify that it does what you think it does. Then, you usually delete your ad-hoc testing apparatus and move on to the next component.

With unit testing, it simplifies this process and gives you an excuse to keep your tests around. That way if you make any changes that break the stuff that you'd tested in the past, you can catch that regression explicitly instead of allowing it to affect other parts of your code. There's real value in that.

As for the red-green-refactor approach to TDD, I find that a bit tedious. But to each his own.

1
  • 1
    For my 2c: In order to to know if your tests are actually working, you need to see them fail before you see them pass. I've sadly witnessed many developers write tests that seemed to be working, yet when the test conditions were changed, the code would still pass the test, even though it should have failed. If the test fails first and passes second, then it is more likely that you've written a test without error. If you end up modifying the test after the code has changed, then you can't be certain the code is sound. Yes it's tedious, but it's got a better chance of being correct. :-)
    – S.Robins
    Commented Mar 17, 2012 at 9:50
2

Is unit testing or test-driven development worthwhile?

Definitely yes (see the other answers)

[Is it] really a good idea and worth the effort and time?

  • Yes if you start something new (add a new module or a completely new application)
  • No if there is already a lot of existing code that was not developed test-driven and that must be extended (legacy).

In my opinion test-driven development is most effective if you write the unit tests before the actual code. this way the code that fulfills the tests becomes clearly separated with a minimum of external references that is easy testable.

If the code already exists without the unit tests there it is usually a lot of extra work to write the unit tests afterwards because the code was not written for easy testing.

If you do TDD the code automatically is easy testable.

2

Let me approach this from the other side. What happens when you develop a non-trivial application without unit tests? If you have a good QA department, one of the first things that will happen is that you will find that you have a large number of reported issues. Why because you didn't test what you did and assumed it would work and because you didn't pay that much attention to the requirements and your application doesn't meet them. Oops back to the drawing board to rewrite and fix. Now you've made the fixes and find a whole new set of issues because you had no way to verify that your fixes didn't affect anything else before you pushed to QA. Oops deadline has now come and gone and management is upset.

Situation is worse if you don't have a good QA department because then the users will find the bugs and not only will that make your boss unhappy, it may bring the production environment to its knees and 100s or even thousands of people will be at a standstill while you fix the bugs that unit testing would have prevented. This is NOT a good career choice.

Now suppose this cowboy approach goes on for years? Now every change, even trivial ones, seems to bubble up a new unsuspected problems. Not only that, but many of the things you would like to do to make the application work better, you can't do because they are too risky or too expensive or both. So you put patches on the patches making the system more and more convoluted and buggier and harder to use.

Users start questioning your time estimates because they keep getting larger and larger and it's hard to explain to them that the system has become such a complicated mess, it is hard to find where to even make the changes and harder still to make sure they don't break something else.

I worked in a place like this where after ten year of development, virtually nothing we wanted to do to fix the real problems could be done because we couldn't tell which of hundreds of customized client applications would break. The initial developers were very much the "unit tests, we don't need no stinking units tests" kind of developers. Everyone who followed them suffered thanks to their short-sightedness.

Without unit tests, software is buggier and takes longer both to initially develop and to maintain. Why on earth wouldn't you want to do unit tests? The time you spend writing the test will be far less than the time you would spend fixing issues you should have found earlier (the earlier the bug is found the less time it takes to fix) and issues you would have avoided altogether by writing the tests first which gives a better understanding of the requirements before you start coding.

0

Most of the time I find developers are resilient to the idea of writing tests. It's not so much that they will argue tests have no value but rather that they are merely a means to figure out how to solve a particular problem. Usually this problem changes based on the context. Once that is done then the tests serve no purpose and might as well be deleted. Here's a sample of contexts my colleagues have given in the past on how to decide when to write a test and you'll find the only possible answer according to them is never:

  • the problem at hand must be a text book example for TDD such as a stack or a calculator
  • trivial code should not be tested (invalidates previous argument)
  • critical or difficult code should be thoroughly tested (implied by previous argument)
  • tests should not be thigtly coupled to the implementation to allow for sweeping refactoring (invalidates previous argument)
  • testing for side-effects such as calling a third party service with a specific payload is not necessary (so no black box testing)

Actually there is one type of testing which I have found is generally accepted and which I believe is ultimately useless. Namely GUI based testing such as by using selenium, webdriver, watir or arquillian. This is how we get the 7 hour build cycles rather than the 5 minute build cycles on my TDD projects.

These same devs usually complain with everybody else how bad the code is and how incompetent the previous devs must have been. They also find it extremely important you make a proper design using a whiteboard, MS office or a wiki and take great care to ensure this design remains up-to-date.

That last one is what really got me to realise such devs are frauds. We all know any design document which is not a unit test will become outdated and will not be kept up-to-date because of the sheer maintenance cost to do so. In fact I've tried and tried to come up with a good means to express design ideas in MS office format which was useful and legible both before and after the fact of writing code. I failed in all cases and though there are people who manage to produce an MS office document which appears pretty I've never actually found those useful either.

So, you have a choice. You can do design and documentation by practicing TDD which is the only known and proven method for producing such documentation based on my 10 years of development experience. Or you can go into politics.

4
  • 2
    tests are not documentation. TDD is a good practice, but too many times devs use the auto-gen tools which spit out too-simplified test stubs. If you have a dev who is resistant to this, instead of writing finely-grained tests, try writing a larger test harness that exercises more of the entire product. They'll find that obviously useful. You still have to write proper documentation though, there's no getting away from that.
    – gbjbaanb
    Commented Mar 20, 2012 at 15:47
  • @gbjbaanb: if developers use auto-gen tools, there are maybe writing unit tests, but definitely not TDD. In TDD you are supposed to write test before methods. You can't automate scafolding of the test of a method that does not yet exists. Also well written tests are documentation (technical documentation for fellow developpers of the project, not requirements neither user manual). Well written and maintained unit tests show you how methods should be tests. And if tests are regularly checked and succeeding they are obviously more accurate than outdated documentation. You can't deny that.
    – kriss
    Commented Jul 2, 2013 at 9:56
  • unittests can be a very good developper documentation as they show examples how the api can be used.
    – k3b
    Commented Jul 2, 2013 at 12:56
  • The point of selenium, webdriver, etc. are that you don't have to manually QA the website as much. So you aren't saving time by removing them from your build process, because they themselves are meant to be time savers.
    – Muhd
    Commented Oct 8, 2013 at 1:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.