javablogspot

Just another WordPress.com weblog

Posts Tagged ‘Test Driven Development’

Contracts? Test-driven? Insight!

Posted by damuchinni on March 14, 2009

The other day I pair-programmed with a new guy at work. He showed my a class and its tests he and another guy had written a few week earlier. I don’t recall exactly what the class did, but it was quite simple, hence the tests was short and simple. Overall well written tests if you ask me.

As we looked at the tests we had the following conversation, which afterwards gave me an new insight to an idea I’ve had a long while: tests are contracts.
He: Most of these tests are for testing that the class logs correctly…
Me: Yes, is that a problem?
He: Well, I know TDD says that you need to write a failing test before you’re allowed to write any production code. But isn’t testing logging a bit over-kill?
Me: I understand what you mean. What kind of logging is this? Why does the class need to log?
He: We needed it to understand the code. For debugging.
Me: Is the logging needed now? Is there some script that parses these logs, for example?
He: No, it’s not needed any more.
Me: In that case I’d say that these tests isn’t needed.

I could go even further and say that those tests shouldn’t be written at all and should be removed. I actually think that tests like these are more confusing then anything else. I’m not saying those two guys who wrote these tests did anything wrong; they were doing TDD and was doing TDD right. What I’m saying is that, in my opinion, TDD isn’t ideal.

Yeah, I hear you’re cries: What?! Heresy! Calm down. I’ll try to explain.

My opinion is that a class’ tests should define what the class has to fulfill to be considered correct. To be precise, with ‘correct’ I mean ‘what makes all things that depend on the class behave correctly’. (I realize that this is an recursive definition of ‘correct’, but you’re a human being so you can handle it. :))

Recall that my pair-programming partner said that the logging wasn’t needed any more. This means that we could remove the part of the code that logs and the class would still be correct according to the definition above. However, the class would not pass its tests because of the tests that tests the logging. This means that the class is over-specified. This is bad. The solution? Ditch the logging tests!

And so my fellow pair-programmer did.

I often say that test-methods should be named shouldFoo since it makes you focus on the behavior that is tested instead of the part that is tested (the tested method for example). I’m thinking of extending this tip to nameing test-methods as shouldFooBecauseBar. If this convention was followed, the the test-methods that tests the logging whould be named shouldLogBecauseWeNeedItforDebugging. That name sound a bit silly, doesn’t it? That because it is silly to test it!

As I said, a class’ tests defines what the class has to fulfill to be correct. In other words, the tests is the contract that the class must fulfill. Having tests that define contracts is much better, I think, than having tests for every little piece of functionality a class have (i.e., TDD). One reason is that it makes it easier to understand how you can change the class without breaking anything.

Now don’t get me wrong, TDD is great, really great. But is it perfect? Of course not, that would be very naive to think (not to mention boring: Nothing more to do here, we’ve find the ideal solution! Now, let’s drink tea all day!).

Is contracts ideal? Probably not. It contracts better? Yes, I think so.

Advertisements

Posted in Test Driven Development | Tagged: , | Leave a Comment »

Test Driven Development

Posted by damuchinni on March 14, 2009

What is TDD?

Test-Driven Development (TDD) is a software development technique consisting of short iterations where new test cases covering the desired improvement or new functionality are written first, then the production code necessary to pass the tests is implemented, and finally the software is refactored to accommodate changes.

Practitioners emphasize that test-driven development is a method of designing software, not merely a method of testing.

Test-Driven Development Cycle

1.
Add a test

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. In order to write a test, the developer must understand the specification and the requirements of the feature clearly. This may be accomplished through use cases and user stories to cover the requirements and exception conditions. This could also imply an invariant, or modification of an existing test. This is a differentiating feature of test-driven development versus writing unit tests after the code is written: it makes the developer focus on the requirements before writing the code, a subtle but important difference.
2.
Run all tests and see if the new one fails

This validates that the test harness is working correctly and that the new test does not mistakenly pass without requiring any new code.
3.
Write some code

The next step is to write some code that will cause the test to pass. The new code written at this stage will not be perfect and may, for example, pass the test in an inelegant way. That is acceptable because later steps will improve and hone it.

It is important that the code written is only designed to pass the test; no further (and therefore untested) functionality should be predicted and ‘allowed for’ at any stage.
4.
Run the automated tests and see them succeed

If all test cases now pass, the programmer can be confident that the code meets all the tested requirements. This is a good point from which to begin the final step of the cycle.
5.
Refactor code

Now the code can be cleaned up as necessary. By re-running the test cases, the developer can be confident that refactoring is not damaging any existing functionality.

Repeat

Starting with another new test, the cycle is then repeated to push forward the functionality. The size of the steps can be as small as the developer likes, or get larger if s/he feels more confident.
TDD Benefits

*

Improve software quality by providing 100% test coverage.
*

Improve code design by forcing developer to think outside of the code as a critics.
*

Increase developer productivity.

”A 2005 study found that programmers that wrote more tests tended to be more productive” (see the research at http://en.wikipedia.org/wiki/Test-driven_development#Benefits)

*

Minimize/Remove debugging/troubleshooting time.

“Programmers using pure TDD on new (”greenfield”) projects report they only rarely feel the need to invoke a debugger” (see http://en.wikipedia.org/wiki/Test-driven_development#Benefits)

*

Code Implementation time is shorter.

“While it is true that more code is required with TDD than without TDD because of the unit test code, total code implementation time is typically shorter.” (see http://en.wikipedia.org/wiki/Test-driven_development#Benefits)

*

Makes Refactoring easy by removing bug fears.

TDD Disadvantage

*

The tests themselves become part of the maintenance overhead of a project.
*

Developer aptitude towards writing test case.
*

Management support is essential. (http://people.apache.org/~stevel/slides/testing.pdf)

Posted in Test Driven Development | Tagged: , | Leave a Comment »