Test Driven Developm ent
Brian Nielsen Arne Skou
bnielsen@cs.aau.dk ask@cs.aau.dk
Test Driven Developm ent Brian Nielsen Arne Skou - - PowerPoint PPT Presentation
Test Driven Developm ent Brian Nielsen Arne Skou bnielsen@cs.aau.dk ask@cs.aau.dk TDD D fi ifi TDD Definifion Test-driven Development is a programming practice that instructs developers to write new code only if an automated test has
bnielsen@cs.aau.dk ask@cs.aau.dk
[ Mansel&Husted: JUnit in Action]
Test Last (waterfall)
Specification Write Test cases Code Impl.
Test Last (waterfall)
Write Test
Test Concurrently (i d d tl )
Specification cases
(independently)
Code Impl. Specification Write Test cases Code Impl.
Test First
cases
TDD is a technique whereby you write your test
Tests drive or dictate the code that is developed An indication of “intent” An indication of intent
Tests provide a specification of “what” a piece of code
actually does
Thinking about testing is analysing what the system
should do!
Some might argue that “tests are part of the Some might argue that “tests are part of the
docum entation”
Mainly Unit Testing
Automated Regression Unit Testing
Standards Domain Experts Standards Informal understanding in developer’s mind
Written specs (iinformal, ncomplete, ambiguous) Customers
“Code that isn’t tested doesn’t work” “Code that isn’t regression tested suffers
“If it is not automated it is not done!”
“A unit testing framework enables
Programmer Friendly
New code and changes to old code can
“Affect” sometimes means “break”
Regression = Relapsed to a less perfect
Regression testing: Check that code Regression testing: Check that code
Regression testing is required for a Regression testing is required for a
Refactoring is a behavior preserving
Restructure, simplify, beautify Refactoring is an excellent way to break
Refactor code tests [ Pass]
tests [ Pass] Refactor code tests [ Fail]
Fix code
Can’t think of t t Write Failed test any more tests
Efficiency
Identify defects earlier Identify cause more easily Identify cause more easily
Higher value of test effort
Producing a more reliable system Producing a more reliable system Improve quality of testing (maintain automated tests) Minimization of schedule Stable code base
Reducing Defect Injection
Small “fixes” have are 40 times more error prone than
new code = > Fine grained tests + run tests continuously
co t uous y
Better programmer Life
Can now work on your code with no fear; No one wants to support a fragile system;
With complete tests code away: With complete tests, code away:
Eases changes (XP embrace change):
addition of functionality addition of functionality new requirements refactoring
refactoring
In Extreme Programming Explored (The Green Book), Bill Wake describes the test / code cycle:
1
Write a single test
1.
Write a single test
2.
Compile it. It shouldn’t compile because you’ve not written the implementation code
3.
Implement just enough code to get the test to compile
4.
Run the test and see it fail I l t j t h d t t th t t t
5.
Implement just enough code to get the test to pass
6.
Run the test and see it pass
7
Refactor for clarity and “once and only once”
7 .
Refactor for clarity and once and only once
8.
Repeat
[Pass]
[Fail] [ Pass] Development continues
[Fail] continues
[Fail]
[Development stops]
Light controller toggles light on/ off when
switch On Off switch
i d i h( ) {
voi d t est Swi t ch( ) { s=new Li ght Swi t ch( ) ; check( s! =NULL) ; check( O N == s swi t ch( ) ) ; check( O N == s. swi t ch( ) ) ; check( O FF ==s. swi t ch( ) ) ; check( O N == s. swi t ch( ) ) ; }
Cl ass Li ght Swi t ch { publ i c enum Li ght St at e { O N, O FF} st at e; publ i c Li ght Swi t ch( ) { st at e=O FF; } Li ght St at e swi t ch( ) { Ret ur n st at e; } }
Cl ass Li ght Swi t ch { Cl ass Li ght Swi t ch { Cl ass Li ght Swi t ch { Cl ass Li ght Swi t ch { publ i c enum Li ght St a publ i c enum Li ght St at e { O N, O FF} st at e; t e { O N, O FF} st at e; publ i c enum Li ght St a publ i c enum Li ght St at e { O N, O FF} st at e; t e { O N, O FF} st at e; publ i c Li ght Swi t c publ i c Li ght Swi t ch( ) { st at e=O FF; } h( ) { st at e=O FF; } publ i c Li ght Swi t c publ i c Li ght Swi t ch( ) { st at e=O FF; } h( ) { st at e=O FF; } Li ght St at e swi t ch( ) { Li ght St at e swi t ch( ) { Li ght St at e swi t ch( ) { Li ght St at e swi t ch( ) { i f ( st at e==O FF) st at e=O N; i f ( st at e==O FF) st at e=O N; i f ( st at e==O FF) st at e=O N; i f ( st at e==O FF) st at e=O N; i f ( st at e==O N i f ( st at e==O N) st at e=O FF; ) st at e=O FF; i f ( st at e==O N i f ( st at e==O N) st at e=O FF; ) st at e=O FF; r et ur n st at e r et ur n st at e; r et ur n st at e r et ur n st at e; } }
Cl ass Li ght Swi t ch { publ i c enum Li ght St at e { O N, O FF} st at e; publ i c Li ght Swi t ch( ) { st at e=O FF; } publ i c Li ght St at e swi t ch( ) { i f ( st at e==O N) i f ( st at e==O N) st at e=O FF; st at e=O FF; el se el se st at e=O N; st at e=O N; r et ur n st at e; } }
Light controller toggles light on/ off when
New Requirem ent: When wire is held
switch
dim dim
Bright Dim1 Dim2 Off
dim dim
switch
voi d t est Swi t ch( ) { voi d t est Swi t ch( ) { voi d t est Swi t ch( ) { voi d t est Swi t ch( ) {
s=new Li ght Swi t ch( ) ; s=new Li ght Swi t ch( ) ; check( s! NULL) check( s! NULL)
check( s! =NULL) ; check( s! =NULL) ; check( O N == s. swi t ch( ) ) ; check( O N == s. swi t ch( ) ) ; check( O FF ==s. swi t ch( ) ) ; check( O FF ==s. swi t ch( ) ) ; check( O N == s. swi t ch( ) ) ; check( O N == s. swi t ch( ) ) ;
} voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { voi d t est Di m m er ( ) { s=new Li ght Swi t ch( ) ; / / i ni t i al l y of f s=new Li ght Swi t ch( ) ; / / i ni t i al l y of f check( s. get Level ( ) ==0) ; check( s. get Level ( ) ==0) ;
( ) ; / / No ef f ect when of f
( ) ; / / No ef f ect when of f ( ) ; / / ( ) ; / / check( s. get Level ( ) ==0) ; check( s. get Level ( ) ==0) ;
ax: 3
ax: 3 check(s.getLevel()= = 3); check(s.getLevel()= = 3); s dim(); s dim(); s.dim(); s.dim(); check(s.getLevel()= = 2); / / dimming works check(s.getLevel()= = 2); / / dimming works s.dim(); s.dim(); check(s.getLevel()= = 1); check(s.getLevel()= = 1);
c ec (s get e e () ); c ec (s get e e () ); s.dim(); s.dim(); check(s.getLevel()= = 1); / / cannot dim more check(s.getLevel()= = 1); / / cannot dim more }
Cl ass Li ght Swi t ch { Cl ass Li ght Swi t ch { publ i c enum Li ght St at e { O N, O FF} st at e; publ i c Li ght Swi t ch( ) { st at e=O FF; }
publ i c Li ght Swi t ch( ) { st at e=O FF; } i nt l evel ; i nt l evel ; publ i c i nt get Level publ i c i nt get Level ( ) { r et ur n l evel ; } ( ) { r et ur n l evel ; } publ i c voi d di m ( ) { publ i c voi d di m ( ) { i f ( st at e==O N && i f ( st at e==O N && l evel >1) l evel l evel >1) l evel ; i f ( st at e==O N && i f ( st at e==O N && l evel >1) l evel l evel >1) l evel - -
} publ i c Li ght St at e swi t ch( ) { i f ( st at e==O N) { { / / changed code st at e st at e O N; O N; st at e st at e=O N; O N; l evel =0; l evel =0; } el se { } el se { st at e=O N; st at e=O N; l l l l 3 l eve evel =3; } } r et ur n st at e; } } } }
Cl ass Li ght Swi t ch { Cl ass Li ght Swi t ch { publ i c enum Li ght St at e { O N, O FF} st at e; publ i c Li ght Swi t ch( ) { st at e=O FF; }
publ i c Li ght Swi t ch( ) { st at e=O FF; } i nt l evel ; i nt l evel ; publ i c i nt get Level publ i c i nt get Level ( ) { r et ur n l evel ; } ( ) { r et ur n l evel ; } publ i c voi d di m ( ) { publ i c voi d di m ( ) { i f ( st at e==O N && i f ( st at e==O N && l evel >1) l evel l evel >1) l evel ; i f ( st at e==O N && i f ( st at e==O N && l evel >1) l evel l evel >1) l evel - -
} publ i c Li ght St at e swi t ch( ) { i f ( st at e==O N) { { / / changed code st at e st at e O FF; O FF; st at e st at e=O FF; O FF; l evel =0; l evel =0; } el se { } el se { st at e=O N; st at e=O N; l l l l 3 l eve evel =3; } } r et ur n st at e; } } } }
Device Drivers at IBM [ Williams, Maximilien, Vouk ’03]
40% reduction in defect 40% reduction in defect
Identical severity
Approximately same productivity
Developers spend more time writing test cases, but
reduces time spent on (unpredictable) debugging reduces time spent on (unpredictable) debugging
64.6 KLOC new code + 34 KLOC JUnit tests
“We belive that TDD aided us in producing a product that
more easily incorporated later changes”
Emerged from Agile and eXtreme
XP Practices
Incremental
Continuous Integration Design Through Refactoring Collective Ownership Collective Ownership Programmer Courage
Lightweight development process Lightweight development process K. Beck: “XP takes best practices and
test-driven developm ent: A Practical Guide
Dave Astels Prentice-Hall/ Pearson Education, 2003 ISBN 0-13-101649-0 Reviewed BUG developers’ magazine, Nov/ Dec 2003
______________________________________ Test-Driven Developm ent: By Exam ple
Kent Beck Addison-Wesley, 2003 Addison Wesley, 2003 ISBN 0-321-14653-0
Martin Fowler Addison-Wesley, 1999 ISBN 0-201-48567-2
ISBN 0 201 48567 2
S. Amber. Introduction to Test Driven
Development (TDD). www.agiledata.org
D. Jansen and H. Saiedian. Test-Driven
Development: Concepts, Taxonomy and Future
p p
E. M. Maximilien and L. Williams. Assessing
Test-Driven Development at IBM. 25th International Conference on Software International Conference on Software Engineering, 2003
K. Beck and E. Gama. Test infected:
Programmers love writing tests Java Report Programmers love writing tests. Java Report, 3(7), July 1998
http: / / www.testdriven.com
http: / / www.junit.org