5 ms·
> Are you writing many tests before you begin implementation? No. I usually write functional/integration tests after I've written most of the code. > TDD prom
by dmitriid 4y ago
> Are you writing many tests before you begin implementation?
No. I usually write functional/integration tests after I've written most of the code.
> TDD promotes that you start with just one.
And that one will be absolutely entirely useless. Because what would be that "first one test"?
Let's assume it's a REST or GraphQL service that returns aggregated data from multiple external services. Until you have more-or-less functioning code (including all model definitions, client definitions, data transforms etc.) you can't even write a "first test for observable behaviour". Also here: https://news.ycombinator.com/item?id=34765360 https://news.ycombinator.com/item?id=34765360
- randomdata 4y ago> Because what would be that "first one test"? Whatever you want. Just pick some small attribute that you expect to observe. I'd personally start with failure modes as they are the most important and interesting code you will write. Hell, you can likely not even bother testing the so-called "happy path" because, really, who cares what happens during success? Failure is where you want users and future readers to have the most documentation to ensure that when things go wrong the metaphorical bridge doesn't come crashing down into the river but rather remains in a repairable state. If it's a REST endpoint that aggregates data from multiple external services, you probably want to see a "retry after" response sent to the client if any of those external services are temporarily unavailable. So write a test that asserts that, then write code that does it. This is also a nice first case as you can detect an unavailable external service quite early in your pipeline, requiring very little of the implementation to see the test pass. No need for religion. If documenting your code later works for you, go for it. Nobody cares. Tests won't be driving your development, so it won't be TDD, but it'll be something and that may be enough. However, in reality most people simply don't have the wherewithal to plan for things like being able to test unavailable remote services if they don't have a test case in front of them forcing them to and won't bother when it is too hard to add later, so there is something to be said about the TDD approach as a general rule, deviating only after you fully understand the tradeoffs.
- dmitriid 4y ago> Just pick some small attribute that you expect to observe. The expected "attribute" is correct data being returned. > Hell, you can likely not even bother testing the so-called "happy path" because, really, who cares what happens during success? wat? > If it's a REST endpoint that aggregates data from multiple external services, you probably want to see a "retry after" response sent to the client if any of those external services are temporarily unavailable. So write a test that asserts that, then write code that does it. So again you want me to write a meaningless test that will be duplicated anyway during the actual proper test. See https://news.ycombinator.com/item?id=34765360 https://news.ycombinator.com/item?id=34765360 > However, in reality most people simply don't have the wherewithal to plan for things like being able to test unavailable remote services if they don't have a test case in front of them forcing them This is a weird statement that is definitely not backed up by reality. > there is something to be said about the TDD approach as a general rule, deviating only after you fully understand the tradeoffs. The problem is, everyone advocates writing multiple useless tests, including TDD proponents. You can't learn "tradeoffs" until you look past the dogma. Once you've looked past the dogma these "tradeoffs" most of them are not tradeoffs, but trivial things that you would do anyway.
- randomdata 4y ago> The expected "attribute" is correct data being returned. Even in the simple example given, there are probably hundreds of different failure cases to account for. The "correct data being returned" will never be a single attribute unless your application does effectively nothing. > wat? The successful case is usually the most understood behaviour, most visible, and easiest to recreate. If you are going to skimp out on documenting some aspects of your code because you hate future developers, the most understood aspect is where you are best to skimp. > So again you want me to write a meaningless test that will be duplicated anyway during the actual proper test. No. Why would you write the same documentation over and over again? This makes no sense. > This is a weird statement that is definitely not backed up by reality. It is certainly backed up every time I have worked with developers who put no effort into making their code testable, making it way harder than it should be to test certain cases afterwards. And in my experience they usually just throw their hands up in the air and say "testing takes too long" after they've made it unnecessarily hard to test. Is it that you always work alone? If so, I can see why you think documentation isn't that useful. If you have a decent memory, it probably isn't. But most people have to work in teams or are in positions where they will one day be replaced and aren't writing documentation for just for themselves. After all, that's what TDD – and, really, testing in general – is all about: Documentation. > The problem is, everyone advocates writing multiple useless tests Nobody advocates writing useless tests. Future readers should be able to learn something useful from every documentation item you write. That your function will return "retry after" when an upstream service is temporarily unavailable is very useful information for users and future developers to know. This is worth documenting. You will undoubtedly need to write multiple tests. Nobody wants to read documentation that is one big ball of mud. A sane developer will break different cases into different tests to help future readers clearly understand that there are different environmental cases, like the range of failure states, to consider.