What’s a branch?
A branch is a piece of code that comes after a condition. In a branch, only one scenario of code will be executed after the condition check.
It can be implemented by If\else or switch case.
Let’s use an example to clarify the idea:
Daniel has 5 dollars. He goes to the supermarket in order to buy a chocolate bar, If he has enough money he will buy it, else, he will not buy and will have to continue his life without the chocolate bar.
Only one scenario can occur, either he buys it (if he has enough money) or not (he doesn’t have enough).
There is no possible scenario that both situations happened (he buys it and doesn’t buy it)
The same rules apply to code. Only one part of the logic will be executed.
There are two scenarios in this case:
1) Code block A will be executed when the denominator equals 0.
2) Code block B will be executed when the denominator is different than 0.
There’s no third option in which BOTH scenarios will be executed. Denominator B can’t be 0 and not 0 at the same time.
What’s branch coverage?
To understand what’s branch coverage first we need to understand what’s code coverage. The idea of code coverage is simple- to display the percentage of your code that is in fact covered by tests. The coverage can show integration tests (integration between couple units of the code) or unit tests (tests that examine a single unit\method of code).
You can think of branch coverage, also called DD-path (decision to decision path) as a junction. In this junction you have only two options, right or left, If or Else. Once you make a choice you can’t choose another scenario. In a scenario in which you choose Else, you can’t choose If as well, in this case, the scenario isn’t covered.
Important note: In branch coverage, you want to check if any of the scenarios occurred and if every piece of code been reached. For example, given an if statement, have both the true and false branches been executed?
Similar to If/Else statement, there’s also switch statement, which is a different way to create a branch in your code. It’s mostly used when you have more than three cases and a short condition. Its advantages are it looks more organized and readable. For example: if you want to create a method that’ll return a number according to each month, in a year’s time. You’d probably use a switch statement. As you can see in this example:
How does it look behind the scenes?
Each If/Else statement is compiled to brfalse.s il instruction, if the statement is correct the brfalse.s will not be executed and the next line of code will be reached (execute the piece of code inside the if statement).
If it’s false the instruction targets the address after the scopes
Switch case statement has a different definition. When it is one or two cases and default case, each case will be translated to Il instructions (in this case beq.s) followed by the address to jump to in case the statement is correct.
In case of a switch statement with more than two cases, it will be translated to switch() instruction with all the address in scopes and jumps to the relevant one according to the input.
In this case, if the method is tested with A (and A is bigger than B) 100% of the code’s lines are tested but the branch coverage will remain 50%.
The counter-scenario to the previous case is when there’s a piece of code that doesn’t reach by the test. For example:
When you test a division with B that is not 0, the catch scope will not be executed and the sequence coverage will be 50% while the branch is 100% as there are no branches in that method.
For example, if you have 75 lines of code and 50 lines was reached and tested in your test that means your method is 66.6% covered by tests.
What’s the best way to learn how much of your branch is covered with tests?
Use a code coverage tool, our coverage tool lets you see the exact branch coverage, the amount of entries in each condition and which code was executed.