Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Test Driven Development, for software and for pancakes

by talexb (Chancellor)
on Jul 23, 2017 at 15:16 UTC ( #1195817=perlmeditation: print w/replies, xml ) Need Help??

It's Sunday morning in Toronto, so that means pancakes for breakfast.

I use the same recipe from the Joy of Cooking that I've used for the last fifteen years or so, which starts with me heating up my two cast iron pans to a 4.5 setting. After making the batter, I make just one pancake in the middle of each pan, and check that they cook at the right speed to confirm I have the correct pan temperature. And I taste the finished pancake, to make sure I haven't messed up the recipe. (Yes, it's possible to forget a crucial ingredient when following a well-worn recipe -- it's amazing what forgetting salt does do a dish.)

I make pancakes four to a pan, so they're 'silver dollar' pancakes, not more than three inches across. I monitor the colour and the speed at which they're cooking as I go, adjusting the heat if necessary. Finished pancakes go into a covered dish to stay warm.

I believe I'm a careful cook, and I'm also a careful developer. That means test early, and test often. You want no surprises when it's time to dish up the goods to your family (pancakes) or your customers (software). Dreaming up new dishes or new applications it's important to be creative, to try new approaches. Cooking or writing software, you have to be methodical, thoughtful, and meticulous.

I consider myself very lucky to have gone to a really good university, but what I studied (Systems Design Engineering) bears only a tangential relationship to the work I do now. It was actually really good training at reading/comprehension, time management, mental gymnastics, and getting the job done. As long as another program had the same goals, I think pretty much any degree or diploma would have done. An Engineering degree from Waterloo just helped me get my foot in the door that much easier.

Conclusion? Do your development with tests, right from the start. You'll thank yourself, again and again. And it makes for good pancakes. ;)

Alex / talexb / Toronto

Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

  • Comment on Test Driven Development, for software and for pancakes

Replies are listed 'Best First'.
Re: Test Driven Development, for software and for pancakes
by eyepopslikeamosquito (Archbishop) on Jul 23, 2017 at 21:19 UTC

    From Effective Automated Testing, some benefits of using Test Driven Development (TDD):

    • Improved interfaces and design. Especially beneficial when writing new code. Writing a test first forces you to focus on interface - from the point of view of the user. Hard to test code is often hard to use. Simpler interfaces are easier to test. Functions that are encapsulated and easy to test are easy to reuse. Components that are easy to mock are usually more flexible/extensible. Testing components in isolation ensures they can be understood in isolation and promotes low coupling/high cohesion. Implementing only what is required to pass your tests may help prevent over-engineering.
    • Easier Maintenance. Regression tests are a safety net when making bug fixes. No tested component can break accidentally. No fixed bugs can recur. Essential when refactoring.
    • Improved Technical Documentation. Well-written tests are a precise, up-to-date form of technical documentation. Especially beneficial to new developers familiarising themselves with a codebase.
    • Debugging. Spend less time in crack-pipe debugging sessions.
    • Automation. Easy to test code is easy to script.
    • Improved Reliability and Security. How does the code handle bad input?
    • Easier to verify the component with memory checking and other tools (e.g. valgrind).
    • Improved Estimation. You've finished when all your tests pass. Your true rate of progress is more visible to others.
    • Improved Bug Reports. When a bug comes in, write a new test for it and refer to the test from the bug report.
    • Improved test coverage. If tests aren't written early, they tend never to get written. Without the discipline of TDD, developers tend to move on to the next task before completing the tests for the current one.
    • Psychological. Instant and positive feedback; especially important during long development projects.
    • Reduce time spent in System Testing. The cost of investigating (and establishing the root cause of) a test failure is much lower for unit tests than for complex black box system tests. Compared to end-to-end tests, unit tests are: fast, reliable, isolate failures (easy to find root cause of failure). See also Test Pyramid.

    For me, the first point above is the most important: TDD improves interfaces and design.

    Of course, TDD is not a silver bullet. I've also experienced (and dislike) the religious fervour surrounding TDD. I've also experienced many large, tangled, legacy code bases where it's unreasonably difficult to test components in isolation. All these horrible old code bases were not developed with TDD. Would using TDD have helped? Probably. But IMHO the single most important factor in code quality is the skill and taste of the designers - not whether TDD was used.

    Update: Added "cost of investigating lower for unit tests" bullet point. Added over-engineering comment to first bullet point.

      For me, the first point above is the most important: TDD improves interfaces and design.

      I agree with this.

      What I find disconcerting is that many when they hear TDD and dismiss it never get around to writing proper tests at all. To me, that's an absolute shame (s/ (shame)/insert_bad_word $1/). Not following TDD != don't write any tests.

      For example, I know of a company with a very large software suite, and it pisses me off to no end that bugs are frequently found that should have easily been caught if even a few basic tests had of been written. I mean, you have a feature in your software for many years then suddenly it breaks when one is doing a deployment? Give me a break.

      I do TDD most of the time, but not all of the time. That doesn't mean one shouldn't write tests at all... it just means its much more unlikely that anyone will get around to it going forward. Personally, 100% coverage is my objective, from several different angles. Either specific existing tests (possibly having been updated or added to) are run before a commit, or if required the whole suite passes first.

      Whether one does TDD or not, never neglect a good quality test suite. It doesn't matter if the project is late. On a complex project, would you rather have data inconsistencies in client data down the road because of your neglect, or have the project behind a couple weeks up front because you're validating your code before or as you write it?

      update: This kind of sounded like I'm reflecting on you, eyepopslikeamosquito, but it surely wasn't. It's a global thing ;)

        I am going to provide a real-world example of why tests are very important, based on a situation I ran into today.

        I wanted to make some changes to my XS-based Bit::Manip distribution. One of my goals was to replace calls to stdint.h's pow() function with bit shift operations instead, to remove the reliance on the external library.

        With my full test suite in place, I could freely replace things like:

        #define MULT 2 return ((int)pow(MULT, bits) - 1) << lsb;


        return ((1 << bits) - 1) << lsb;

        ...and not have to worry about a thing, because all I had to do was make the change, run the tests, and on fail, go back to the math. Once all tests passed, I knew I was good.

        Without a test suite, how would I ever know if I'm 100% accurate in my modification? I wouldn't be. Because all of my subs are covered entirely, I know that one change there didn't break anything within the sub its defined in, nor does the change break anything far away either.

      Interesting .. the last time I used TDD for a big project was for an API that I was developing, and the key (for me, anyway) was that the interface had to be rock-solid -- so, while doing that project, your first point was the most important one to me. The second point is the next most important for me .. having a safety net for when I update something over here .. which ends up breaking something over there. How the heck did that happen? Ah .. git diff to the rescue. How did I miss that? OK, one more test. :)

      Your last point, about psychological backup .. it's wonderful to spend some time on the code, and get into the rhythm of running the tests, getting a green result, and doing a commit. The module grows before your eyes, and everything is completely tested.

      Great post, thanks so much!

      Alex / talexb / Toronto

      Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      I have found Improved interfaces and design. Especially beneficial when writing new code… completely, shockingly true as well. It is an assumption and sloppy thinking disruptor. It alone comes close to justifying all the costs.

