Walking Dead TDD Daniel Hinojosa
←
→
Page content transcription
If your browser does not render page correctly, please read the page content below
Walking Dead TDD Daniel Hinojosa
TDD is Dead?
The Bait “ Test-first fundamentalism is like abstinence-only sex ed: An unrealistic, ineffective morality campaign for self-loathing and shaming. TDD is dead. Long live testing. (http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html)
DHH’s TDD Shaming “ But whatever it started out as, it was soon since corrupted. Used as a hammer to beat down the nonbelievers, declare them unprofessional and unfit for writing software. A litmus test. — David Heinemeier Hansson TDD is Dead
DHH’s TDD Conclusion “ Yes, test-first is dead to me. But rather than dance on its grave, I’d rather honor its contributions than linger on the travesties. It marked an important phase in our history, yet it’s time to move on. Long live testing. — David Heinemeier Hansson TDD is Dead
What is Test Driven Development?
Test Driven Development Using tests to drive your code Allows you to understand your code Model the API the way you want it to look Means of communicating an API before implementation
A little more about TDD
The TDD Rhythm “ 1. Quickly add a test. 2. Run all tests and see the new one fail. 3. Make a little change. 4. Run all tests and see them all succeed. 5. Refactor to remove duplication. — Kent Beck Test Driven Development by Example 2003
Another take on TDD “ 1. Write a failing test. 2. Write code to make it pass. 3. Repeat steps 1 and 2. 4. Along the way, refactor aggressively. 5. When you can’t think of any more tests, you must be done. — Neal Ford Evolutionary architecture and emergent design 2009
Demo of TDD
Craps!
Benefits of TDD Evolutionary Design Ability to get rid of code Readable Code Refactoring with confidence Not Chained to your code and job Up front recognition of bugs Design software from the API perspective
But, What was DHH’s solution? Step one “ Step one is admitting there’s a problem. I think we’ve taken that now.
DHH’s solution? Step two “ Step two is to rebalance the testing spectrum from unit to system. The current fanatical TDD experience leads to a primary focus on the unit tests, because those are the tests capable of driving the code design (the original justification for test-first).
What is wrong with DHH’s TDD’s View? TDD never wants you not to do system testing. TDD is for instant feedback Don’t just solely relegate continuous integration to be testing heavy tests Clarifies later that unit testing (albeit after the fact) is valuable, though not TDD (Somewhat inconsistent)
TDD vs. Testing After the Fact Testing After the Fact is not TDD Testing After the Fact will never be TDD Testing After the Fact leads to inelegant solutions Testing After the Fact will often lead to: "Meh, Looks good" testing
Huge Point of Disagreement “ System testing only and Test After the Fact leads to vastly different code.
Disagreeable Code That Could Possibly be Prevented with TDD?
Constructors do the real work new keyword in a constructor static method calls in a constructor or at field declaration Anything more than field assignment in constructors Object not fully initialized after the constructor finishes (watch out for initialize methods) Control flow (conditional or looping logic) in a constructor Code does complex object graph construction inside a constructor rather than using a factory or builder Adding or using an initialization block Guide Writing Testable Code (http://misko.hevery.com/code-reviewers-guide/)
Digging into Collaborators Objects are passed in but never used directly (only used to get access to other objects) Law of Demeter violation: method call chain walks an object graph with more than one dot (.) Suspicious names: context, environment, principal, container, or manager Guide Writing Testable Code (http://misko.hevery.com/code-reviewers-guide/)
Brittle Global State & Singletons Adding or using singletons Adding or using static fields or static methods Adding or using static initialization blocks Adding or using registries Adding or using service locators Guide Writing Testable Code (http://misko.hevery.com/code-reviewers-guide/)
Class does too much Summing up what the class does includes the word “and” Class would be challenging for new team members to read and quickly “get it” Class has fields that are only used in some methods Class has static methods that only operate on parameters Guide Writing Testable Code (http://misko.hevery.com/code-reviewers-guide/) What about PowerMock?
Ambulance But who do I blame for such transgressions?
We are humans! Human nature has rules to ensure that we meet criteria in a society ..or a project Humans break rules for both good and bad reasons What determines whether it is a good or bad reason is why it was implemented in the first place…(Programmer Confidence) Humans break rules prematurely because they believe they have enough experience to break those rules
We are humans! Humans are arrogant Unexperienced Humans are especially arrogant (I was one) Do you want to form a culture and project with arrogant unexperienced programmers? Money and lots of it is pumped into software projects, you are allowed to make certain demands if it is your project
There is bad code out there, and a lot of it! Gets worse without TDD TDD forms a way of thinking TDD creates decoupled code, therefore reuseable code Arrogance breeds bad code Bad Code (Long lines with margins deep) Large Cyclomatic Complexity
"Letting go of TDD" doesn’t work I don’t continuously work on the same project, I need to refamiliarize myself with an old project. Documentation? Ok. Documentation doesn’t have good relationship to the code. Method names are useless onto themselves, knowing how it works with a test suite that doesn’t require set up works well! I have let myself slip, due to deadlines, and I am an experienced programmer. Scattered logic caused me to delete my code and start again.
Kent Beck “ "As a programmer, do you deserve to feel confident?" (Can you sleep at night knowing your code works) — Kent Beck Is TDD Dead? You Tube Video Series
Martin Fowler “ "The primary benefit of TDD is self testing code" — Martin Fowler Is TDD Dead? You Tube Video Series
My take on Martin Fowler’s Quote “ Extends what the compiler does, to check with your domain if what you are doing is accurate.
Robert Martin “ I know this sounds strident and unilateral, but given the record I don’t think surgeons should have to defend hand-washing, and I don’t think programmers should have to defend TDD. — Robert Martin The Clean Coder: A Code of Conduct for Professional Programmers 2011
Michael Feathers “ To me, legacy code is simply code without tests. — Michael Feathers Working Effectively with Legacy Code 2004
Rich Hickey “ "I think we’re in this world I’d like to call Guard Rail Programming… 'I can make change because I have tests!' Who does that? Who drives their car around, banging against the guard rails? Do the guard rails help you get to where you want to go?" — Rich Hickey Guard Rail Programming Bringing back TDD from the dead…
Why do we fail? Takes a lot of time Mocking is kind of an inane practice Over Testing/Violating YAGNI/Testing Useless Stuff Poor exception handling We weren’t taught that way I don’t know what I want when I start We do not leave our code alone
Do the new or alternative testing frameworks help us make it easier?
Cucumber-JVM (Java) Calculator.feature Scenario: The calculator should add two numbers from a feature Given a calculator instance When the sum method is given two numbers, 4 and 9 Then the calculator should return the sum of the two numbers https://github.com/cucumber/cucumber-jvm
Cucumber-JVM (Java) public class CalculatorFeatureSteps { private Calculator calculator; private int actual; private int expected; @Given("^a calculator instance$") public void a_calculator_instance() throws Throwable { calculator = new Calculator(); } @When("^the sum method is given two numbers, (\\d+) and (\\d+)$") public void the_sum_method_is_given_two_numbers(int number1, int number2) throws Throwable { actual = calculator.sum(number1, number2); expected = number1 + number2; } @Then("^the calculator should return the sum of the two numbers$") public void the_calculator_should_return_the_sum_of_the_two_numbers() throws Throwable { Assert.assertTrue(actual == expected); } } https://github.com/cucumber/cucumber-jvm
Do Alternate Languages help us?
Spock (Groovy) class Math extends Specification { def "maximum of two numbers"(int a, int b, int c) { expect: Math.max(a, b) == c where: a | b | c 1 | 3 | 3 7 | 4 | 4 0 | 0 | 0 } } http://spock-framework.readthedocs.org/en/latest/data_driven_testing.html
ScalaCheck (Scala) import org.scalacheck.{Prop, Properties} object BasicScalaCheckProperties extends Properties("Simple Math"){ property("Sum is greater or equal to its parts") = Prop.forAll {(x:Int, y:Int) => x+y >= x && x+y >= y} property("Sums are associative") = Prop.forAll { (x:Int, y:Int) => x+y == y+x } } Simple Properties Bites Quick and Fierce [info] ! String.Sum is greater than its parts: Falsified after 0 passed tests. [info] > ARG_0: 0 [info] > ARG_1: 0 [error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0
Test.Generative (Clojure) (defspec integers-closed-over-addition (fn [a b] (+' a b)) ;; input fn [^long a ^long b] ;; input spec (assert (integer? %))) ;; 0 or more validator forms
The Flying Wallendas
Links and Credits TDD is dead long live testing - http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html Mocks are not stubs - http://martinfowler.com/articles/mocksArentStubs.html Neal Ford - Evolutionary architecture and emergent design: Test-driven design, Part 1: http://www.ibm.com/developerworks /java/library/j-eaed2/ Miško Hevery - Static Methods are Death to Testability http://misko.hevery.com/code-reviewers-guide Nicole Adams - 10 Most Horrific Accidents in History [http://listverse.com/2013/04/22/10-most-horrific-circus-accidents- in-history]
Questions?
Thank You Email: dhinojosa@evolutionnext.com Github: https://www.github.com/dhinojosa Twitter: http://twitter.com/dhinojosa Google Plus: http://gplus.to/dhinojosa Linked In: http://www.linkedin.com/in/dhevolutionnext Last updated 2014-10-19 07:09:49 MDT
You can also read