Test Driven Development Demonstrated Alan Christensen @christensena Tom Gutteridge @trgutteridgeA g ile P r o f e s s io n a ls N e t w o r k C h r is t c h u r c h Th a n k s to o u r s p o n s o r s …
Format• Introduction Presentation• Live coding exercise• Review slides• TDD in the real world• Questions and discussion
Test Driven Development• It is a development technique• Incremental (iterative) workflow • Always write a failing test first (red) • Only write the minimum code to pass the failing test (green) • Improve code while all tests are passing (refactor) http://www.agileapps.co.uk/methodology/continuous.html
Not about testing #1• Yes you do end up with a suite of tests• But TDD is a development exercise • my mindset is coding, not testing • I will not be exhausting edge cases, etc (at least initially)
Not about testing #2• By practicing TDD • I approach my code from the outside, focusing on specifying behaviour • I can focus on one thing at a time • My resulting code is inherently designed for testability • I get fast feedback
Live coding exercise• Coding Kata• Wikipedia definition: “A code kata is an exercise in programming which helps hone your skills through practice and repetition”
TDD improves design• Encourages separation of concerns/single responsibility principle (SRP)• Incremental, iterative: can lead to simpler designs• Reduces fear of refactoring, encouraging improvements to design• Alerts me to design smells
Tests as documentation• Unit test code provides numerous working examples of API usage• Good unit test structure and naming can act as a specification• Tests as documentation always up to date (or the tests are failing)
Objections to TDD• It takes too much time• Tests can make it harder to refactor, not easier• It’s just too hard with our legacy code or un-mockable framework(s)• Our test suite takes too long to run so we don’t run it very often
Why is TDD Hard?• Mindset seems unnatural at first• Many frameworks/library components make it difficult to verify behaviour• Large monolithic blocks of legacy code are hard to isolate• Good design is not always obvious at first• Forgetting to test first, not afterwards!
Make TDD easier• Practice Red-Green-Refactor discipline on simpler examples (e.g. katas) away from a real code base• Learn from each other (e.g. weekly brown bag/dojo sessions), pair programming• Learn good design, especially OO design• Listen to your tests! If it’s getting hard going, consider refactoring your code• Take it seriously!
Tips: Untestable Frameworks• Use adapter pattern to "broker" untestable dependencies• Adapters should be tailored to how they are used by the app. Adapters do not need to expose entire API, only what is needed• Decouple logic from frameworks (e.g. use MVC pattern)
Productivity with TDD• It takes practice to become productive• Test code should be taken seriously, not treated as throwaway• Keep duplication to a minimum but balance this with readability• Worst case: your design completely changes resulting in rewrite. You have the old tests as a reference (specs)
What is a unit?• "smallest thing that makes sense" George Dinwiddie• Sometimes a method, sometimes a collaboration of classes
Unit vs Integration• Unit tests • should be fast (fast feedback loop) • should be focused • when they fail, they usually point you to where problem is • rigorous within the component under test • one assert per test
Integration vs Unit• Integration tests • usually slow • good for verifying unit tested components connect together properly • good for acceptance tests • often easier to start with on a legacy code base
Other Topics• System Under Test isolation (mocks and stubs)• Real World Unit Testing (or how to deal with existing test unfriendly code)• Context specification (or how to write expressive, DRY test suites)• Tips and Tricks, avoiding anti-patterns
Links• String Calculator kata exercise http://osherove.com/tdd-kata-1/• Bowling game kata step by step (Powerpoint) http://butunclebob.com/ArticleS.UncleBob.TheBow
A particular slide catching your eye?
Clipping is a handy way to collect important slides you want to go back to later.