6 ms·
Could it be that TDD vs. tests-after-code is a highly personal thing? I personally find it easier to write good tests after I've coded something functional. Bef
by geerlingguy 10y ago
Could it be that TDD vs. tests-after-code is a highly personal thing? I personally find it easier to write good tests after I've coded something functional. Before hand, I know one or two fuzzy ideas of what I want to accomplish, but I can't list out the concrete, real-world test scenarios until after I've coded something, poked and prodded it, etc.
But I know some people are wired differently; they'll think a lot more about scenarios first, then code after they have everything accounted for. For them, TDD as a philosophy seems more fitting.
I think the chasm exists between _untested_ code and code that has tests. I've never understood the seemingly-religious zealotry behind TDD as an XP practice. Just like pair programming... if it works for you and your coding style, awesome. But don't force it down my throat or act like it's the One True Path to clean code.
- barbs 10y ago> if it works for you and your coding style, awesome. But don't force it down my throat or act like it's the One True Path to clean code. This applies to so many things in Software Development - text-editors, variable names, plugins, architectures, operating systems...
- jbigelow76 10y ago...life
- dtwhitney 10y agonope - vim
- jpt4 10y agoEd. Edit: ED IS THE STANDARD TEXT EDITOR! [0] [0] https://www.gnu.org/fun/jokes/ed-msg.html https://www.gnu.org/fun/jokes/ed-msg.html
- arcticbull 10y agocat.
- ben-schaaf 10y agobutterflies
- Steeeve 10y agoAhh... good old M-x butterfly
- deleted 10y ago[deleted]
- yitchelle 10y agoWell, things start to get complicated and messy when the team size starts to grow and the technical debt starts to mount. Thats when it needs to goes from hacking to engineering.
- bunderbunder 10y agoFor me it's a highly situation-dependent thing. Sometimes writing tests first helps me think about the high-level design of my code. Other times I've got to try a few things before I have any idea what the code should look like, and writing tests first would just create a lot of extra code churn. I feel that, as time goes on, I'm getting better at anticipating which situation I'm in. I also switch back and forth between the two testing methods even more rapidly.
- madeofpalk 10y agoYes. When doing UI code (with something like React) it's next to impossible to do TDD - you can't know the structure until you actually implement it. If I'm fixing a bug in some sort of non-ui code, I often find TDD to be very helpful. Create a test case that demonstrates that failure, then fix the implementation to make the test pass.
- Udik 10y agoI'm not sure that testing a bug, even before writing the code that fixes it, qualifies as TDD.
- olalonde 10y ago> Sometimes writing tests first helps me think about the high-level design of my code. I'm personally a fan of "readme driven development" (https://news.ycombinator.com/item?id=1627246 https://news.ycombinator.com/item?id=1627246). It's a nice compromise between tons of upfront planning and nothing at all.
- barking 10y agoThat's an interesting discussion and article. I sort of do this already for new features. You really feel the power of it, when after writing a lot of stuff you realise that there's a hitch, rewrite from earlier and shudder at the thought of the mess and wasted time if code had been written. In its final state the document becomes a series of steps that I can check off, which is helpful in a motivational sense. I had thought of involving users in the design of new features via the support forum but I'm afraid of how that might turn out. A readme type document would probably be about as good a way of doing it as any though.
- catnaroek 10y ago> they'll think about scenarios first, then code after they have everything accounted for. I'm one of those people. But I find it hard to believe that a test suite can reflect everything I understand about a problem domain. Focusing too much on unit tests makes it difficult to find the general rules that govern the behavior of a system. Have too few unit tests, and they won't capture all the subtleties and corner cases. Have too many unit tests, and they won't fit in your head.
- Alex3917 10y ago> I think the chasm exists between _untested_ code and code that has tests. IMHO untested code isn't always a bad thing. Anything related to privacy, security, or data integrity should be heavily tested. But beyond that, code should need to earn its tests. (At least in a web startup context.) After all, the core of agility is being able and willing to go in a different direction when something isn't working.
- i__believe 10y agoI think there are a lot of nuance to this statement. After a few years on the start up scene, I believe that if you are using a "duck" typed language your core concepts should be tested without exception (for example rails and django models). The farther you get away from these core concepts, the less your tests need to be there and the more likely that code is to change. In addition, if you are truly in the earliest stages of your startup (pre-revenue/traction) the tests are not needed -- but you have to be _very_ aware that you are making a tradeoff for sheer velocity and you will have to pay the price later on. I've seen too many startups fail to pay the price and it comes back to haunt them and reduces their overall velocity.
- snovv_crash 10y agoIf your code doesn't have tests then you can't refactor because you don't know if you broke something. Getting the right level of tests is important, they should check the interface and not the implementation, otherwise I agree, you can't refactor anything. But if you test your interfaces the same way that real code would use it then it actually makes you more agile, because it gives you the peace of mind to do major changes.
- dasmoth 10y ago"Tests can make refactoring much easier" is a statement I could easily buy into. "If your code doesn't have tests then you can't refactor" is pure dogma and trivial to falsify (go on, refactor some untested code now!). More likely to introduce bugs? Perhaps. But relying on that absolutist statement about refactoring will alienate me every time.
- paulddraper 10y agoTDD vs. test-after-code is a small distinction. 80% of software development is designing correct abstractions/interfaces/APIs. If you have the correct abstractions, everything else is easy by comparison. And both tests and code are fundamentally founded on these early design decisions. So whether I do TDD or tests-after-code, I'm confronted with the 80% first: designing the interfaces (either in writing or mentally). Naturally, I never get this part right at first, and so I wind up refactoring a lot as I go along. ("Build one to throw away", I believe this has been called.) Now in my experience, TDD requires me to refactor more during this process than tests-after-code. But suit yourself. Changing the order within the last 20% won't be earth-shattering one way or the other.
- methyl 10y ago> 80% of software development is designing correct abstractions/interfaces/APIs Not sure if that claim is wrong or not, but I will state it anyway. If you write in TDD manner and you decide to change the API/abstraction a little bit because of something you didn't think of, you will have to correct both tests and the code. When you do test-after-code it's much easier (IMO) to hit correct abstractions and interfaces because you are working on a living thing, not some artificial test cases you have to figure out. Then you write tests to ensure those abstractions are respected and in working order. TDD people, please correct me if I'm wrong. EDIT: disclaimer: I'm a front-end developer working mostly in React and Redux
- embwbam 10y agoThis is why designing the interface in a language with a powerful type system provides the same quoted benefit of TDD. It helps you think about the interface before you move to implementation. In my experience, using a type system to do this requires much less effort and refactoring.
- paulddraper 10y agoI am a big fan of "testing via types". Unit tests can demonstrate that my code is correct; it can say nothing about how my code is used by others. In contrast, a type system can extend those protections downstream. (Yes, yes, unless you go way off the deep end of dependent types, you still need tests. But a powerful type system can systemically prevent a huge number of very common bugs.)
- shubhamjain 10y ago> But don't force it down my throat or act like it's the One True Path to clean code. When I was a programming beginner and started learning about TDD, I was always thinking how soon to start using it because everyone says it's such a good idea. If you would search anything about it, you'd rarely find a resource not marvelling at its surprising benefits (at least, that is how it was few years back). Granted, it may have its merits but is it really a good idea for everything? No way! One of the anti-patterns I have seen in programming world is how everyone jumps on adopting / advocating a 'good' practice without understanding how it fits the project. I wrote about this a while back[1]. Cue in — git flow, TDD, not using goto, DOM Parser instead of RegEx. [1]: https://shubhamjain.co/2015/10/26/imperfect-best-practices/ https://shubhamjain.co/2015/10/26/imperfect-best-practices/
- madeofpalk 10y agoReminds me of a comment by Harry Roberts on CSS methodologies https://twitter.com/csswizardry/status/539726989159301121 https://twitter.com/csswizardry/status/539726989159301121 Modularity, DRY, SRP, etc. is never a goal, *it’s a trait*. [...] understand that they’re approaches and not achievements.
- zby 10y agoFor me it also depends on the task - I never do a strict TDD - but often I like to start with some tests. Sometimes it is hard to write the tests, but it is easy to see if your code works - sometimes it is easy to write the tests, but not the code. I would call it 'do first what is easier'. But it is important to write the tests quickly after you wrote the piece of code - so that you don't forget something.
- wirrbel 10y agoWhen I first learned about TDD I thought the same (order of test and implementation does not matter that much). Yet when you do the TDD steps * write a failing test (RED) * implement minimal functionality so all tests pass (GREEN) * REFACTOR and overcome the initial revulsion you will get a ton of benefits that you didn't know existed. I'll first give a few that are more on the code quality side * You have a complete test suite, without redundant tests * Tests are usually not that mock-focused [] as the implementation-after-test didn't introduce random roadblockers for testing. tests do assert the relevant properties (tests-later code bases often have code bases that don't assert much or properties you don't care about). * When you write your test first, you basically write a small example how it feels like to use the API you have in mind for solving your problem. This drastically improves quality. Some non-technical benefits of TDD * I find TDD helps me tackle bigger code-pieces where I just don't know how to start implementing. * TDD is programming gamification. You are rewarded with regular, small successes of having added another test and made it green. So whenever you ask yourself: OMG, have I made any progress in the last 3 days, you can actually tell: Yes, I added 15 tests and made them pass - I objectively got closer to implementing that feature. * Not an issue where I work, but have often heard about this from other places: If tests are there first, no one can tell you to not spend so much time on writing tests. TDD-style is protecting your boss from shipping that car without having the brakes checked. * The same line: TDD gives explicit room for refactoring. [*] obviously one cannot avoid mocking especially when dealing with resources external to your code base, yet I have hardly seen TDD-originated tests that mocked
- nhaehnle 10y ago> I find TDD helps me tackle bigger code-pieces where I just don't know how to start implementing. This made me think. There are many axes of software development, and aside from TDD/non-TDD axis, there's also the bottom-up vs. top-down axis. By top-down, I mean you start with a skeleton that provides an interface to the outside world, and the fill in the implementation details. Bottom-up, on the other hand, means you first write some routine that you know will be vital in some form or another, but without immediately seeing how it will be hooked into the interface to the outside world. Top-down has the advantage that you can have something runnable quickly, and it seems to me that TDD requires top-down development. But somehow, there have been times when I was working on a piece of code and it just flowed more naturally in a bottom-up manner. It has happened that I went for a day (and very rarely longer) working on tricky algorithmic code before I even tried to compile it for the first time. This is definitely something that I try to avoid when I can, it's just that sometimes it works out that way. And it is totally incompatible with the TDD way of doing things. How often this happens surely depends on the type of project you're working on. As usual with these things, it seems like TDD can be a useful inspiration, but it shouldn't be taken as dogma.
- mcv 10y agoTo me, it depends on the problem. With some problems, I'm not sure yet how to implement it, but I do already know what the result should look like. That's an excellent case for TDD. You get to work on the problem, refine your ideas about it, and you start with the part you already know: the results. If you have no idea what the results should look like, then TDD is pointless.
- regularfry 10y agoThe "lightbulb" moment for me was doing what Kent Beck suggests, and writing down the list of tests I "knew" I needed to write, before writing any tests. That's a very similar step to diving into writing the code first, "knowing" what it ought to look like, and the ideas feeding into either step would be the same. Writing a list of tests first is quicker, though, and working through the list, updating it as I learn more, tells me that my initial ideas were wrong often enough that I'm almost convinced that the true secret of TDD isn't the tests at all. It's that checklist, and the purely mechanical process of working through it, checking them off one-by-one and fixing it up as I go along. To relate this to your situation, I often find that I'll only get started with a fairly fuzzy idea, and the checklist will be short. I can still expand it as I go, knowing that I'm working on as solid foundations as I can given the constraints. I think there's a danger in writing off practices like TDD with "if it works for you..." because it avoids discussion of why it works for some people and not others. That in turn gives people license to ignore it simply because it's unfamiliar, and the brain doesn't like unfamiliar things by default. That's a shame, because for some of those people they'll be stuck in local optima, writing off the one thing which could break them out of it.
- crdoconnor 10y ago>Could it be that TDD vs. tests-after-code is a highly personal thing? I personally find it easier to write good tests after I've coded something functional. Before hand, I know one or two fuzzy ideas of what I want to accomplish, but I can't list out the concrete, real-world test scenarios until after I've coded something, poked and prodded it, etc. I generally find it better to engage in "top-down" development - specification->tests->high level code->low level code as it's cheaper to fix mistakes at higher levels first. If I'm doing purely experimental code though - where I'm not sure of what I even want or what the output should be, tests are just a waste of time. It also loses its effectiveness the more declarative the code is. If I'm essentially tweaking configuration or HTML there's no point.