Most of the developers are familiar with the concept of assertion in test writing. Assertion is the process of making sure some condition is met. Most of the times the condition is a kind of check for the result of the tested unit. For example an array being empty, of a variable being filled with the proper value. Check this example, let's write a simple calculator class. This class has two methods: add
and multiply
. add
method simply adds two integers and returns the result, but the multiply
method uses the add method for multiplication.
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int multiply(int a, int b) {
int result = 0;
for (int i = 0; i < b; i++) {
result += add(result,a);
}
return result;
}
}
For the add method my unit test would be like this :
@Test
public void testAdd() {
int a = ThreadLocalRandom.current().nextInt();
int b = ThreadLocalRandom.current().nextInt();
int result = calculator.add(a, b);
Assertions.assertEquals(a + b, result);
}
For any two given integers, the result of add
method should be equal to adding them together.
My unit test for multiply
method would be like this:
@Test
public void testMultiply() {
int a = ThreadLocalRandom.current().nextInt();
int b = ThreadLocalRandom.current().nextInt();
int multiplicationResult = calculator.multiply(a, b);
Assertions.assertEquals(a * b, multiplicationResult);
}
It works, but there's something to note. We know that the multiply
method heavily relies on the add
method. If add is not working, there's no point in testing the multiply
. For our example, it would not hurt much but in real-world problems, it may affect test time and resources heavily. What can we do? We can use Assumption.
@Test
public void testMultiply() {
int a = ThreadLocalRandom.current().nextInt();
int b = ThreadLocalRandom.current().nextInt();
int additionResult = calculator.add(a, b);
Assumptions.assumeTrue(a + b == additionResult);
int multiplicationResult = calculator.multiply(a, b);
Assertions.assertEquals(a * b, multiplicationResult);
}
When assuming, you check the prerequisites of the test, if they are not available or do not have the expected value, there's no point in continuing with the test. In the above example, we first make sure that the add
method is working properly.
Why not just assert them? The difference is if the assertion fails the test will fail but if the assumption fails the test will be ignored. Although in many tests they are asserted, that's not the way it should be. We do not want to test the functionalities of other methods, but we want to be sure that they are working properly.
If the tests are well written for all the parts of code, the part which makes the assumption fail would have proper tests that would fail.
For example, if our add method is not working properly, the testAdd
would fail and the testMultiply
would be ignored.
Top comments (3)
nice, thanks for share
Very nice!.
but the 7th line i think is "Assumptions.assumeTrue(a + b == additionResult);"
Thanks, yes you are right. Fixed!