Introduction
Have you needed help defining what to test when you encounter a complex condition in your code? Do you feel lazy when looking at a condition that has too many logical statements?
It’s easy to look at that big if statement that you find in legacy code and think: “Man, what should I test here? Should I cover all the possible combinations in this code? If I do every possible combination will I catch all the bugs?”.
The answer to all these questions is no. Testing everything in your code to cover all details as much as possible will be expensive. You can find new ways to save time, cover more cases, and spot hidden bugs in your code. How can you do this?
You can do this by MC / DC criteria. It guides you to test combinations for well-checked code. Let’s find out how.
Understanding the problem of complex conditions
If you have a logical statement it can be true
or false
which is 2 possibilities.
That’s our starting point. If a single logical operation composes the condition of our code. Then the amount of possibilities to test will be only two (true or false), so it’s easy to test all combinations.
if(age >= 18)
The only possible combinations here are:
- an age that is equal to or higher than 18
- an age that is less than 18
That’s an easy case.
But as the complexity grows, the number of possible combinations also grows.
Let’s take a look at this example:
Let’s consider a student. They can join the field trip if their parents agree. They must also be in grade 12 or part of the science club
The code will look something like this:
if (hasParentalPermission && (grade == 12 || isScienceClubMember)) {
System.out.println("The student can go on the field trip.");
} else {
System.out.println("The student cannot go on the field trip.");
}
So the total of combinations will be 2³. Which is 8.
Test Case | hasParentalPermission | grade == 12 | isScienceClubMember | Result |
---|---|---|---|---|
1 | True | True | True | True |
2 | True | True | False | True |
3 | True | False | True | True |
4 | True | False | False | False |
5 | False | True | True | False |
6 | False | True | False | False |
7 | False | False | True | False |
8 | False | False | False | False |
Table 1 - All possible conditions
So now if you want to cover all possibilities you’ll have to write 8 scenarios for a simple code. That’s starting to become expensive.
If we have 4 conditions, that will be even worse, meaning that we will have 2⁴ (16) possible conditions.
One issue is that many conditions are repetitive. This can complicate things when trying to account for all scenarios.
So that’s the point of MC/DC. This allows you to bypass these possibilities while maintaining reliable testing. It will reduce the number of possibilities to N + 1 (condition count + 1).
How to apply MC/DC in 2 simple steps
Follow these steps:
- You must test each condition as true and false once.
- Each condition has to affect the resulting outcome independently.
Example:
Let’s apply the MC/DC for the condition that creates the above table, to reduce the amount of possibilities.
By doing so we can extract a N+1 table of possibilities:
hasParentalPermission | grade == 12 | isScienceClubMember | Result | Testing |
---|---|---|---|---|
T | T | T | True | Testing all conditions true |
T | T | F | True | Test how grade ==12 Affects the outcome |
T | F | T | True | Test how isScienceClubMember affects the outcome |
F | T | T | False | Test how hasParentalPermission affects |
Table 2 - Reduced condition scope using MC/DC
If you look closely, each condition has been evaluated as true and false once. Each of them had the chance to change the result outcome. Let’s check.
- hasParentalPermission condition could alter the result. It was tested as true and false at least once.
- grade == 12 had the chance to change the outcome and was true and false at least once.
- isScienceClubMember had the chance to change the outcome and was true and false at least once.
It doesn't seem very easy but is very simple. Practice for a while and it will become second nature. This will help a lot in creating efficient unit tests.
Conclusion
You learned a quick way from this article. It’s for testing tricky parts in your code. Now, deciding what to test is easier. This helps spot issues in your code.
Now, it’s your turn. Practice this. Look at your code. Find places to use this method. This will save you a ton of time and can avoid some headaches too!
Don’t forget to follow me on social media and here on dev.to to be the first to read when my next article comes out!
Top comments (0)