Monday, February 22, 2010

Second try: stupdendous Aha re unit tests

I have gotten zero responses to my 42 post:

I should have remembered that nobody reads long posts. So here is the Aha in a nutshell:

Unit tests are not just for testing! They are the master tool for programming, design, testing, refactoring, studying code, or anything else.

Think of a unit test as the root of a tree. The tree represents any task (including designs).

The unit test formalizes, automates and protects the task or design.

Expanding the notion of unit tests this way is a stupendous Aha. It has totally altered how I approach my work.

For details, read the long post. Print it out, including the lengthy "reply". Study it. Respond. Please.

Edward

P.S. I expect three possible responses to this post, and the longer post:

1. Yeah, I knew that. Welcome to the club of hugely effective programmers.

2. Wow! I didn't know that. This is going to change my life.

3. Huh? I have no idea what you are talking about. Can you do a better job of explaining your ideas?

EKR

5 comments:

  1. can I mix responses?
    Yeah, I knew that. When I will start doing it this is going to change my life.

    (I had read the previous one, just nothing more to tell ^^)

    ReplyDelete
  2. There is more to testing than just unit tests of course. :) I agree that they are most useful, esp. in the contexts you mentioned.

    Of course testing itself brings some overhead to development. It's possible that the tests are not valid for instance. Who tests the tests? (This observation probably leads to some thoughts about standardizing tests, ideas of abstraction etc.)

    I'm still a bit ambivalent between the relationship between testing and design. To me they feel like separate tasks. Consider the roles of architect and builder in real life. The architect sets the constraints for the builder and then it's up to him to stay within them. To expand the metaphor further, consider tests as scaffolding... :)

    ReplyDelete
  3. Hi Edward,

    I'm more in the first camp, in that tests for several years have been the most effective way for me to specify the intended behaviour of software I am building. "Executable requirements" is something along the lines of how I think of them.

    However, I think our modern languages, libraries, and tools still have a ways to go before they properly support this paradigm. As you note in the more recent post, the cruft of inheriting from TestCase and other test-specific tools can actually inhibit this usage of tests. I look forward to a language that incorporates testing (including mock objects) directly into the syntax.

    Now, having said that, I can assure you my ideas about this aren't particularly novel, and derive from a great many smarter and more prolific developers (including yourself). In this regard, "Mock roles not objects" (www.jmock.org/oopsla2004.pdf) has been quite influential.

    ReplyDelete
  4. I'm not fitting into any of your three given replies. I disagree with you, both that unit tests are any sort of root of any sort of tree, and that these tests would somehow automate and define a task or solution in any grand way.

    At the end of the day, whether or not your WSGI application says "Hello world" is what matters, not if the unit tests are telling you it should be doing so. (Although that's always a good preflight test.)

    ReplyDelete
  5. Agreed with the previous commenter, unit tests are by no means a silver bullet:
    - They are not sufficient for proving correctness. If you can think of all possible scenarios and edge cases to test for, then you can think how to handle them in the code in the first place; and vice versa, if you have bugs in your code, what makes you think your unit test code will be flawless ?
    - They are a chore to write, especially when done by the same programmer who wrote the code to be tested (that's the typical case). It often feels like writing the same code twice since you have intimate knowledge of the code's internals.
    - They are a pain to maintain as the API changes. Continuous integration helps catching code-test mismatches as soon as they happen, otherwise when a test fails it might well be the case that the current code is correct and the test is not.
    - It's a low priority task compared to adding features or fixing known bugs; AKA "at the end of the day, ship the fucking thing!" (http://www.joelonsoftware.com/items/2009/09/23.html)

    ReplyDelete