Learning Objectives
By the end of this lesson you will be able to:
- Identify the three most common boolean operator mistakes in code
- Translate each mistake into one or more targeted test cases
- Explain why boolean bugs survive standard test suites
The Invisible Bug
Consider a discount system with this rule: "Apply a discount if the user is a premium member OR if their cart total exceeds €200."
A developer writes: if (isPremium && total > 200). Every basic test passes: premium users with large carts get the discount. Non-premium users with small carts don't. The bug only appears when a premium user has a small cart — or when a non-premium user has a large cart. These are the combinations that slip through.
Bug #1: AND Instead of OR
Specification: "Discount applies if condition A OR condition B."
Bug: if (A && B) — now both must be true.
Test to catch it:
- A=true, B=false → should get discount, but doesn't ← catches the bug
- A=false, B=true → should get discount, but doesn't ← catches the bug
- A=true, B=true → gets discount (passes even with the bug)
- A=false, B=false → no discount (passes even with the bug)
Always test each condition independently — true with the other false, and false with the other true.
Bug #2: OR Instead of AND
Specification: "Block the user if they are suspended AND their account is flagged."
Bug: if (isSuspended || isFlagged) — now either condition alone blocks.
Test to catch it:
- isSuspended=true, isFlagged=false → should pass, but is blocked ← catches the bug
- isSuspended=false, isFlagged=true → should pass, but is blocked ← catches the bug
Bug #3: NOT Applied to the Wrong Expression
Specification: "Show error if NOT (age is valid AND income is provided)."
This means: show error if age is invalid OR income is missing.
Bug: if (!age_valid && !income_provided) — now the error only shows when both are wrong.
Test to catch it:
- age_valid=false, income_provided=true → should show error, but doesn't
The bug often comes from the developer distributing NOT incorrectly. De Morgan's law: NOT(A AND B) = (NOT A) OR (NOT B). Developers frequently forget this.
Why Boolean Bugs Survive Testing
- Happy path dominance — most test suites test the "all conditions met" and "none met" cases. The individual-condition failures live in the middle.
- Specification ambiguity — if the spec says "members and high-value customers get discounts," does it mean both conditions are required, or either? Bugs start in the specification.
- Review blindness — code reviewers see
if (A && B)and mentally read "A and B" — matching the spec word for word, without noticing the logical difference.
Pro Tip: For any condition containing
&&or||, write at least one test where exactly one side is true and the other is false. This is the minimum to distinguish AND-bugs from OR-bugs.
Summary
AND/OR confusion is not a beginner mistake — it appears regularly in production code written by experienced developers. As a tester, your job is to independently flip each condition in a compound expression and verify the result. Each operator represents a family of test cases, not a single scenario.