When I’ve written tests for some code and want to make sure that it’s actually testing what it’s supposed to, I’ll mess up or remove the code-under-test, and see if the tests fail. If they don’t, I’ve got a problem.
Is there a name for this technique? It’s a real bother having to talk in sentences everytime I want to suggest to someone that they do it.
2
You’re looking for mutation testing.
The idea of mutation testing is to check that the code can be modified to cause the testing to fail, as you have pointed out. An example is as such:
public double getDiscountedRate(int age, int employmentDurationInMonths) {
return age < 30 || employmentDurationInMonths < 18 ? 0.2 : 0.05;
}
So if we have this test:
@Test
public void canGetCorrectDiscountedRate() {
assert getDiscountedRate(29, 24) == 0.2;
}
The assertion will be true. If the formula is modified as such:
public double getDiscountedRate(int age, int employmentDurationInMonths) {
return age < 30 && employmentDurationInMonths < 18 ? 0.2 : 0.05;
}
Then we will expect the assertion to be false now. This helps when there may be a careless error in the method, such as (post-operator modification):
public double getDiscountedRate(int age, int employmentDurationInMonths) {
return age < 30 && employmentDurationInMonths < 18 ? 0.2 : 0.2; // where is 0.05?
}
In this, the fact that the assertion did not fail for the modified code will let the developer know that it was wrongly returning the same discount rate even when the condition is false.
The Wikipedia article on mutation testing has also helpfully pointed out ‘fault injection’ as a related article.
3