Should I use or split multiple asserts?
I get this question often. It makes sense to stuff all kinds of assertions after a single setup and invocation. For me, it usually comes down to: Try to separate rather than join them. While it’s possible to have some asserts for the same operation, in most situations, where we’re better off separating them.
The main idea behind this is that if the first assertion fails, we won’t know what happened with consequent ones. When that happens, we lost information that is important for solving the problem.
The following example here is of a transaction that transfers money from one account to another. To check it completely, we’d like to test that both account balances changed.
@Test
public void getBalance_AfterTransfer_CorrectAmount() {
bankAccount accountSrc = new bankAccount(5000);
bankAccount accountTarget = new bankAccount(0);
accountSrc.Transfer(500, accountTarget);
assertEquals(accountSrc.getBalance(), 4500);
assertEquals(accountTarget.getBalance(), 500);
}
I think we can all agree that the transaction we check is a single operation. It makes sense that we assert both balance amounts here, with the same setup and invocation.
When You First Fail
What happens when the first assert fails? It throws an exception, the test ends, and the second assertion will not be checked. An error will only be reported on the first one.
The other assert can give us information about the problem. We lost that information.
Now consider the other option. If there were two separate tests:
@Test
public void getBalance_AfterTransfer_SrcDecremented() {
bankAccount accountSrc = new bankAccount(5000);
bankAccount accountTarget = new bankAccount(0);
accountSrc.Transfer(500, accountTarget);
assertEquals(accountSrc.getBalance(), 4500);
}
@Test
public void getBalance_AfterTransfer_TargetIncremented(){
bankAccount accountSrc = new bankAccount(5000);
bankAccount accountTarget = new bankAccount(0);
accountSrc.Transfer(500, accountTarget);
assertEquals(accountTarget.getBalance(), 500);
}
If we ignore the duplication for a minute, now we have the results of both tests and conditions. In the test run report we’ll see the result of both.
Why is that important?
Because we want to fix the problem as quickly as possible. And more information helps you triangulate the problematic code.
Is it worth splitting the tests? As always – it depends.
Assuming we should write the test, it tests for a higher risk code. If that’s the case, when it breaks, we want to fix it as quickly as possible.
We’ll want more data sooner. I’d go for the split.
Reference: | Should I use or split multiple asserts from our NCG partner Gil Zilberfeld at the Everyday Unit Testing blog. |