3 ms·
The place where I'm getting stuck is the claim that all programming can be done in steps that small. That just doesn't seem realistic. For instance, how could
by zestyping 7y ago
The place where I'm getting stuck is the claim that all programming can be done in steps that small. That just doesn't seem realistic.
For instance, how could one possibly write a complete test for the behaviour of a regular expression that matches a C comment in less than 2 minutes or even 5 minutes?
The test has to be understandable to other readers, so I would easily spend a few minutes just documenting it carefully so that other readers could convince themselves that the test is complete.
- jdlshore 7y agoYou build it up gradually. For example, let's say we're writing an isComment function (and please excuse any misunderstandings about C comment syntax): Test: it("starts and ends with slash-star", function() { assert.isTrue(isComment("/**/"), "empty comment"); assert.isFalse(isComment(""), "empty string"); assert.isFalse(isComment("foo"), "not a comment"); }); Code: isComment(text) { return text.matches(/\/\*\*\//); // excuse any errors; haven't actually tried this } That's the first TDD loop. Takes less than a minute. But it's obviously incomplete, so now we build it up, step by step. Add another test: it("can contain text", function() { assert.isTrue(isComment("/* foo */")); } Modify the code: isComment(text) { return text.matches(/\/\*.*?\*\//); } That also takes less than a minute. We continue in this way, step by step, handling more and more specific edge cases, until we think we've handled all the cases. For example, the next test might be it("can span multiple lines").
- zestyping 7y agoHmm. Okay, so my incorrect assumption was that the test has to be correct. In this process, it is okay for the test to be incomplete. I've been pondering why this feels so counterintuitive to me. I think it's because, in traditional testing, the test is treated as authoritative. Your test is supposed to be 100% correct, and then you make the code good enough to pass the test. The word "test" suggests a teacher grading an exam: the teacher must be 100% correct. So, I wonder if it is helpful when explaining this approach to explicitly set aside this assumption. The program and the test can both be incomplete. Would it be an overstatement to say it seems like the test and the program have more of a symmetric relationship, rather than an asymmetric one? Thanks for taking the time to explain this!
- jdlshore 7y agoYou're welcome! I'm not sure what you mean by symmetric vs. asymmetric relationships, but if you mean that they're developed in parallel, both as first-class citizens, with each informing the other, and each taking about the same amount of time and code, then yes. Or you could also call it a symbiotic relationship.
- zestyping 7y agoYes, all those things. ("Symbiotic" doesn't quite get at it because it doesn't imply this kind of equality on both sides.) Based on my personal experience and observations of others so far, I think a large fraction of programmers experience unit tests as (a) taking more time to write than the code under test; (b) requiring much more code than the code under test; and (c) relied upon to be correct much more than the code under test. (To be clear, I'm talking about unit tests, not integration or system tests.) In order to understand what you meant by TDD, I needed to unlearn all these things, and I suspect others will need to as well.