Subscribe

Archives

  • Categories

  • License

    Creative Commons License


    All work on this site, excepting software and unless otherwise noted, is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License.




    Pragmatic Test Driven Development

    This summer, I’ve learned an incredible amount as an interning software engineer. Although it has certainly been informative in a technical sense, one of the things that I am growing to appreciate in greater depth is the emphasis on improving the process itself in which I have traditionally programmed. My company, like many other companies which practice agile development principles, stresses the importance of proper coding habits such as code reviews, team transparency, sensible object orientation, Test Driven Development, and so on — pretty much the textbook pragmatic programmer stuff, at least in the ideal.

    Admittedly, none of these have come particularly easy. Each concept introduces an additional learning curveĀ  on top of the hard, technical concepts that are necessary to make satisfactory progress during the day. Add to that the pressure of having a clearly defined task but only a limited interval in which to accomplish it (read: summer employment woes), and the temptation to forgo the ideal in favor of what’s more efficient is even stronger. But we all know that early “efficiency” can lead to a nightmare down the road, in terms of code quality, stability, and maintainability. So wherein lies the balance?

    I’d like to use TDD as an example here, though this problem extends to many other coding practices. It is a practice that has, in my very limited experience, been particularly difficult to convince myself that a) the initial investment pays off; and b) having conceded the first point, to apply the technique effectively. For myself, adaptation of TDD has been rather evolutionary; however not in the sense that I don’t fully understand the importance of testing — rather, in the idea of development being driven by tests that you write. For those that need it, here’s a quick recap of the process:

    1. Write a test that prototypes the functionality you wish to achieve. This forces the developer to think of the overall architecture before any code is written that, had it been written beforehand, could influence the developer’s willingness to make design change decisions.
    2. Run the test. It might (and probably should) fail.
    3. Write the minimum code necessary for the test to pass.
    4. Repeat, refactoring as necessary.

    So… it took me a while to realize the power of testing (and as a side note, how using proper design techniques like MVC and its derivatives make it a much less painful process). I learned this partly from hearing it evangelized so heavily at work, and to some degree the hard way from the first implementation of GCast. Always present is the tension of how to balance “perceived” productivity (i.e., what’s tangible that you produce), and the satisfaction of knowing you did things right.

    I’m convinced that this boils down to three elements: efficiency, quality, and sanity. Sanity because testing is, um, boring.

    But from here it gets tricky: in rewriting most of this code from scratch, I have used tests extensively and so far am tickled at how useful they are in the design process, let alone for their obvious benefits. Yet, the closest I have come so far to true TDD is concurrently designing classes and their tests (and that itself mainly due to the fact that in the case of GCast, the situation is prime for such a mode of development). The reason for this particular method is that I dislike the added formality of writing out the tests and then implementing the classes. If I’ve spent my spare time dreaming up the implementation already, I’d rather code first and then test, code and test, et. al. — in the wrong order, yes, but iterative nonetheless.

    pragmatic-tdd

    Thinking about it, my adaptation of testing has been progressive as my perception of the added benefits has widened: Use tests, waste less scarce time hair-pulling and debugging. Use tests during the design process, and they contribute to better architecture decisions. Begin the process from tests, and it’s the berries. Right?

    Only that’s where I’m stuck in the balancing act.

    Leave a Reply

    Spam Protection by WP-SpamFree