3 ms·
Your tests only need to assert what failure states the user should expect under what conditions, not cover how it should be implemented. If, say, your implement
by randomdata 3y ago
Your tests only need to assert what failure states the user should expect under what conditions, not cover how it should be implemented. If, say, your implementation uses panic/recover instead, your tests shouldn't care. Asserting 'how' the code is to be implemented is how you get brittle tests that are a nightmare to maintain.
And making those assertions shouldn't be mindless work. Documenting the failure cases should be the most interesting work of all the code you are writing. If you are finding that it isn't, then that tells you that you should be using a DSL that has already properly abstracted the failure cases for your problem space away.
- closeparen 3y ago* The user isn't inside the package, but the test has to be or it's not a unit test (and coverage doesn't count). * While "errors are values" makes it possible to enumerate the potential failure cases, most of the time errors are just strings. The thing you are forced to document by the lack of exception semantics is the sites at which you might be dealing with an error vs. a success value. In an IO heavy application this rounds up to "everywhere." * Go is not really powered to do DSLs in a type-safe way, except through code generation. I would view the LLM as a type of code generator here.
- randomdata 3y ago* The test isn’t inside the package either. In fact, Go in particular defines _test packages so that you can ensure that there is explicit separation. You are not testing units if you don’t look at the software the same way the user does. * If your errors are strings, you are almost certainly doing something horribly wrong. Further, your tests would notice it is horribly wrong as making assertions on those strings would look pretty silly, so if your errors are strings that tells that your testing is horribly, horribly wrong. * Go is not a DSL, no. It is unabashedly a systems language. Failure is the most interesting problem in systems. Again, if your failures aren’t interesting, you’re not building a system. You should not be using a systems language, you should be using a DSL. When you have no idea what you are doing, choosing the wrong tool at every turn, an LLM might be able to help, sure.
- closeparen 3y agoGo is positioned as the DSL for microservices. I don't think the language design is fit for this purpose, but that's certainly how the community understands it. In a microservice, "one of your upstream calls might fail and then you return an error to your caller" is not that interesting. I agree that the widespread use of code generation (LLM or otherwise) is revealing of this tension.
- randomdata 3y ago> Go is positioned as the DSL for microservices. Do you mean Goa? Indeed, it is not a language fit for what we're talking about. It only allows description of services, not the implementation. For that you have to fall back to Go, which completely misses the whole reason for using a DSL. > "one of your upstream calls might fail and then you return an error to your caller" is not that interesting. Sure, and which is why you wouldn't use Go here. There is absolutely nothing in Go that is geared towards abstracting those kinds of things away. And you can't tell me that Goa tempts you. It is not a good DSL.