Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: Test Driven Development, for software and for pancakes

by eyepopslikeamosquito (Archbishop)
on Jul 23, 2017 at 21:19 UTC ( [id://1195840]=note: print w/replies, xml ) Need Help??


in reply to Test Driven Development, for software and for pancakes

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.

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

Replies are listed 'Best First'.
Re^2: Test Driven Development, for software and for pancakes
by stevieb (Canon) on Jul 23, 2017 at 21:45 UTC
    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;

      With:

      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.

        Hi there. Unwittingly, you have provided perhaps the perfect counter-example to TDD.

        Similar to how one cannot prove non-existence, one also cannot anticipate the unforeseeable. In other words, tests may guard against regressions, but they cannot save you from bugs.

        In C, bitwise shifts by less than operand width, are allowed. Given 32-bit unsigned int, a shift by 32 invokes undefined behavior. And in particular, on x86 this shift is equivalent to a NOP.

        print bit_mask(32, 0);

        But don't feel too bad about it; similar shift-mask bugs have occurred in security-critical contexts before...

Re^2: Test Driven Development, for software and for pancakes
by talexb (Chancellor) on Jul 24, 2017 at 00:14 UTC

    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.

Re^2: Test Driven Development, for software and for pancakes
by Your Mother (Archbishop) on Jul 23, 2017 at 22:55 UTC

    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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1195840]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2024-04-25 07:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found