Great work!

XP to next level

BugEater

AND, OR, NOT — Where Developers Go Wrong

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

  1. Happy path dominance — most test suites test the "all conditions met" and "none met" cases. The individual-condition failures live in the middle.
  2. 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.
  3. 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.

Quiz

A developer writes: if (isAdmin || isPremium && hasAccess). Due to operator precedence, this evaluates as:

Which test case would EXPOSE a bug where && was used instead of ||?

A developer codes if (amount > 100) instead of if (amount >= 100). Which input VALUE is the critical test?

Which coding practice BEST prevents operator precedence bugs?