1 / 64

Common Objections to TDD (and their refutations)

Common Objections to TDD (and their refutations). Seb Rose Twitter: @sebrose Blog: claysnow.blogspot.com E-mail: seb@claysnow.co.uk Phone: 01721 788178. Agenda. Motivation Education Inappropriate project Cultural Time pressures Unclear benefits. Refutations. Really?. re·fute

tirza
Télécharger la présentation

Common Objections to TDD (and their refutations)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Common Objections to TDD(and their refutations) Seb Rose Twitter: @sebrose Blog: claysnow.blogspot.com E-mail: seb@claysnow.co.uk Phone: 01721 788178

  2. Agenda • Motivation • Education • Inappropriate project • Cultural • Time pressures • Unclear benefits

  3. Refutations. Really? re·fute /rɪˈfyut/ verb(usedwithobject),re·fut·ed,re·fut·ing. • toprove to be false or erroneous, as an opinion or charge. • to prove (a person) tobein error.

  4. TDD – in one slide • Test First predates XP and Agile • TDD has been around for a while • One of XP’s core practices • Widely referenced • Still quite controversial • I am not going to describe TDD in any detail • Red/Green/Refactor (and variants) • ‘T’ for Test has unfortunate connotations • First ‘D’ definitely stands for Driven • Second ‘D’ may stand for Development or Design

  5. Survey • Simple survey ran for 3 months • Jan – Mar 2012 • 260 unique respondents • 896 objections • “What reasons are there not to practice TDD” • “The question wreaks of elitism - it should instead be ‘what reasons are there to practice TDD’”. • Free text made for a wide range of responses • Harder to analyse • Split into 18 types, grouped into 5 categories

  6. Results

  7. Breakdown • Education (223) • Lack of Practice, Lack of Investment • Project (194) • Domain, Legacy, Environment, Tooling • Cultural (179) • Management, Team, Fanaticism, Demarcation, Egotism • Time (174) • Slowness of development, maintenance and execution • Benefits (120) • Lack of Proof & Experience, Alternatives

  8. Interconnectedness of all things • Classification is subjective • Many responses could be categorised several ways • Respondents had different points of view • Their own objections • Objections they had heard others express • Further analysis required • Follow-up survey(s)

  9. Software Crisis! The required techniques of effective reasoning are pretty formal, but as long as programming is done by people that don't master them, the software crisis will remain with us and will be considered an incurable disease. And you know what incurable diseases do: they invite the quacks and charlatans in, who in this case take the form of Software Engineering gurus. - Dijkstra(ACM Turing Award Lecture 1972)

  10. Fanaticism and Fluff The steps of FDD are simple: • Take a tiny piece of fluff from the plate and put it on your head, holding your head quite still to ensure that the fluff does not fall off your hair. • Write a line of code. • Say, “I am the Fluff Lord, within the Dominion Of The Fluffists.” • Repeat. That’s it. Seriously, that’s all there is to it.

  11. Agenda • Motivation • Education • Inappropriate project • Cultural • Time pressures • Unclear benefits • Wrap up

  12. Hard to learn • “TDD is hard.” • Yes, it is • Any technique is hard to master • Fundamental changes are hard to adopt • 10,000 hours of practice • Did you stop trying to ride a bicycle when you fell off?

  13. Where to start • “Sheer lack of knowledge on how to approach it appropriately. There are too many bowling examples and not enough practicality.” • How do you usually learn something new? • Unit Testing skills are foundational • Coding Dojo to practice TDD • http://cyber-dojo.com • Better used as a group, but still useful solo

  14. Tests before code • “The compiler complains if I write tests before the code” • First step to get to green is to make the test compile • Only then can you move on to make the test pass

  15. Tests will be buggy • “Your test code is just your production code, written from the other end (i.e. just as complex and likely to have bugs)” • No process is infallible • “To err is human …” • Safety in numbers • Pair programming • Peer review

  16. Unfamiliar architectural style • “How will we ever know what’s going on if we can't see all of the code at once?” • TDD tends to lead to small, concise implementations • Low coupling • High cohesion • “Proliferation” of interfaces • Literate-ish programming

  17. No design improvement • “My observations of code from TDD-based projects show no significant improvement in architecture, security, code style, testability, etc. over other projects built with testing in mind.” • TDD ensures testability • Tendency for smaller decoupled composition • YAGNI & Emergent Design • Other design concerns (e.g. security, performance etc.) not addressed by TDD

  18. Learning several things at once • “In a new technology, it's too difficult to learn how to TDD as well as how to master that technology.“ • Even if you are experienced with TDD, it changes your perspective on the new technology • Idioms • Tooling • Kent Beck suggests reimplementingxUnit in the new language

  19. Discipline • “TDD is a discipline and a work habit. It's very difficult to establish the habit.” • Habits are hard to form, but also hard to break. • Nothing works better than positive feedback • There are many self-help guides available  • Switch – Chip & Dan Heath • Drive – Dan Pink

  20. Agenda • Motivation • Education • Inappropriate project • Cultural • Time pressures • Unclear benefits • Wrap up

  21. Too simple • "This code is too simple to need a test“ • Then the tests will be simple too • What’s simple to you may be opaque to others • As the code evolves, tests can help keep it simple

  22. Just a spike • “Because you're prototyping an idea and it's much faster to spike without tests. If you do end up using the code then you can write tests and refactor.” • Use the right tool – TDD is not mandatory • Discipline to ensure spike does not mutate • “Write one to throw away” • TDD the spike anyway!

  23. Not useful for all aspects of design • “I don't think that deriving a design by writing tests is a useful practice. Tests by themselves cannot cover many aspects of a design (designing for concurrency and performance in particular by writing tests is something that I've never seen anyone do).” • TDD is not the only tool in the toolbox • Probably wrong tool for performance testing • Can be applied to concurrency testing (but not recommended)

  24. Not useful for functional/declarative programming • “Because it is largely adequate in imperative programming and not when you go functional and declarative - when code reads like specification.” • Orthogonal. • Absence of side effects makes testing MORE effective. • Discuss!

  25. Legacy code • “Difficulty starting with legacy code. A simple change done through TDD can take orders of magnitude longer due to a need to redesign toward testability. ” • Working Effectively With Legacy Code – Feathers • Small, conservative steps, eventually tame fear and doubt • Consider less intrusive approaches initially • e.g. TextTest – texttest.org

  26. Insufficient tooling • “There is no unit-test framework for the language I'm using, and I don't have time/inclination to develop one myself.” • There probably is. • You might not need one • “TDD in C” – OlveMaudal

  27. GUI • “I do a lot of UI code and don't really know how to properly do that with TDD.” • “Subcutaneous” testing • Presenter First pattern • Based on MVC/MVP patterns • Very shallow view, with no business logic • Stateless presenter orchestrates interaction between view and model

  28. Excessive coupling to data • “A test expresses a unit of change as data that fits the needed computation. Creating that data is harder than writing the program that accomplishes the change.” • Unit tests preferably utilise ‘small’ amounts of data • For domains where this is not possible • You will need large amounts of data irrespective of test approach • Bootstrap process with constructed data • Continue with captured data

  29. Agenda • Motivation • Education • Inappropriate project • Cultural • Time pressures • Unclear benefits • Wrap up

  30. Management antipathy • “Management want results NOW; very much willing to clean up small oversights later. 'Close is good enough' attitude.” • Management are generally result focused • Previous bad experiences affect appetite for change • Both ways! • Start small • Need to demonstrate benefit to ‘bottom line’

  31. Team resistance • “Teammates are not prepared. They do not have enough knowledge or experience in unit testing.” • “No one tells me how to program!” • Changing behaviours is hard • “Fearless Change” has many patternsfor introducing change

  32. I never make mistakes • “I already know what the code needs to do and it's low risk. I don't need a test for it.” • “My first design idea is always perfectly good.” • “My code always works the first time.” • Do people really believe this? • Even if they do, is everyone that ever touches the code going to be so talented?

  33. Testing is for testers • “We don't need TDD, we've got a QA department. They'll find the bugs for us.” • TDD is not just about testing • Drives design • Refactoring/regression safety net • Write tests to explore EVERY defect you find • Living documentation • Helps future developers understand intended behaviours

  34. All TDD-ers are fanatics • “It has become a cult. Its advocates have made it antithetical to ‘Individuals and interactions over processes and tools’. It is evangelized through coercion and browbeating -- necessarily, as it isn't compelling on it's own.” • “Someone needs to tell unclebob that he might be right, but he's part of the problem - to non-modern coders (which felt like the majority last time I looked) he comes across like a raving loony.”

  35. Fluff (continued) If at any time you even THINK about writing a line of code before putting fluff on your head, then you’ve to delete all your code, shake all the fluff from your head onto the plate and start all over again. I have been practicing FDD for 12 years now; sometimes in the office, I have so much fluff on my head that my boss thinks I’m a hay-stack, only made of fluff. A sort-of fluff-stack, if you will. But one thing is beyond doubt: the code I write, when I’m in this fluff-zone, is the most high-quality code that anyone has ever seen.

  36. Agenda • Motivation • Education • Inappropriate project • Cultural • Time pressures • Unclear benefits • Wrap up

  37. More code to write • “Takes too much time to write test.” • How will your code get tested? • Test team? • Customers & Stack Trace Driven Development? • How much time will be spent figuring out how to make changes later? • What proportion of your time do you actually spend coding?

  38. More code to maintain • “If I change something it will break a whole bunch of tests that I will have to fix and it will be more work for me in the end than just verifying my changes manually.” • It is USEFUL to know when behaviour changes • Foundational Unit Testing skills reduce brittleness • next 6 slides

  39. Testability • Testability needs to be designed in • TDD ensures code is testable • Code with hidden dependencies is hard to test • Dependency Injection/Inversion • Pass dependencies into code under test • Write factories that permit injection of test doubles • Interfaces should be cohesive • Wide interfaces encourage unnecessary coupling • Avoid globals, singletons etc. • Retro-fitting unit tests is hard • Take small steps • Introduce a ‘seam’ – c.f. Working Effectively with Legacy Code

  40. Necessity • Test observable behaviour • Don’t modify encapsulation to aid testing • If a behaviour isn’t observable through the public interface what is it for? • Don’t slavishly write one test per method • Test behaviours • Some methods may not need any dedicated tests • Methods that implement useful behaviours may need many tests • Choose test variants carefully • Edge conditions • Invalid inputs • Multiple invocations • Error signalling

  41. Granularity • Test a SINGLE observable behaviour • It is tempting to combine related behaviours in a single test – DON’T • … even if EXACTLY the same steps are needed public void shouldSortTwoStringsAndReportCorrectSize() { SortedSet<String> animals = new TreeSet<String>(); animals.add(“Zebra”); animals.add(“Anteater”); assertEquals(2, animals.size()); assertEquals(“Anteater”, animals.first()); assertEquals(“Zebra”, animals.last()); }

  42. Understandability • Name tests to describe the behaviour under test • Describe nature of the test • Is it checking that preconditions are enforced? • Is a dependency going to signal an error? • Long names are fine – you only type them once • Be precise • shouldReturnCorrectValue is not a good name for a test • shouldReturnCorrectSumOfTwoIntegersWithoutOverflow • should_return_correct_sum_of_two_integers_without_overflow • When a test fails you want to know WHAT WENT WRONG • You don’t want to reverse engineer the test • You don’t want to run smaller tests to isolate the failure

  43. Maintainability • Unit Tests should be written to same quality as Production code • Tests will be maintained and read just as often as production code • Code is communication to other developers not just a compiler • Organise tests into cohesive suites • Refactor tests to avoid duplication • Use suites to perform common set up/tear down operations • Extract common code into methods • Extract common functionality into classes • Remove redundant tests

  44. Reiteration: 5 -ities • Testability • Necessity • Granularity • Understandability • Maintainability • MUNGT ? • TeNGUM?

  45. Mock-based tests rot • “Unit-test mock/stub assumptions rots” • Use collaboration and contract tests – J.B. Rainsberger • Collaboration tests make assumptions about the contract; contract tests try to justify those assumptions • A stub in a collaboration test must correspond to an expected result in a contract test • An expectation in a collaboration test must correspond to an action in a contract test

  46. That library is third party • “API layers above and below you don't provide adequate mocks. Testing against the ‘real thing’ is hard/impossible.” • “Don't mock types you don't own” – Joe Walnes • Write adapters that provide a domain specific API • Write acceptance tests that verify the library’s behaviour • Run whenever adopting a new version

  47. Slow execution • “Running the tests takes too long.” • For TDD to work tests need to (build and) execute in seconds • Some environments need careful configuration • C/C++ • Rails • Are they really Unit Tests? (See next slide)

  48. A test is not a unit test if: • It talks to the database • It communicates across the network • It touches the file system • It can’t run at the same time as other unit tests • You have to do special things to your environment (such as editing config files) to run it (Michael Feathers’ blog, 2005)

More Related