TDD ... Time Saving Development




I've been asked by some work colleagues to produce a short demo/presentation about TDD, so to get my mind into gear, I thought I put all my thoughts (and the thoughts of others) down on my blog and see if it provokes any feedback that can improve my presentation.  I really think about TDD as not so much Test Driven, but more Time Saving.  For us lazy developers that like computers to do as much work for us as possible, so we can be doing better things, why not just add automated testing to the computers to do list....


Red, Green, Refactor


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.

Source: http://en.wikipedia.org/wiki/Test-driven_development


More than just testing

•    More of a design technique
•    Clearly stating the business requirements through a “test”
•    Setting yourself incremental goals through test cases
•    Ensuring the developer fully understands the requirements before coding - how can you write a test if you don’t understand what you are testing?
•    Code completeness: You’re development is complete when you cannot think of anymore tests to write = meaning you have covered all the business scenarios that can occur.


Technical Benefits

•    Higher quality code and design = clear distribution of object responsibilities, low coupling and high cohesion
•    Designing for testability = easily verify what your code does
•    Better understanding of the context in which the code was written
•    Immediate verification that you don’t break any of the existing code
•    More confidence in modifying the existing system
•    Cleaner design and more flexible system


Business Benefits

•    Changes to the system can be produced quicker and with more confidence
•    Allows the business to change their mind with a quicker turn around time
•    Test cases when written correctly (in domain/business terms) provide another form of documentation around the context in which the system was developed
•    Less bugs make it into production code
•    Same bugs less likely to reoccur or be reintroduced into the system


Let's Be Realistic
  
TDD works best in complex enterprise systems that have evolving business requirements.  If you are working on a simple throw away prototype, or something that is never going to change ever again, then it’s probably not worth the effort.  However we do live in the real world and 90% of the projects we work on are evolving and complex enterprise systems.  Remember though that TDD is not just about testing, its more about design - and there is always a place for good design.


Code/Test Coverage

If you follow TDD precisely to law you should gain 100% code coverage, which means all of your production code has at least one test that is verifying its behaviour.  In the real world 100% code coverage is unrealistic to try to achieve.  GUI’s are the main killer of code coverage, but also testing simple getter/setter properties are really not worthwhile (this is very subjective though).  However you should strive to achieve as close to 100% coverage as possible.  Introducing mock objects into “hard to test” areas of your system will help you achieve this goal.

Below is a good explanation of why striving for 100% code coverage is a good idea:

“One of the biggest advantages to high levels of code coverage is the agility you gain. Agility means you have a thorough suite of tests to prove your code works as expected. When a new requirement comes in that means you have to change some core classes within your application, suddenly you can do such changes with courage and not fear the consequences because your tests tell you the exact consequences of the changes you make. You can make new releases more often and with a high level of confidence in the quality of the code in each release.  
I found the ability to release often and with confidence quite a mind shift for me. As I worked through numerous iterations of a log analysis application called toaster, and released them for production use, I kept thinking I hadn't tested it enough and would cringe about not going through a more formal test cycle. Occasionally I would manually test the production results just to confirm. And occasionally I would encounter a bug that wasn't picked up in the unit tests even though I had 100% coverage. But, this was far far far less than the number of bugs I was used to with more traditional / heavyweight methodologies.”     
Source:  http://homepage.mac.com/hey.you/lessons.html

Work Smart, Not Hard

By writing your code Test First, you always have your tests there to run at any time you see fit.  You can run them over and over with just the click of a button.  If you stick to traditional manual testing strategies, you will find yourself doing these tests over and over again in a manual, time consuming manner – or even worse, not testing at all.

“Before I switched to test first development, I'd write the code that I thought solved the problem and then proved that it did what I thought it should, whether that mean writing details to a log file, stepping through a debugger, or visually watching the results of running the code. All valid approaches to debugging and testing but when it came time to revisit the code, or fix a bug, all that effort had to be duplicated again. With test first you don't make that an option.”

Source: http://homepage.mac.com/hey.you/lessons.html


Why test first though? Why not do it later?

The short answer: because we are lazy by nature and won't ever get around to testing it if we leave it until later.

The longer answer:

By testing first, we are always setting ourselves "mini-goals".  We set ourselves a goal (write a test), work towards fulfilling that goal (write the code), and then clean up any mess we have have created in that process (refactor).  Testing first makes sure we as developers stay focus on the task at hand, and have visible indicators when our task is complete.  Without this, its very easy to just drift along not really knowing how much progress you have made.

At the end of a day of development, I like to leave one failing test, so that the next morning I can come in to work, run the tests and get an immediate reminder of what I was up to.


It’s all about maintainability
"Develop as though the next developer that will be maintaining your code is an axe murderer"

Source: sorry… please let me know if you know where this is from - I just remember reading it a while back.

Always keep in mind the next developer that is going to have to pickup your code, work out what its doing and make changes to it.   If the next developer comes onto the scene of a code base that is a complete mess with no visible testing strategy and has to delve through it to work out what is going on – and then is asked by the business to make a change to the core of that code… you may just find yourself opening the door one night to a bloke with an axe in his hand.  

Making changes and additions to a system without any simple way to verify those changes, is a time consuming and sometimes daunting task.  Wouldn’t it be wonderful if you could walk into a project, pickup someone else’s code, make changes to it and then check that you haven’t broken the existing system or introduced a new bug at the click of a button?



 del.icio.us  Stumbleupon  Technorati  Digg 

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this entry.
Comments

Leave a comment

 Enter the above security code (required)

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.