XP Reflections - Test Driven Development
|
|
This article is written by Dave
Chaplin, an IT Consultant with 10 years experience. He leads and mentors teams of developers
on agile .NET projects and has extensive experience in agile development techniques, particularly
Test-Driven Development. Dave can be emailed at
davechaplin@byte-vision.com.
Date:
Thursday, September 16, 2004
Abstract
This article reflects on experiences of leading teams who use the technique of
Test Driven Development (TDD). It discusses observations made together
with some practical advice for those considering embracing the technique.
Introduction
The set of ‘XP Reflections’ articles are based on actual hands on experience in
the field leading teams of developers doing XP.
When I state doing XP I’m not really referring to following precisely the
out-of-the-box XP process. Like most projects the process was adapted to suit
the specific project, culture and capabilities of the organisations in which it
was used.
This article discusses the topic of Test Driven Development.
[Acknowledgements to Antony Marcano of http://www.testingreflections.com
for the inpiration behind the 'reflections' phrase. His site is well worth
checking out.]
Benefits of TDD
In my opinion Test Driven Development is the greatest asset to come out of the
agile movement. Significant quality and productivity gains are made by using
TDD. Hence it is very rapidly spreading through development circles.
TDD speeds development by decreasing the time taken to regression test code in
orders of magnitude. For example, on a previous assignment we could
exhaustively regression test 45,000 lines of code (4 people – 18 months) using
around 600 tests in 48 seconds.
With TDD repeat bugs are eliminated.
Before learning TDD it is like owning a car and always driving around in fourth
gear when in fact it has five. Then someone comes along and shows you how to
use fifth gear (TDD). The journey becomes smoother and faster. Considering
going back to continued use of fourth gear is futile.
Every developer who I have trained in TDD techniques (about 25) continues to
use TDD for their development effort today.
Win-Win
The technique provides a win-win for both management and developers. Managers
obtain a comfort factor that the each release of the application will have high
quality. They are spreading TDD as they move from company to company. Having
‘seen the light’ in one organisation they are keen to turn the switch in
another.
Developers no longer have to code in fourth gear when they know fifth.
Developers coding using TDD would prefer to code with others who have also
learnt TDD. Otherwise they are dragged back down to fourth gear. ‘Can I show
you how we can work quicker and enjoy it more?’
Is it new?
TDD aligns itself with the best practice of ‘Test Automation’. Basically, do
lots of testing, do it often, and make it darn quick to do. This then ensures
it is fast, exhaustive and 100% repeatable.
However, the problem in the past has been that the best practice of Test
Automation has normally* only been adopted at the functional level by
professional test teams after developers have released a version ready for
testing. Professional testers have then used tools like WinRunner, Robot, and
more recently OpenSTA.
[*There are some organisations who have conducted Test Automation at the
development level, but it is certainly not common.]
So, whilst TDD is new in terms of its branding, essentially it just brings the
best practice of Test Automation to the development level. We all should have
been doing this for years anyhow!
Some could argue that TDD is different to traditional unit testing in that the
tests are written before the code. This is true, and it helps to ensure the
design is testable. But, good designers should design systems that are
testable. Either way, you get to the same result.
TDD fills the gap
Developers have never really embraced testing before shipping software for
testing. Developers like to create, and find testing their own code incredibly
dull – so they don’t do it.
Some ad-hoc testing gets done in development, but it is rarely exhaustive,
usually manual, and applied at the functional level – testing from the front
end of the application.
Occasionally a developer might build a test harness which they can use to test
components built, but this is usually a windows form they have knocked together
and again requires manual testing.
Manual test harnesses are step closer but they are certainly not fast, not 100%
repeatable, and not exhaustive. Also, the tests are only documented in the
developers head, and they are the only person who knows who to use the test
harness. This is not ideal.
TDD uses standard industry wide tools that are freely available, an example
being NUnit for .NET development.
Implementing TDD – some practical advice
Having discussed the advantages of TDD and why it is becoming increasingly
popular here’s some practical comments regarding implementation:
-
TDD is counter-intuitive for traditional developers. They initially think that
it cannot possibly be quicker to write twice as much code. [Typically test code
size is the same as production code.] In my experience the only way to convince
them is to ask for their trust, and demonstrate it in a real world scenario.
Once they see they will their test times reduced and code quality increased it
will simply click.
-
TDD in the hands of novices can result is huge messes being made. The options
are to hire a mentor or suffer the same mistakes again. You will achieve your
objective twice as quick with a mentor.
-
Learning TDD takes time:
-
Developers can learn how to use standard unit testing tools in an afternoon. It
can then take them around three months (with a good coach) before they then
learn what to test and how to write a good test.
-
After the three month period of learning how to write good tests it will take
an experienced OO developer and designer (5+ years) a further 6 months before
they become good at designing systems for testability.
-
After about one year a good OO designer will have testability embedded in their
thinking to a point as which it is instinctive.
-
The quality of the test code needs to be of production quality. This is often
overlooked and maintaining test code as the application code expands can become
cumbersome.
-
TDD is used in agile methods that make use of refactoring. It is not advisable
to even consider refactoring without a full suite of exhaustive tests.
-
Whilst tests are required at the unit level, it is important to have tests at
the functional level. These then provide a safety net when refactoring ‘below
the bonnet’.
-
In terms of developer capability my view is that TDD requires very good
developers who have at least 5 years development experience in an OO language
combined with knowledge and experience of using design patterns. TDD is
certainly not for hackers.
-
Applying TDD principles to existing projects is hard. It is likely that the
existing code base has a design which is untestable. This means the level of
decoupling and interfaces are not sufficient to be able to inject tests at any
point in the code base. Retrofitting tests to existing systems can be a real
pain. It is much easier to start with TDD in mind than it is to retrofit it
afterwards.
-
For reasons raised above, for those embracing TDD for the first time it is
advisable to start with a new project. Perhaps a small one.
-
It is true that considerable gains are made using TDD in iterative development
projects. Since quality is higher there is no stepping back before moving
forward after each test cycle and release. In one shot developments it is still
beneficial to use TDD since the development effort itself is still iterative
and as the application evolves significant gains are made in the ability to
regression test previous work in seconds.
-
Whilst TDD produces massive productivity gains, bear in mind that its tests are
applied at the functional level – not the business. You could build yourself a
very fast development capability like a well oiled machine. But if your
business requirements are wrong, and you’ve been driving up the wrong road, the
application is worthless. Getting to the wrong place in a broken car or a
fighter jet is the same. It is still the wrong place.
Closing comments
TDD is provides significant quality and productivity gains and is a win-win for
managers and developers.
It is however hard to do, and it is advisable to start small for the first time
and if possible hire a mentor.
Other Articles
Test Driven Development (Dec 2003)
The Losers Olympics (Sep 2003)
Making Projects Succeed: Part 1 - Measurable
Business Goals (Sep 2003)
Pitfalls In Software Development (June 2003)
Extreme Web Architectures - Testing Web Applications In
Seconds (June 2003)
Pair Programming and Quad Programming - From
Experience (June 2003)
Making Extreme Programming A Success (April 2003)
Contractual Test Driven Development (TDD with DBC)
(April 2003)
Moving To XP (Feb 2003)
Maximising Development Productivity (Dec 2002)
Writing Automated Browser Tests Using
NUnit and IE (Oct 2002)
Mitigating Requirements Risk With Agile
Practices (Oct 2002)
10 Tips for Successful Team Leading (Oct
2002)
Developing Automated Using Tests Using NUnit 2.0
With VB.NET (Sep 2002)
Quality By Design - Part 1.doc (May 2001)
Quality By Design - Part 2.doc (May 2001)
Quality By Design - Part 3.doc (May 2001)
Other Resources
NUnit
http://www.nunit.org/
http://sourceforge.net/projects/nunit/
Extreme Programming
http://www.extremeprogramming.org/rules/testfirst.html
http://www.extremeprogramming.org/index.html
Refactoring
http://www.refactoring.com
Agile Modelling
http://www.agilemodeling.com/
|