5 ms·
> 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
by 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.
- dmitriid 4y ago> Even in the simple example given, there are probably hundreds of different failure cases to account for. Definitely not hundreds. But yes, they need to be tested > The successful case is usually the most understood behaviour, most visible, and easiest to recreate. Tests are not written to document behaviour, but to validate that your program does what it's supposed to do. If you don't test successful cases, you don't even know if it runs correctly. > 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. I see you have the erroneous assumption that tests are documentation. > 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. This is slightly orthogonal to being able to write testable code etc. Most tests are trash to begin with, and most testing frameworks give next to zero help in designing and running actual tests you would really want. I couldn't care less if a team mate wrote "untestable code" in some modules. In 99% of the time that code is some repetitive boilerplate anyway. Ironically, this is the code that everyone prioritises to make testable. And then you want to test all that in concert... Ahahaha good luck. Even starting up a local rest service with mocked dependencies to test is a royal pain in the butt in most cases, and has nothing to do with testability of some small pieces of code. > that's what TDD – and, really, testing in general – is all about: Documentation. Tests are not documentation, have never been, and can never be viewed as such. Testing is literally about testing: to test that your program behaves correctly given some requirements. It literally is in the name. You write tests not to educate your co-workers, but to make sure your program doesn't crash and burn the moment you push it to prod. > Nobody advocates writing useless tests. Future readers should be able to learn something useful from every documentation item you write. Again: 1. Tests are not documentation. Have never been, will never be. 2. Existing testing practices all but enforce writing useless tests, prioritising duplication, hundreds of unit tests etc. over what' actually needed. > Nobody wants to read documentation that is one big ball of mud. All tests are inevitably a ball of mud because they lack context, and they are not documentation.