7 ms·
I've never heard TDD being that you write all of your tests up front, before you've written any code. I've always heard it as: When you're writing a class/unit,
by s73ver 9y ago
I've never heard TDD being that you write all of your tests up front, before you've written any code. I've always heard it as: When you're writing a class/unit, you write a few tests for what that unit is going to do. You then make those tests pass. You add some more tests, make those pass, and so on and so on.
- taeric 9y agoYou are still writing the tests first, with no real learning from them other than "they are now passing." It is thought this is like engineering. You design an experiment and then pass it. However, that is not how experiments work. You design an experiment, and then you collect results from it. These may be enough to indicate that you are doing something right/wrong. They are intended, though, to be directional learnings. Not decisions in and of themselves. So, I probably described something in more of a strawman fashion than I had meant. I don't think that really changes my thoughts here, though.
- sb8244 9y agoYou can throw away the test if you don't find value in it. This can be very useful for fleshing out an idea.
- taeric 9y agoBut this advice should be extended further. Always be willing to throw away the code and the tests. Take the learning. Be ware, though, that you are not throwing your customers for a bad ride. As soon as you have customers, it is nigh impossible to throw away the code without neglecting them. And they are your ultimate responsibility. Not the code.
- sb8244 9y agoExactly right, it can be very hard to make changes (even the right changes) once it's in customer hands. Sometimes it is easy, sometimes it is not. However, it's always easy to throw out code that isn't yet committed.
- nostrademons 9y agoYou're often learning the optimal API as well. I've had several experiences where I write a library, write some tests for it, and then realize that the library's API is inconvenient in ways X, Y, and Z, and that I could have a much simpler API by moving a few tokens around. When I write the tests first, I tend to get a fairly usable API the first time around, because I'm designing it in response to real client code. (This all depends on having a clear enough idea of what the library needs to do that I can write realistic test code...I've also had the experience where I write the tests, write the library, and then find that the real system has a "hidden" requirement that isn't captured by the tests and requires a very different way of interacting with the library.)
- taeric 9y agoSo, this is a slightly different mantra. Working backwards from the customer is an important thing. And if you know that customers will be using your product programmatically, then yes, building the API first is important. But note, in that world, you aren't necessarily building tests of your software. You are building specifications for your API. I can see how these might be seen as similar. And for large portions of your code, they can be. However, for the vast majority of your code, it exists to help out other parts of your code. Not to be used as a library/framework by others.
- mayoff 9y agoIt’s funny that you say “I'm designing it in response to real client code.“ To me, a test is not real client code. Real client code is code that calls the API in service of the user. E.g. the real client code for the Twitter API is in your preferred Twitter client, not in the tests that run against the Twitter API.
- nostrademons 9y agoThat's the caveat I mention in my second paragraph. But yes, if the tests are well-designed and built with actual real-world experience, I do treat them like real client code. Someone looking to use the library should be able to read the unit tests and have a pretty good idea what code they need to write and what pitfalls they'll encounter. And when the library is redesigned or refactored, the tests are first-class citizens; they aren't mindlessly updated to fit the new code, they're considered alongside other client code as something that may or may not have to change but ideally wouldn't.
- ericgunnerson 9y agoAuthor here... This discussion on what happens - or doesn't happen - after the tests are passing is precisely the point of the article. The idea of TDD is that every test you look at the existing code and improve it. The majority of developers I've seen trying TDD do this with small code but do not with significant codebases, and you end without the benefits.
- robotresearcher 9y ago> with no real learning from them other than "they are now passing." You don't learn much the moment the test passes. But designing and writing the test requires understanding the requirements in detail, which is often a learning process.
- PretzelFisch 9y agoIf you wrote the test after you coded your unit,you would not know why it passed. It could be a false positive. When you move on to the next part of the requirement, you can ensure all your tests still pass. Sometimes the tests give you the starting point of the problem, "what is the simplest way to get result x" with a way to rapidly get feed back that all the requirements are ment as the structure takes form and you refactor all the code.
- bluGill 9y agoI sometimes write tests that I know will pass. A common example is when the previous version of an algorithm had a bug in some special case. My new algorithm written from scratch doesn't have that special case at all so there is no test for it. However because the last version had that bug there is a lot of fear so I will write a test that it works even though it is inherent in my new algorithm that it works and at no point in the TDD cycle is that test the correct one to write.
- Sir_Substance 9y ago>I've never heard TDD being that you write all of your tests up front, before you've written any code. That's interesting, because as a non-TDD practitioner who occasionally gets it evangelized to me, that's certainly how I was told to go about it by multiple people. Possibly TDD has a marketing problem?
- goldenkey 9y agoTDD doesn't have a marketing problem -- all these sponsored wigs evangelized it for the last 20 years, there's at least a dozen at every conference, many getting paid thousands to give their gritty speeches. TDD as these maggots explained it is: write your tests first, write your code, make sure the tests pass, rinse, repeat.
- logfromblammo 9y agoTDD is writing code to automatically validate that a specification/requirement has been met, before writing the code that meets the requirement. It does one requirement at a time. You might add a specification that the code has to create a list of strings from a data set. You write a test that takes a data set as input and checks the output to see if it is the expected result. This fails, because the code hasn't been written yet. Then you write the simplest function possible to make the test pass. Once it passes, you check to see if anything can be refactored. You can refactor as much or as little as you like, provided that all the tests still pass. Once you're satisfied, you write another test for another requirement. It's like a spinning ratchet wheel, where the test suite is the pawl. It keeps you from backsliding, but you can't spin too fast, or it flies off and won't engage with the wheel. Turn-click-turn-click-turn-click. Writing all your tests up front is one of the worst ideas I have ever heard.
- kevwil 9y agoWow, if that's how people are describing it, no wonder it's seen negatively. That seems very waterfall-ish and horrible. Thankfully that's not TDD as originally intended.
- thaumasiotes 9y agoIt's a very common way to evangelize TDD. Ruby Koans is a tutorial entirely based on that principle.
- ZoFreX 9y agoBut Ruby Koans is a tutorial on Ruby, not on TDD.
- sb8244 9y agoYou are correct. Not only this, but it's a blatant violation of TDD. TDD is having a single test go red->green, not a suite.
- tomnipotent 9y agoExactly this. It's Red, Green, Refactor. 1. Write test; build fails because code under test DOESN'T EXIST 2. Write the least amount of code needed for the test to pass 3. Refactor & repeat process ad infinitum The Wikipedia entry for TDD also states this explicitly [0] This is a differentiating feature of test-driven development versus writing unit tests after the code is written: it makes the developer focus on the requirements before writing the code, a subtle but important difference. [0] https://en.wikipedia.org/wiki/Test-driven_development#Test-driven_development_cycle https://en.wikipedia.org/wiki/Test-driven_development#Test-d...
- andybak 9y ago> I've never heard TDD being that you write all of your tests up front, before you've written any code. That's the only way I've ever heard it described. I thought that's why it's called "Test Driven"
- skookum 9y agoCan you provide a reference? I'm not a big proponent of TDD but have read up on it and experimented with it some, and none of the TDD literature I've read suggests writing all the tests up front. Virtually all the mainstream TDD literature and talks advocate for the "write a test, make it pass, lather, rinse, repeat" model of development.
- taeric 9y agoI think this is a case of two ways to hear "write all the tests first." If you read that as "write every single one of your tests, then write the code", then you see it as a strawman and not the point of TDD. If you read that as "before you write any specific line of code, you write the test for it first", then you are likely to see that as the same as TDD. I intended the second reading. I can see how both are accurate ways to read it, though. Apologies for the confusion.
- andybak 9y agoAh. Exactly the misunderstanding I was labouring under. Turns out we are all in agreement after all.
- deleted 9y ago[deleted]
- s73ver 9y agoI mean before you've written any code at all. Like, you have to have the tests for all units created before you start writing the code for any unit. That's what the person I responded to made it sound like. Writing tests before you work on the unit you're working on shouldn't be a problem because you should know what that unit is supposed to do. If you don't, then it doesn't matter if you do TDD, Agile, BDD, or whatever. You're not going to be able to do it right. Go have a conversation with someone to find out what that is supposed to do.