- Every branch was "visited". Plain coverage already ensures that. I would actually advocate for 100% branch coverage before 100% line coverage.
- Every part (condition) of a branch clause has taken all possible values. If you have if(enabled && limit > 0), MC/DC requires you to test with enabled, !enabled, limit >0, limit <=0.
- Every change to the condition was shown to somehow change the outcome. (false && limit > 0) would not pass this, a change to the limit would not affect the outcome - the decision is always false. But @zweifuss has a better example.
- And, of course, every possible decision (the outcome of the entire 'enabled && limit > 0') needs to be tested. This is what ensures that every branch is taken for if statements, but also for switch statements that they are exhaustive etc.
MC/DC is usually required for all safety-critical code as per NASA, ESA, automotive (ISO 26262) and industrial (IEC 61508).
I hope you don't have any string inputs, or your test is gonna take a while to run!
But yes, exhaustively testing your code is a bit exhausting ;)
It's mandated by DO-178C for the highest-level (Level A) avionics software.
Example: if (A && B || C) { ... } else { ... } needs individual tests for A, B, and C.
Test #,A,B,A && B,Outcome taken,Shows independence for
1,True,True,True,if branch,(baseline true)
2,False,True,False,else branch,A (A flips outcome while B fixed at True)
3,True,False,False,else branch,B (B flips outcome while A fixed at True)
Test # A B C Result
1 True True False True
2 False True False False
3 True False False False
4 False True True True