Test Driven Lasse Koskela Chapter 1: The Big Picture Paul Ammann http://cs.gmu.edu/~pammann/ Overview • • • • • The Challenge: Solving the Right Problem Right Solution: Being Test-Driven Build it Right: TDD Building the Right Thing: Acceptance TDD Tools for Test-Driven Development A Different Approach To Software Development 7/1/2016 2 The Challenge: Solving the Right Problem Right • Most Systems Don’t Work “Quite Right” – Even If They Did, They Often Solve The Wrong Problem • Creating Poorly Written Code – Riddled with Defects • Lots of Drivers: Time to Market, New Technologies, Lots of Code – Nightmare to Maintain • “I don’t want to touch that!” (But software does evolve!) • Failing to Meet Actual Needs – Do Specifications Actually Capture Customer Requirements? Software Development is Hard 7/1/2016 3 (One) Solution: Being Test-Driven • Approaches – Traditional: Design, Implement, Maybe Test – TDD: Test, Implement, Refactor • High Quality with TDD – Quality Comes in Many Flavors – Less Time Fixing Defects • “Aged” Defects are Much More Expensive to Fix • Meeting Needs with Acceptance TDD – Formulating Requirements Directly As Acceptance Tests • What’s In It for Me? – No More Long Debugs, More Confident, More Time Process: Hard To Quantify, But Can Have a Huge Effect 7/1/2016 4 Functionality: Incremental Integration TDD Encourages Incremental Integration of Functionality Inventory of non-integrated work Integrated Functionality Total Functionality Risk Reduction: Non-Integrated Functionality is Dangerous 7/1/2016 5 Evolutionary Design Traditional Design Advice is to Anticipate Design Designers Often Anticipate Changes That Don’t Happen Anticipated Change Anticipated Change That Doesn’t Happen Emerging Design Unanticipated Change Both Anticipated and Unanticipated Change Affects Design 7/1/2016 6 Build It Right: TDD • Test-Code-Refactor: The HeartBeat – The Rule: Only Ever Write Code To Fix A Failing Test – Traditional Development Cycle – Test-Driven Development Cycle – TDD Vocabulary Sometimes Called Red-Green-Refactor 7/1/2016 7 Build It Right: TDD • First, We Write A Test • This Really Amounts To Design By Example – We Make API decisions – We’re Thinking Hard About How Code Is Used – We’re Taking a Client Perspective • That’s Good! – We’re Working At A Very Small Scale • Example for a Stack – stack = …; stack.push(x); y = stack.pop(); assertEquals(x,y); – Note: A Simple Setter/Getter Approach Satisfies This Test. Start With One Concrete Client Interaction 7/1/2016 8 Build It Right: TDD • Then We Write Just Enough Code – We Don’t Write More Code – All We Want Is To Make The Test Pass • It Should Be A Very Small Gap • Implementation Probably Not Optimal • We Don’t Care (Yet) Goal: Make Code Base (Just) Pass Test Suite 7/1/2016 9 Build It Right: TDD • And Then We Refactor • TDD Without Refactoring Just Makes Ugly Code – Thoroughly Tested, But Ugly • There Are A Variety of Transforms To Address This • Developing In Small Increments – The Code Always Runs! • Changes Are Small Enough To Fit In Our Heads • TimeFrame is Minutes To (Maybe) Hours – Evolutionary Design • Anticipated Vs Unanticipated Changes • Many “Anticipated Changes” Turn Out To Be Unnecessary New Ways To Apply Standard Lessons 7/1/2016 10 Build It Right: TDD • Keeping Code Healthy With Refactoring Refactoring: A disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior – Refactoring is Disciplined • Wait For A Problem Before Solving It – Refactorings are Transformations • Many Refactorings Are Simply Applications of Patterns – Refactorings Alter Internal Structure – Refactorings Preserve Behavior Focus Is On Current Code, Not Future Code 7/1/2016 11 Build It Right: TDD • Making Sure The Software Still Works – Protection With Automated Tests • Test Harness is Only Thing That Ensures Software Works • Rerun Tests After Each Change (Regression Testing) – Fast Feedback • Sometimes, Entire Test Suite Is Too Slow • Role Of Continuous Integration Servers – Regression Tests In Background – Management of Multiple Developers/Multiple Changes TDD Works In Actual Practice 7/1/2016 12 Build The Right Thing: “Acceptance” TDD • TDD For Requirements Capture – Closely Related To Use Cases • Tests Are The Shared Language – Clients and Developers Agree On Concrete Stories • Tests as Specifications – Most People Understand Examples Better Than Definitions • Specification By Example – A Powerful Way To Convey • The “Happy Path” • And Also The Exceptions and Variations We’ll Focus On “Regular” TDD In This Class 7/1/2016 13 Tools for Test-Driven Development • Unit Testing With Xunit – We’ll Focus On JUnit; Many Similar Tools Exist • Acceptance TDD Has Its Own Toolsets • Continuous Integration and Builds – These Tools Are Necessary In Practice • Code Coverage – There is a Lot More to Coverage Than Koskela Presents • Interesting Number for Edge Coverage: 85% Without Tools, TDD Is Infeasible 7/1/2016 14