3 ms·
If you haven't tried property-based/generative testing, I urge you to do so. You'll never want to write unit tests again (this is an exaggeration of course, but
by senderista 7y ago
If you haven't tried property-based/generative testing, I urge you to do so. You'll never want to write unit tests again (this is an exaggeration of course, but not much). IMHO the modern cult of unit testing has about the lowest effort/reward ratio I've seen among standard programming practices. Put that effort into isolating non-trivial invariants in your code (which might actually require thinking about the problem, i.e., producing an informal spec), asserting those invariants everywhere you can in your code, and writing generative tests that just test your assertions with random input. Then you can think of higher-level invariants ("properties") that might not be possible to verify in the code itself, and write property-based tests to verify those invariants. The most important such invariant is that your program computes the right answer. You can test this by creating a "model" or oracle which you are confident will compute the right answer (albeit perhaps horribly inefficiently), and writing property-based tests that verify that the model gives the same answers as your code on random inputs. ("Inputs" in this case aren't just user data, but also sequences of operations or state transitions; they can be any data that your code bases its decisions on.)
Unit tests will always have their place as 1) a minimal, provisional test suite for initial development, and 2) some finite set of important edge cases that might not be covered by randomly generated test cases. But they are much less efficient (IME) than generative testing in terms of developer effort per-bug-found. Additionally, property-based tests force you to think systematically about your code to identify important invariants, and that's always a good thing. You can spend the time left over from not writing useless unit tests in writing functional and integration-level tests, which (IME) are far more likely than unit tests to yield bugs (which IME generally reside in unanticipated interactions between components rather than internal logic errors).