1. What is it?
    1. "Technique for building software that guides software development by writing tests" (Martin Fowler)
    2. "A rapid cycle of testing, coding, and refactoring" (James Shore)
    3. "[a way to] give us feedback on the quality of both [the code's] implementation (“Does it work?”) and design (“Is it well structured?”)" (Nat Pryce & Steve Freeman)
    4. "A way of managing fear during programming" (Kent Beck)
  2. What it promises
    1. Predictability
    2. Learning & Feedback about the code/design
    3. Confidence to make changes
    4. Less time spent debugging
    5. Confidence to say "it works"
    6. Creating room for other kinds of testing (exploratory)
    7. Preventing unneeded code
    8. Focus on doing one thing at a time
    9. Executable specification/documentation
    10. The opportunity for better design
  3. Mechanics
    1. Write a test list
      1. Write down any examples that come to mind
      2. Write simpler examples
      3. Write examples for all variations, edge cases, and cool scenarios that come to mind
    2. Start with a failing test, then make it pass
      1. Uncle Bob's 3 Laws
      2. Red / Green / Refactor cycle
    3. Basic "moves"
      1. First Things First
        1. start by writing an assertion
      2. Keep the House in Order
        1. All tests must pass before moving on to the next test
      3. Duplication Fighter
        1. Remove duplication after all tests pass (production & test code)
      4. Better Green than Sorry
        1. Refactor only when all tests are passing; re-run all tests after every refactoring
      5. No Guessing Games
        1. Test names reflect intent
      6. Assertive Minimalist
        1. Minimize the number of assertions ("test one thing")
    4. Green Bar Patterns
      1. Fake it ('til you make it)
      2. Triangulate
      3. One-to-Many
      4. Obvious Implementation
    5. Advanced
      1. The Transformation Priority Premise
      2. The Cycles of TDD
      3. The Domain Discontinuity
      4. The Pragmatics of TDD
      5. How Test-Driven Development Works
      6. Specifying the negative in TDD
      7. TDD and Asynchronous Behaviour
  4. Unit Test Design
    1. What is a Unit Test?
      1. Martin Fowler's definition
      2. They are called Microtests (Mike Hill)
      3. "A test whose result (pass or fail) depends on the correctness of the implementation of a single piece of non-trivial behaviour" (JB Rainsberger)
    2. Good Unit Tests
      1. Programming with GUTs (Kevlin Henney)
        1. Tests drive development if they provide a clear specification of the required functionality: define what we mean by "this code is correct"
        2. Write your tests for the person trying to understand your code
          1. Describe context, starting point, preconditions
          2. Illustrate how the code is invoked
          3. Describe the expected results or postconditions
        3. Tests are written in a "propositional style": they tell you what the tests are about
        4. Test for required behaviour, not incidental behaviour
        5. Test behaviours, not methods
      2. Qualities of GUTs
        1. Intention Revealing
          1. Arrange, Act, Assert form
          2. Comunicate Intent
          3. Tell the Story of the System
        2. Defect Localization
          1. Explicit Cause-Effect
          2. Independent
          3. Repeatable
          4. Self-Checking
          5. "Test One Thing"
          6. Specific and Focused
        3. Fast feedback
    3. xUnit concepts
      1. Test Methods
      2. Assertions
      3. Test Suites
        1. Fixture
        2. Setup
        3. TearDown
    4. Listen to your tests
      1. What your tests don’t need to know will hurt you (JB RAinsberger)
      2. Checking a method directly or indirectly
      3. How to Write 3v1L, Untestable Code
    5. Test Smells
      1. Obscure Test
      2. Conditional Logic in Test
      3. Assertion Roulette
      4. Fragile Test
      5. Frequent Debugging
      6. Manual Intervention
      7. Slow Test
      8. Hard-to-test code
  5. Essential Books
    1. "Test Driven Development by Example", by Kent Beck
    2. "Growing Object-Oriented Software, Guided by Tests", by Steve Freeman & Nat Pryce
    3. "xUnit Test Patterns: Refactoring Test Code", by Gerard Meszaros
  6. The "TDD is Dead" debate
    1. TDD is dead. Long live testing (David Heinemeier Hansson)
    2. RIP TDD (Kent Beck)
    3. How Does TDD Affect Design? (James Shore)
    4. Is TDD Dead? Final Thoughts about Teams (Uncle Bob)
    5. Is TDD Dead? (Martin Fowler)
  7. Research
    1. Papers
      1. TDD vs TAC
        1. On the Effectiveness of Test-first Approach to Programming (Erdogmus, 2005)
          1. Test-First programmers write more tests per unit of programming effort. In turn, a higher number of programmer tests lead to proportionally higher levels of productivity
          2. Test-First programmers did not achieve better quality on average, although they achieved more consistent quality results.
        2. Evaluating Advantages of Test Driven Development: a Controlled Experiment with Professionals (2006)
          1. there is statistical evidence that TDD requires more time than TAC: this does not necessarily entail that TDD deteriorates the productivity, as the quality of code could be improved.
          2. there is not statistical evidence that TDD brings about more accurate and precise unit tests than TAC, even if subjects who used TDD outperformed those who use TAC, during all the experimental runs (inconclusive)
          3. TDD lets a greater predictability of performances than TAC
      2. Impact on Defect Density
        1. Test-Driven Development as a Defect-Reduction Practice (Williams, 2003)
          1. 40% reduction of defects, with minimal impact to developer productivity
        2. An Initial Investigation of Test Driven Development in Industry (2003)
          1. TDD approach appears to yield code with superior external code quality,
          2. The experiment results showed that TDD developers took more time (16%)
          3. On an average, 80% of the professional developers held that TDD was an effective approach and 78% believed the approach improves programmers’ productivity.
          4. Qualitatively, this research also found that TDD approach facilitates simpler design and that lack of upfront design is not a hindrance.
        3. Evaluating the Efficacy of Test-Driven Development: Industrial Case Studies (Baht, 2006)
          1. 2x improvement in defect density
          2. up to 35% increase in time
        4. On the Sustained Use of a Test-Driven Development Practice at IBM (Sanchez, 2007)
          1. significant reduction in defect density
        5. Realizing quality improvement through test driven development: results and experiences of four industrial teams (Nagappan, 2008)
          1. 40-90% drop in defect density
          2. 15-35% increase in time
      3. Impact on Code (Internal) Quality
        1. Quantitatively Evaluating Test-Driven Development by Applying Object-Oriented Quality Metrics to Open Source Projects (2009)
          1. improved the level of cohesion by about 20%
          2. improved the level of coupling by about 10%.
          3. improved the complexity level of code by about 31%
        2. An Empirical Evaluation of the Impact of Test-Driven Development on Software Quality (Janzen, 2006)
          1. Developers at all levels applying the test-first approach are likely to write more tests and achieve higher test coverage than with a test-last approach.
          2. Mature developers applying the test-first approach are likely to write less complex code than they would write with a test-last approach.
          3. beginning developers tend to write more complex software when using the test-first approach. However more mature developers tend to write more complex code with the test-last approach
          4. there are some indications that the test-first approach may decrease cohesion
          5. beginning developers tend to write larger methods and classes with the test-first approach, but that this trend seems to reverse as developers mature
          6. There are some indications that the test-first approach may increase coupling, although there is evidence that this could be a desirable type of coupling through abstractions.
          7. Mature developers applying the test-first approach are likely to write more smaller units (methods and classes) than they would write with a test-last approach.
          8. programmers using the test-first approach may be more productive while producing equal or better quality products than test-last developer (inconclusive)
          9. Mature developers who have applied both the test-first and test-last approach are more likely to choose the test-first approach.
          10. beginning programmers think the test-last approach is better and are more likely to choose it whereas more mature programmers think the test-first approach is better and are more likely to choose it
          11. despite recognizing many valuable benefits of the test-first approach, some programmers are still unwilling to choose it.
          12. trying the test-first approach significantly increases the likelihood of adopting it
      4. Developer Experience
        1. The Effect of Experience on the Test-Driven Development Process (2007)
          1. The experts achieve a higher conformance to the rules of test-driven development than the novices
          2. experts have shorter test cycles than the novices and the test cycles of the experts show a smaller variation.
          3. A novice who is able to follow the TDD process changes the test code more often than a novice who is not able to apply test-driven development
          4. The experts reach the first acceptance test in a shorter period of time than the novices. During that time frame, the experts write smaller programs and better tests than the novices in terms of block coverage
      5. Productivity
        1. The Impact of Test-Driven Development on Software Development Productivity — An Empirical Study (2007)
          1. TDD may have positive impact on software development productivity. Moreover, TDD is characterized by the higher ratio of active development time (described as typing and producing code) in total development time than test-last development approach.
    2. Summary Research
      1. A Case Study on Test-Driven Development in Mobile Software Development (2005)
      2. Test driven development: empirical body of evidence (2006)
      3. A Survey of Evidence for Test­Driven Development in Academia (2008)
      4. Overview of the Test Driven Development Research Projects and Experiments (2012)
      5. Effects of Test-Driven Development: A Comparative Analysis of Empirical Studies (2014)
      6. Comparing TDD research (summary slide)
  8. Reasons to do this crazy thing
    1. Why I Practice TDD (George Dinwiddie)
      1. freedom to start working toward my solution before I can map it all out
      2. freedom to clear my head of the details because my tests are keeping track of them for me
      3. freedom to make changes knowing my tests will alert me if I’ve violated a previous assumption that I’ve forgotten
      4. freedom to deliver code I can trust to work the way I think it does
      5. freedom of knowing I can correct my error without rewriting all the parts that do work
      6. freedom of feeling confident I can push my code into whatever shape I need, because I’m used to doing that every day
    2. A Hardheaded View of TDD (James Shore)
      1. Alerting me and others to errors when we change or add code
      2. Helping us understand the original intent of my code
      3. Helping me write correct, usable code now
    3. How TDD affects my designs (JB Rainsberger)
      1. More value objects
      2. More fire-and-forget events
      3. More interfaces
      4. Inmutability
    4. Is TDD Faster than TAD? (Jeff Langr)
      1. the ability to keep my code and design clean
      2. high confidence that I’m not breaking something in the process.
    5. "TDD solves our fear of changing code" (Uncle Bob) - Video
    6. How TDD and Pairing Increase Production (Michael Hill)
      1. the hard part of programming is the thinking, not the typing
      2. TDD increases your production because it serves as a thinking-aid
        1. limits back-tracking and gold-plating
        2. reduces code-study and debugging
    7. TDD and Its (at least) 5 Benefits (Scott Bain)
      1. it provides a very detailed, reliable form of something we need to create anyway, a functional specification.
      2. it provides clear, rapid feedback to the developers as they are creating the product code
      3. ability to refactor existing code in a confident and reassured fashion.
      4. ability to add new behavior in this same way. (confidence)
      5. ability to retain knowledge in a trustworthy form