Where Developers Matter
Integrated Development Environments for Windows, Java, and Web Developers
| | Log On

The Coad Letter: Test-driven Development, Issue 95, Why Test

Abstract: In this issue, we explore the behavior of testing

Dear Friend,

Welcome to this issue of the Test-driven Development Edition of The Coad Letter which is based on some (of the many) words of wisdom from Ron Jeffries. The subject we'll be discussing is "Why Test?". I was inspired to write this issue by reading a posting that Ron made to the XP mailing list[2]. Ron was responding to a question from Carl Manaster about whether test code is not needed if you could have written code that worked fine in the first place.

-- Dave

Dave Astels
dave@adaptionsoft.com

Ron Jeffries
Object Mentor, Inc.
ronjeffries@acm.org

PS. Do you lay awake nights worrying about your software projects? Do you have the data to show whether or not they are out of control? With eXtreme Programming you'll always have the proof that they are on-target, on-time, and on-budget. Learn how you can sleep soundly again at www.adaptionsoft.com.

PPS. Get this free report by Hurwitz Group and see how Together ControlCenter helps you improve your application-development processes while building higher quality applications. Find out how to control costs and make the most of your infrastructure assets.


1 The Question: Part 1

Plenty of test-laterers or test-neverers would tell you, honestly, that they have written some routines that worked right the first time, without testing. How they can know they work right without testing may be another question, but let's assume for the moment it's true. I'll be a little bolder here and assert that I have on occasion written routines that worked right without unit tests.

If the code works when written without tests, is writing the tests wasted effort?

2 The Response

Yes.

That's why XP originally had the rule to test everything that could possibly break. Now, however, the practice of testing in XP has evolved into Test-Driven Development. You don't worry about what needs to be tested and what doesn't. You write the tests first to drive what needs to be written.

So, if it can't possibly be wrong, then don't test it.

Well, almost.

Tests not only ensure that the code you just wrote works as required, it also protects that code against the unintentional introduction of errors in the future. This can be the result of making a change while implementing some other feature in such a way that the original functionality is broken. It can also be due to making a mistake when refactoring by hand. This has two important purposes:

  1. as a regression test to make sure that everything that works now still works in the future
  2. as a checkpoint during integration. Since all tests have to pass for the production codebase, all tests have to pass after you integrate your latest work. If they fail, you've broken something.

Therefore if your code can't possibly be wrong and will never need to change, then don't test it.

Well, almost.

Tests also help us design the code and its interface. How? When we write a test first, before the code that will pass that test, we are in the place of a client of the code. We are only concerned with what the behavior is, not how it works. The code in question is not written yet, so we are free to choose the interface that is most usable. This applies to functionality (e.g. I need to be able to ask the Sale object for its total) and naming (e.g. total(), getTotal(), calculateTotal(), ...). This is known as intentional coding and we'll have an issue on that in the near future.

We invariably get simpler and more clear designs when we do TDD. Why? When we do a design phase before coding (aka Big Design Up Front (BDUF)) we're guessing. Some of our guesses are more educated than others. We aren't always thinking in terms of how that interface will be used, but rather what functionality we think it will need to have. When we design using TDD, we are making those decisions while we write code that will use that interface. The result is an interface that does just enough for right now, does what is really needed, and has names that read well in real code. We are designing the interface in the context in which it will be used.

So if your code can't possibly be wrong will never need to change, has a perfect design, and everyone loves the interface, then don't test it.

Well, almost.

Tests also explain the code. Consider that with a full set of tests (as you will have if you use TDD...if there isn't a test for a specific function, then that function isn't there) you have a full set of examples of how to use the code. A well written set of tests will show what happens with boundary conditions, how to properly use the code, and what happens in error conditions. It is a "cookbook" that is implicitly up to date. How many times have you been on a project and looked something up in the official cookbook, only to find that it is out of date compared to the code? No more.

So if your code can't possibly be wrong, has a perfectly simple design, and everyone loves the interface, and if the code and how to use it is perfectly clear, then don't test it.

Well, almost.

It isn't enough that the code can't possibly be wrong, has a perfectly simple design, and everyone loves the interface, and if the code and how to use it is perfectly clear.

We have to know in advance that this is true.

So you're right. Strictly speaking, any code that we know with certainty, is perfectly clear in operation and usage, that works perfectly, that is perfectly easy to use, and that contains absolutely zero defects, does not need testing.

Can you say that with certainty about your code? I know I can't say it about mine. That's why I use TDD.

3 The Question: Part 2

Of course tests are there to ensure that future changes don't break the code, but - well, YAGNI (YAGNI is an XP acronym for You Aren't Going To Need It, and was originally applied to the practice of designing and coding for functionality that you think that you might need in the future. The way requirements and technology changes, there's a fair chance you're wasting time & effort if you do anything before it's needed). Some code never gets refactored; some code never gets broken. I suspect there are a great many tests out there that, after first green (this refers to "the green bar" of jUnit: when all tasks pass the progress bar is green, if any test(s) fail the bar turns red) has been achieved, never fail again (and I'm thinking that first green could have been achieved without the test).

4 The Response

Tests are in fact wasted for any code that really will never be edited, and that really works perfectly, about which you need to learn nothing before you write it, and that is perfectly easy to understand, and perfectly easy to use, and has the simplest possible design. Therefore do not test such code. We'll call this the don't test rule.

Of course, for this to work, you must do it perfectly. Therefore, if, while using the don't test rule,

  • there is EVER a bug in any of your code, or
  • the code EVER has to be edited, or
  • you EVER see a way to make that code better, or
  • anyone EVER asks a question about how the code works, or
  • anyone EVER complains about the interface to the code,

you must stop using the rule and return to using test-driven development.

5 In Closing

I hope you've enjoyed this insight into the rationale for testing and what can be gained from it. In the next issue we'll have a look at the standard tool for test-driven development in Java: the jUnit unit test framework.

Dave

Afterward

Ron coached the original XP team and has been coaching XP teams since 1996. He has been developing software since 1961. Ron created and oversees xprogramming.com[1] and is the co-author of Extreme Programming Installed[3].

Thanks to Ron and Carl for their kind permission to quote them and take editorial license with their words.

Bibliography

1
Ron Jeffries.
XProgramming.com an extreme programming resource.
www.xprogramming.com.

2
Ron Jeffries.
private communication, April 2002.

3
Ron Jeffries, Ann Anderson, , and Chet Hendrickson.
Extreme Programming Installed.
The XP Series. Addison Wesley Longman, 2001.
ISBN 0-201-70842-6.

Published on: 8/3/2002 12:00:00 AM


Server Response from: BDN9A

 

Borland® Copyright© 1994 - 2008 Borland Software Corporation. All rights reserved. Contact Us  |   Site Map  |   Legal Notices  |   Privacy Policy  |   Report Software Piracy