4 ms·
> The main failing of TDD is the assumption that you know all of the tests that you will need before you know your software. You know what makes this work for
by yebyen 9y ago
> The main failing of TDD is the assumption that you know all of the tests that you will need before you know your software.
You know what makes this work for me (I am a TDD & BDD dev, and I don't think it's dead) is the fact that you can reorder commits. When I hit a case like this, where the correct code is easier to write than the correct test, I still test it.
I write the test after, then I reorder the commits once the test passes, and make sure it fails predictably in the way you were expecting it to fail. Sometimes you find your test doesn't fail correctly with the codebase you had before the feature was implemented, and then you amend the commit and use rebase or cherry-pick.
Adding BDD to the mix helps a lot too. Sometimes you can write the whole test up-front! Sometimes you can write pseudocode for the test, but you don't have enough information about the details of the implementation to write what you'd call a complete test before the feature is born. Usually you can at least get a vague, english-language description of what the feature is supposed to do.
Then you have, at least, a foundation for your test (which can ultimately be upgraded to an executable proof/regression test), and you have a way to measure how far from the vague, usually simple, plain-english description of the feature you've had to go in order to produce "correctly behaving" code. (And you can amend the behavioral spec to correctly explain the edge cases.)
I am in the habit of telling my team members with less TDD and BDD experience, who are just trying to get the hang of building up a codebase with strong regression tests, that they should always try to write a Cucumber Scenario before they wrote the feature, even if they don't write step definitions until (sometimes a great while) after the feature is done.
I agree that the burn-down chart is not the end goal of TDD, and you should not optimize your process simply around making sure you have a progress chart and a great estimate up-front. Complete coverage of the codebase is more important! And surely there are other things even more important than that.
- charlieflowers 9y ago+1, that's a pretty cool idea >> I write the test after, then I reorder the commits once the test passes, and make sure it fails predictably in the way you were expecting it to fail.
- yebyen 9y agoYes! When you know how to use git, you can honor the spirit and basic practice of TDD without following it to the letter.
- jalfresi 9y agoAgreed! That actually makes it much more feasible to insert into my current workflow!
- TeMPOraL 9y agoLol, that literally sounds like cheating. You write the code first, tests later, and then reorder the commits so that you can say to everyone (colleagues and managers) that you follow TDD... Seriously, why bother reordering the commits?
- yebyen 9y agoIt's really important in TDD to know that your test fails when the code you write for that feature it is missing. If it doesn't fail, that's a false positive. The prescribed pattern is, you write your test (it should be red), you write your code (it should turn green), you commit, push to CI, look at the rest of the tests, make sure none of them turned red... take another look at the code, refactor, commit, push to CI, look at tests again, and then start over on the next feature. (Edit: OK so reordering the commit is not actually the most important part, it's checking out that commit you reordered: with the code for the test, without the matching code for the implementation; and running the test to make sure that it fails until the feature is implemented.) I don't really care if you think it's cheating to reorder the commits, if it gets the job done faster / better in some way. I'm not writing code for a grade, I'm writing an application that I'll need to maintain later. If that feature breaks and that test doesn't turn red, it's been a complete waste of time writing it (and actually has provided negative value, because I will now be less inclined to test that behavior manually, knowing that there is a test and it passes.) That's a false positive that you can easily guard against by reordering the commits before squashing/merging everything back and confirming you see some red where it's expected. (You don't need to reorder if you did actually write the test before writing the code for the feature, but forcing people to do this seems to be the most common cause for complaint about working in TDD. If your developers quit their jobs, then TDD has provided negative value too.) Meanwhile if you have tools for analyzing code coverage, you can make a rule that code coverage must remain above X% to merge work back to master, or that merges must never decrease the percentage of code covered by tests. You don't have to use these rules, but if you're having trouble getting your team members to test their commits, it's not always a bad idea. It has nothing to do with proving things to managers. Code that isn't covered by tests is code that can break silently without anybody noticing. Code that is covered by bad tests is no better than code that is not covered by any test. It can break without anybody noticing. You need to know that your tests work; if you write the code before the test it's just so easy to accidentally write a test that passes anyway, even if the feature was never implemented. Also, because you can. Forget TDD completely, if you don't know how to use rebase and cherry-pick, you need to learn to use them so you can reorder your commits. It makes your history cleaner. Nobody cares what commit you were looking at when you started making your change, that's not useful information. Would you rather have a history that looks like this[left] or this[right]? http://www.bitsnbites.eu/wp-content/uploads/2015/12/1-nonlinear-vs-linear.png http://www.bitsnbites.eu/wp-content/uploads/2015/12/1-nonlin... You may not care now, but I'll bet you care again if you're stuck doing the conflict resolution when it's time to merge!