Re: Test Driven Development, for software and for pancakes
by BrowserUk (Patriarch) on Jul 23, 2017 at 15:52 UTC

      Interesting -- however, just because this headline claims that it failed to become mainstream, doesn't mean it's not a useful methodology.

      Let's look at the list on this page.

      • TDD is Expensive / There may be an additional time cost, but I believe there's also an increase in the quality of the final product.
      • TDD Will Retard Your Project Launch / This depends; if you have a hard date for your launch, then TDD may cause you to launch with a slimmer product.
      • You Will Change Your Projects and Old Tests Become Waste / Perhaps some top-level tests will be invalidated as the project changes, but I would imagine that the lower level stuff code and tests would continue to be useful.
      • Testing the Means is a lot more Work Than Testing the Outcomes / I would rather have decent tests all the way up the food chain, than having something at the end that says Go/No Go with no idea where the issue might lie.
      • Extensive Testing is Boring / Sure, sometimes developing software is boring. However, if you bounce between writing tests and code, I don't imagine that would be boring for long. Writing documentation for two weeks straight is something I did recently that was a little boring -- but necessary -- for the contract I'm on right now. I wouldn't be happy if I were doing it full-time, but for me it's come after four months of development. So I'm OK with that balance.
      • Many TDD Preachers Do Not Use it Most of the Time But Do Not Admit it / This sounds anecdotal to me -- to each their own.
      • Many Reputed Developers Do Not Use TDD at all / Another anecdotal claim. The reputed developers may have good enough levels of craftmanship that they don't need tests. I'm happy to use tests myself when I develop software, as it gives me confidence in my code.
      And it's good to also read in this article that TTD is not dead. I think it's still a valuable development methodology.

      Everything Has to be an Object, however .. ugh.

      Alex / talexb / Toronto

      Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      Thanks for sharing the cool link. I never really used TDD but anyway - some thoughts: Let's say you want to write a chess engine. You start with the board representation. This is quite tricky. Robert Hyatt needed years to understand how to accomplish this. Nowadays these techniques are less or more well know, but you still need a mistakeless representation. Isn't something like this a use case where you are lost without TDD?

      My 2˘ about the other manias:

      1. Everything Has to be an Object: No
      2. Forcing Yourself to Use as Many Design Patterns As Possible: No
      3. Argue Over Code Formatting Styles: Yes. Always in style
      4. Programming has to be Beautiful: Yes. Even the dishes i cook are so (but perhaps my programs are not)
      5. Hire More Developers to do Pair Programming: Yes. I did just a handful of jobs using it but this were my best projects ever

      Best regards, Karl

      «The Crux of the Biscuit is the Apostrophe»

      perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

        but you still need a mistakeless representation. Isn't something like this a use case where you are lost without TDD?

        I really fail to see why you think that particular example is amenable to TDD, or unamenable to any of the other non-test-driven development methodologies?

        Nor why a game's internal data representation should be any more "mistakeless" than that of an automated drug dispenser, or a traffic control system, or fingerprint matching algorithm?

        But as you've chosen that example, here's a little thought experiment for you. You are charged with writing a replacement board representation: write your first test.

        Chances are, you simply haven't a clue where to start; and you'd defend that by saying that you need a specification.

        But how do you write a specification for something you have no idea how to write? So maybe you read this (if you haven't already). So, now you know a little about the possible representations and requirement of them, so write that first test. Once again you (probably) cannot.

        One thing I can guarantee, Robert Hyatt didn't use TDD back in 1968, and -- having read a few of his papers -- I doubt that, even given his 50 years of experience and knowledge, that he used it when they switched from rotated bitboards to magic moves circa 2004.

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
        In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
Re: Test Driven Development, for software and for pancakes
by zentara (Archbishop) on Jul 24, 2017 at 13:52 UTC
    me heating up my two cast iron pans

    I like to use a Scanpan myself, and fried rice. :-)

    I'm a total amateur compared to you fellows, but I do find when I write my code, for the first draft, I almost always print out arrays and variables after everytime I use them. I almost always get things wrong the first time thru, so my method is very helpful to me.

    It's my guess is that the reason TDD failed is that the Test that you didn't account for, is the one that causes the bug, ( if any).

    What is more worring to me is the security vulnerabilities which Perl5 is susceptible to.

    For instance, could a normal or guest user on your machine, with access to Perl scripts, cause a buffer-overflow of some sort, and gain root access? I'm sure the NSA would pay for that information. :-)

    How safe is Perl out there in the wild? Are systems being hacked thru Perl? As far as know, Perl has been very safe in my limited use. I guess security is the number one test.

    I'm not really a human, but I play one on earth. ..... an animated JAPH
        Are systems being hacked thru Perl?

      To me, Perl is just a big lever, allowing me to make use of the underlying operating system to get things done efficiently. As far as vulnerabilities go, I see two possible vectors, 1. through Perl itself, and 2. through the underlying operating system.

      Perl is open source -- so any dark corners or clever secrets would probably have been found and patched/removed long ago. It's under constant use in this day and age, so any security weakness would be found, discussed, patched and back-ported.

      It's the underlying operating system's responsibility to make it impossible for any elevation of privileges or any unauthorized access. Again, any potential weaknesses are (should be) reported as soon as they're found, and updates made.

      That's not to say that Perl is 100% safe (for some definition of 'safe'); you'd have to consult with a computer security expert on that. I'm not that guy. :)

      Alex / talexb / Toronto

      Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

        I offer 3. through the client or transport layer if mishandled at the code level. There have been some really esoteric bugs like the UTF-7 XSS exploit in older IEs. Not a lot of devs know/knew that even doing something as seemly harmless, and rampantly common, as character encoding improperly could be a security hole.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1195817]
Approved by stevieb
Front-paged by ww
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2023-09-30 16:14 GMT
Find Nodes?
    Voting Booth?

    No recent polls found