{"id":180,"date":"2014-08-11T11:43:26","date_gmt":"2014-08-11T11:43:26","guid":{"rendered":"http:\/\/www.davefarley.net\/?p=180"},"modified":"2017-01-24T11:43:26","modified_gmt":"2017-01-24T11:43:26","slug":"the-basics-of-tdd","status":"publish","type":"post","link":"https:\/\/www.davefarley.net\/?p=180","title":{"rendered":"The basics of TDD"},"content":{"rendered":"<p>The objectives of Test Driven Development and unit testing are generally misunderstood. The problem is the word \u2018test\u2019, it is much less about testing and much more about specification of requirements, showing your working \u2013 as in maths, and the impact it has on design. TDD is much more important than only testing. Robert C Martin has a good analogy, he likens TDD to double entry bookkeeping:<\/p>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px 0px 0px 30px; border: 0px none white;\"><em style=\"text-align: left; background-color: transparent; vertical-align: baseline; font-style: italic; margin: 0px; padding: 0px; border: 0px none white;\">Software is a remarkably sensitive discipline. If you reach into a base of code and you change one bit you can crash the software. Go into the memory and twiddle one bit at random and very likely you will elicit some form of crash. Very, very few systems are that sensitive. You could go out to one of these bridges over here, start taking bolts out and they probably wouldn\u2019t fall. I could pull out a gun and start shooting randomly and I probably wouldn\u2019t kill too many people. I might wound a few but \u2014 you know \u2014 you get a bullet in the leg or a lung and you\u2019d probably survive. People are resilient \u2014 they can survive the loss of a leg and so forth. Bridges are resilient \u2014 they survive the loss of components. But software isn\u2019t resilient at all: one bit changes and \u2014 BANG! \u2014 it crashes. Very few disciplines are that sensitive.<\/em><\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px 0px 0px 30px; border: 0px none white;\"><em style=\"text-align: left; background-color: transparent; vertical-align: baseline; font-style: italic; margin: 0px; padding: 0px; border: 0px none white;\">But there is one other [discipline] that is, and that\u2019s Accounting. The right mistake at exactly the right time on the right spreadsheet \u2014 that one-digit error can crash the company and send the offenders off to jail. How do accountants deal with that sensitivity? Well, they have disciplines. And one of the primary disciplines is dual-entry bookkeeping. Everything is said twice. Every transaction is entered two times \u2014 once on the credit side and once on the debit side. Those two transactions follow separate mathematical pathways until they end up at this wonderful subtraction on the balance sheet that has to yield to zero.<\/em><\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px 0px 0px 30px; border: 0px none white;\"><em style=\"text-align: left; background-color: transparent; vertical-align: baseline; font-style: italic; margin: 0px; padding: 0px; border: 0px none white;\">This is what test-driven development is: dual-entry bookkeeping. Everything is said twice \u2014 once on the test side and once on the production code side and everything runs in an execution that yields either a green bar or a red bar just like the zero on the balance sheet. It seems like that\u2019s a good practice for us: to [acknowledge and] manage these sensitivities of our discipline\u2026<\/em><\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px 0px 0px 30px; border: 0px none white;\"><em style=\"text-align: left; background-color: transparent; vertical-align: baseline; font-style: italic; margin: 0px; padding: 0px; border: 0px none white;\">&#8211;<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" href=\"https:\/\/archive.is\/o\/LLhot\/unhandled-exceptions.com\/blog\/index.php\/2009\/02\/15\/uncle-bob-tdd-as-double-entry-bookkeeping\/comment-page-3\/\">Robert C. Martin<\/a><\/em><\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">The sensitivity of software is a good point to reflect upon, there is little in human experience that is so complex and yet so fragile. Without a strong focus on showing your working, no matter how good you are as a developer, if you omit the tests, your software will be worse than it could have been.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">The double-entry bookkeeping analogy only holds up though if you do test first development. If you write your test after the code it is generally not sufficiently independent to provide a valid \u201cseparate path\u201d check.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">Test first is the idea that your write the test before you write the code that is being tested. This seems like a bizarre idea to many people at first, but actually makes perfect sense.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">If you write the test first and run it, you get to see it fail, so you are testing the test.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">If you write the test first then you are expressing what you want of your software from the outside in. It leads you to design for behaviour and so you have less of a tendency to get lost in irrelevant technicalities.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">This is a much more effective design approach than testing after you have written the code, and as a by product it leads inevitably to software that is easy to test \u2013 you have to be pretty dumb to write a test before you have written the code for an idea that can\u2019t be tested!<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">Finally there is a virtuous circle here. Software is easy to test when it is modular. It is easy to test when dependencies are externalised and it is easy to test when there is a clear separation of concerns.<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">Now the software industry is famous for change, but if there is any idea that has remained constant for, literally, decades it is that quality software is modular, has well defined dependencies and clear separation of concerns \u2013 sound familiar? This has been how computer science has defined quality since before I started, and that was a very long time ago!<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px; border: 0px none white;\">Using TDD as a practice makes you produce higher quality software, not because it is well tested (though that is a nice by-product) but because it improves the quality of your designs. Want more detail:<\/div>\n<div style=\"text-align: left; background-color: transparent; vertical-align: baseline; margin: 0px 0px 24px; padding: 0px 0px 0px 30px; border: 0px none white;\"><a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/c2.com\/cgi\/wiki?TestDrivenDevelopment\" href=\"https:\/\/archive.is\/o\/LLhot\/c2.com\/cgi\/wiki?TestDrivenDevelopment\">http:\/\/c2.com\/cgi\/wiki?TestDrivenDevelopment<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/www.agiledata.org\/essays\/tdd.html\" href=\"https:\/\/archive.is\/o\/LLhot\/www.agiledata.org\/essays\/tdd.html\">http:\/\/www.agiledata.org\/essays\/tdd.html<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/butunclebob.com\/ArticleS.UncleBob.TheThreeRulesOfTdd\" href=\"https:\/\/archive.is\/o\/LLhot\/butunclebob.com\/ArticleS.UncleBob.TheThreeRulesOfTdd\">http:\/\/butunclebob.com\/ArticleS.UncleBob.TheThreeRulesOfTdd<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/unitmm.sourceforge.net\/fibonacci_example.shtml\" href=\"https:\/\/archive.is\/o\/LLhot\/unitmm.sourceforge.net\/fibonacci_example.shtml\">http:\/\/unitmm.sourceforge.net\/fibonacci_example.shtml<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/clean-cpp.org\/test-driven-development\/\" href=\"https:\/\/archive.is\/o\/LLhot\/clean-cpp.org\/test-driven-development\/\">http:\/\/clean-cpp.org\/test-driven-development\/<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/agile2007.agilealliance.org\/downloads\/presentations\/TDD-Cpp-Agile2007-HandsOnTddInCpp.ppt_801.pdf\" href=\"https:\/\/archive.is\/o\/LLhot\/agile2007.agilealliance.org\/downloads\/presentations\/TDD-Cpp-Agile2007-HandsOnTddInCpp.ppt_801.pdf\">http:\/\/agile2007.agilealliance.org\/downloads\/presentations\/TDD-Cpp-Agile2007-HandsOnTddInCpp.ppt_801.pdf<\/a><br \/>\n<a style=\"text-align: left; background-color: transparent; vertical-align: baseline; color: #0066cc; margin: 0px; padding: 0px; border: 0px none white;\" title=\"http:\/\/www.growing-object-oriented-software.com\/\" href=\"https:\/\/archive.is\/o\/LLhot\/www.growing-object-oriented-software.com\/\">http:\/\/www.growing-object-oriented-software.com\/<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The objectives of Test Driven Development and unit testing are generally misunderstood. The problem is the word \u2018test\u2019, it is much less about testing and much more about specification of requirements, showing your working \u2013 as in maths, and the &hellip; <a href=\"https:\/\/www.davefarley.net\/?p=180\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[4,16],"tags":[],"_links":{"self":[{"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/posts\/180"}],"collection":[{"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=180"}],"version-history":[{"count":1,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/posts\/180\/revisions"}],"predecessor-version":[{"id":181,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=\/wp\/v2\/posts\/180\/revisions\/181"}],"wp:attachment":[{"href":"https:\/\/www.davefarley.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=180"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=180"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.davefarley.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=180"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}