7 ms·
TDD is testing in production in disguise. After all, bugs are unexpected and you can’t write tests for a bug you don’t expect. Then the bug crops up in producti
by wonnage 1y ago
TDD is testing in production in disguise. After all, bugs are unexpected and you can’t write tests for a bug you don’t expect. Then the bug crops up in production and you update the test suite.
- embedding-shape 1y agoTDD has always been about two things for me; be able to move forward faster because I have something easy to execute that compares it against the known wanted state, and in the future preventing unwanted regressions. I'm not sure I've ever thought of unit testing as "prevent potential future bugs", mostly up front design prevents that, or I'd use property testing, but neither of those are inside the whole "write test then write code" flow.
- Retric 1y agoThe intended workflow of TDD is to write a set of tests before some code. The only reason that makes sense conceptually is to prevent possible future bugs from going undetected. Put another way if your TDD always pass then there’s no point in writing them, and there’s no known bugs before you have any code. So discovering future bugs that didn’t exist when you’re writing those tests is the point.
- black_knight 1y agoI don’t really understand how to write tests before the code… When I write code, the hard part is writing the code which establishes the language to solve the problem in, which is the same language the tests will be written in. Also, once I have written the code I have a much better understanding as the problem, and I am in a way better position to write the correct tests.
- numpy-thagoras 1y agoYou write the requirements, you write the spec, etc. before you write the code. You then determine what are the inputs / outputs that you're taking for each function / method / class / etc. You also determine what these functions / methods / classes / etc. compute within their blocks. Now you have that on paper and have it planned out, so you write tests first for valid / invalid values, edge cases, etc. There are workflows that work for this, but nowadays I automate a lot of test creation. It's a lot easier to hack a few iterations first, play with it, then when I have my desired behaviour I write some tests. Gradually you just write tests first, you may even keep a repo somewhere for tests you might use again for common patterns.
- pjmlp 1y agoI want to have a CUDA based shader that decays the colours of a deformable mesh, based on texture data fetched via Perlin noise, it also has to have a wow look as per designer requirements. Quite curious about the TDD approach to that, espcially taking into account the religious "no code without broken tests" mantra.
- CuriouslyC 1y agoBreak it down into its independent steps, you're not trying to write an integration test out of the gate. Color decay code, perlin noise, etc. Get all the sub-parts of the problem mapped out and tested. Once you've got unit tests and built what you think you need, write integration/e2e tests and try to get those green as well. As you integrate you'll probably also run into more bugs, make sure you add regression tests for those and fix them as you're working.
- pjmlp 1y agoGot to figure that TDD for the UX wow designer part.
- sarchertech 1y agoTDD is terrible for anything where the hard part is the subjective look and feel.
- MoreQARespect 1y ago1. Write test that generates an artefact (e.g. picture) where you can check look and feel (red). 2. Write code that makes it look right, running the test and checking that picture periodically. When it looks right, lock in the artefact which should now be checked against the actual picture (green, if it matches). 3. Refactor. The only criticism ive heard of this is that it doesnt fit some people's conceptions of what they think TDD "ought to be" (i.e. some bullshit with a low level unit test).
- Retric 1y agoTDD fits better when you use a bottom up style of coding. For a simple example, FuzzBuzz as a loop that has some if statements inside is not so easy to test. Instead break it in half so you have a function that does the fiddly bits and a loop that just contains “output += MakeFizzBizzLineForNumeber(X);” Now it’s easy to come up tests for likely mistakes and conceptually you’re working with two simpler problems with clear boundaries between them. In a slightly different context you might have a function that decides which kind of account to create based on some criteria which then returns the account type rather than creating the account. That function’s logic is then testable by passing in some parameters and then looking at the type of account returned without actually creating any accounts. Getting good at this requires looking at programs in a more abstract way, but a secondary benefit is rather easy to maintain code at the cost of a little bookkeeping. Just don’t go overboard, the value is breaking out bits that are likely to contain bugs at some point where abstraction for abstraction’s sake is just wasted effort.
- leptons 1y agoThat's great for rote work, simple CRUD, and other things where you already know how the code should work so you can write a test first. Not all programming works well that way. I often have a goal I want to achieve, but no clue exactly how to get there at first. It takes quite a lot of experimentation, iteration and refinement before I have anything worth testing - and I've been programming 40+ years, so it's not because I don't know what I'm doing.
- lisbbb 1y agoI don't want to insult you, but I had to re-program myself in order to accept TDD and newer processes and there are a lot of systems out there that weren't written with testability in mind and are very difficult to deal with as a result. You are describing a prototype-until-you-reach-done type of approach, which is how we ended up with so much untestable code. My take is that you do a PoC, then throw it out and write the real application. "Build one to throw away" as Brooks said back in 1975. I get where you're coming from, because I'm about a decade behind you, but resisting change is not a good look. I feel the same way about all this vibe coding and junk--don't really think it's a good idea, but there it is. Get used to being wrong about everything.
- Ekaros 1y agoI am not really sure if TDD often is compatible with modern agile development. It lends well to more waterfall style. Or clearly defined systems. If you can design fully what your system does before starting it is more reasonable. And often that means going down to level of are inputs and states. Think more of something like control systems for say mobile networks or planes or factory control. You could design whole operation and all states that should happen or could happen before single line of code.
- lisbbb 1y agoThere is no relationship between agile/waterfall and TDD. Same as there is no relationship to pair programming and agile/waterfall, either.
- Retric 1y agoTDD operates at a vastly smaller scale. You don’t write every single test for the entire project before writing a single line of code. Write some tests for a non trivial function before creating the function and the entire cycle might take as little as 20 minutes.
- lisbbb 1y agoIt's as matter of practice. The major problem is that business folks don't even know how to produce a testable spec, they just give you some vague idea about what it is they want and you're supposed to produce a PoC and show it to them so they can refine their idea. If you go and produce a bunch of tests based on what they asked for, but no working code, you're getting fired. The whole process is on its head because we don't have solid engineering minds in most roles, we have people with liberal arts degrees faking it until they make it. There were a few places I worked that TDD actually succeeded because the project was fairly well baked and the requirements that came it could be understood. That was the exception, not the rule.
- fainpul 1y agoBut with tests you can only prevent those future bugs you managed to think of. Anything you didn't anticipate will not be covered by tests. TDD is useful to build some initial "guard rails" when writing new code and it's useful to prevent regressions (by adding more guard rails when you notice the program went off the road). You can't just add "all the guard rails ever needed" in advance.
- Retric 1y agoSome classes of bugs need specific tests to find, but I can catch a spelling error without specifically looking for a spelling error. Similarly, bugs often crop up because of interactions which aren’t obvious at the time. Thus the reason a test is failing can be wildly different than the intended use case of a test. Perhaps the test failed because the continuous integration environment has some bad RAM, you’ll need to investigate to discover why a test fails.
- XorNot 1y agoHonestly the way I use testing these days is as a more persistent version of a Jupyter notebook. Some piece of code is just complex enough I don't fully understand it, so hopefully the test framework in language of choice will make it easy enough to isolate it and right a bunch of quick to execute explorations of things I expect and do not expect about it.
- embedding-shape 1y ago> The intended workflow of TDD is to write a set of tests before some code. The only reason that makes sense conceptually is to prevent possible future bugs from going undetected. Again, I don't do that for correctness, I do it because it's faster than not having something to work against, that you can run with one command that tells you "Yup, you did the thing!" or "Nope, not there yet". When I don't do TDD, I'm slower, because I have to manually verify things and sometimes there are regressions. Catching these things and automating the process is what makes (for me) TDD worth it. > Put another way if your TDD always pass then there’s no point in writing them Uuh, no one said this? I'm not sure where people got the idea that TDD is this very strict "one way and one way only", the core idea is that your work gets easier to do, if it doesn't, then you're doing it wrong, probably following the rules too tightly. We don't have to be so dogmatic about any methodologies out there, everything has tradeoffs, chose wisely.
- enraged_camel 1y ago>> After all, bugs are unexpected and you can’t write tests for a bug you don’t expect. Ironically, AI can. In my experience it is extremely good at thinking about edge cases and writing tests to defend against them.