3 ms·
I think you forgot at least one valid assertion and implied another one: foo.call() might have a return value. Also, the whole story invocation shouldn't thro
by choeger 4y ago
I think you forgot at least one valid assertion and implied another one:
foo.call() might have a return value.
Also, the whole story invocation shouldn't throw an exception, if your language has them. This assertion is often implied (and that's fine), but it's still there.
Finally the test case is a little bit stupid, because very seldom code doesn't have any input that changes the behavior/result. So your assertion would usually involve that input.
If you follow that though consequently, you end up with property-based tests very soon. But property-based tests should have as many assertions as possible for a single point of data. Say you test addition. When writing property-based tests you would end up with three specifications: one for one number, testing the identity element and the relationship to increments. Another one for two numbers, testing commutativity and inversion via subtraction, and one for three numbers, testing associativity. In every case it would be very weird to not have all n-ary assertions for the addition operation in the same spot.
- mollerhoj 4y agoWhen you say I 'forgot' an assertion, are you implying that test should include all possible assertions on the code? That would perhaps cover more surface, but my goal (read zealot ideology) here is to have the tests help document the code: test "pressing d key makes mario move 2 pixels right" { expect { keyboard.d() }.to change { mario.x }.by(2) } I could test the value of the d() function, but I dont because I don't care what it returns. Didnt understand the "whole story invocation" and exception part, am I missing some context? Sure property-based testing can be invaluable in many situations. Only downside is if the tests become so complex to reason about that bugs become more likely in the tests than the implemenation. I've sometimes made tests with a manual list of inputs and a list of expected outputs for each. I'd still call that 1 assertion tests (just run multiple times), so my definition of 1 assertion might too broad..
- hinkley 4y agoWhen you get the suites nested and configured right, and the code decomposed properly to support it, each of these assertions is two lines of code, plus the description of each constraint. So you just write four or five tests covering each one, in descending likelihood of breakage.