Cause-Effect Graphing Technique Explained
Cause-effect graphing is the technique that decision tables grew out of. It was formalized by Myers in 1979 as a systematic way to capture the logical relationships between system inputs and outputs — and then mechanically derive a decision table from that model.
Most teams skip straight to decision tables and miss the intermediate step. That's fine when the logic is simple. When the logic is complex — multiple interacting conditions with AND, OR, and NOT relationships — the graph step catches errors in your analysis before you commit them to a table.
This post explains cause-effect graphing from scratch, with a complete worked example for a login form.
Causes and Effects: The Core Concepts
In cause-effect graphing terminology:
Causes are inputs — conditions that are either true or false at the time of the test. Examples:
- Username field is non-empty
- Password field is non-empty
- Account exists in the database
- Account is not locked
Effects are outputs — observable behaviors that either happen or don't happen. Examples:
- User is logged in and redirected to dashboard
- Error message "Invalid credentials" is displayed
- Error message "Account locked" is displayed
- Login button remains disabled
Both causes and effects are binary: true (1) or false (0). This constraint is the same as limited-entry decision tables — and it's why the conversion between graphs and tables is mechanical.
Logical Connectives
Causes combine to produce effects through logical connectives. There are four:
Identity
Effect is true if and only if the cause is true. Direct, one-to-one relationship. Written as a plain arrow: C1 → E1.
NOT
Effect is true if and only if the cause is false. Written as an arrow with a circle: C1 ⊸ E1. In plain text notation: ¬C1 → E1.
AND
Effect is true if and only if ALL connected causes are true. Standard logical AND.
OR
Effect is true if ANY connected cause is true. Standard logical OR (inclusive).
There's also an Exclusive OR (XOR) used occasionally — effect is true if exactly one cause is true — but it's less common in practice.
Constraints Between Causes
Besides the four connectives, cause-effect graphs support constraints that express impossible or mandatory combinations of inputs:
- E (Exclusive): at most one of the causes can be true at a time (e.g., a radio button group — only one can be selected)
- I (Inclusive): at least one of the causes must be true
- O (One and only one): exactly one must be true
- R (Requires): if cause A is true, cause B must also be true
These constraints reduce the number of rules you need to test by eliminating impossible combinations.
How to Draw a Cause-Effect Graph
- List all causes on the left side. Number them C1, C2, C3, ...
- List all effects on the right side. Number them E1, E2, E3, ...
- Draw connections from causes to effects using the appropriate connectives
- Add intermediate nodes if needed — sometimes an effect depends on a combination of causes that itself feeds into another combination. These intermediate nodes represent sub-expressions.
- Mark constraints between causes that can't all be true simultaneously
Once the graph is drawn, you systematically trace backward from each effect to determine what combination of causes produces it.
Converting a Cause-Effect Graph to a Decision Table
The conversion is algorithmic:
- For each effect, identify all combinations of causes that make it true (trace backward through the graph)
- For each such combination, check that no E/O constraints are violated
- Each valid combination where at least one effect is true becomes one rule (column) in the decision table
- Rules where no effects fire (everything's blank) can be collapsed into one "no action" rule or verified that the system handles the case correctly
Worked Example: Login Form
A login form with the following behavior:
- Login button is enabled only if both username and password fields are non-empty
- When the button is clicked, if credentials are valid and account is not locked, user logs in
- If credentials are invalid, show "Invalid credentials" error
- If credentials are valid but account is locked, show "Account locked" error
Step 1: Identify Causes
| ID | Cause |
|---|---|
| C1 | Username field is non-empty |
| C2 | Password field is non-empty |
| C3 | Credentials are valid (username + password match a record) |
| C4 | Account is locked |
Note: C3 and C4 only make sense when C1 and C2 are both true. We'll handle this with constraints.
Step 2: Identify Effects
| ID | Effect |
|---|---|
| E1 | Login button is enabled |
| E2 | User is authenticated and redirected |
| E3 | "Invalid credentials" error shown |
| E4 | "Account locked" error shown |
Step 3: Define the Logic
E1: C1 AND C2
E2: C1 AND C2 AND C3 AND (NOT C4)
E3: C1 AND C2 AND (NOT C3)
E4: C1 AND C2 AND C3 AND C4Constraint: C3 and C4 are only evaluated when C1 AND C2 are both true. When C1 or C2 is false, E2/E3/E4 don't fire regardless.
Step 4: Enumerate Combinations
With 4 binary causes, we have 2^4 = 16 possible combinations. The constraint that C3 and C4 are only meaningful when C1=Y and C2=Y reduces the meaningful cases significantly. Let's enumerate systematically:
When C1=N or C2=N: Button is disabled (E1=N), no login attempted, E2/E3/E4 all N. These collapse to three rules:
- C1=N, C2=N → button disabled
- C1=Y, C2=N → button disabled
- C1=N, C2=Y → button disabled
When C1=Y and C2=Y: Button enabled. Four sub-cases from C3 and C4:
- C3=Y, C4=N → user logs in (E2)
- C3=Y, C4=Y → account locked error (E4)
- C3=N, C4=N → invalid credentials (E3)
- C3=N, C4=Y → invalid credentials (E3) — can't have a locked account with invalid credentials unless the system checks account status first; depends on implementation order
The last case (C3=N, C4=Y) is technically possible in some systems (locked account, wrong password). Cause-effect graphing forces you to ask the question — what should happen? Your requirements need to answer it.
Step 5: The Decision Table
| R1 | R2 | R3 | R4 | R5 | R6 | R7 | |
|---|---|---|---|---|---|---|---|
| Conditions | |||||||
| C1: Username non-empty | N | Y | N | Y | Y | Y | Y |
| C2: Password non-empty | — | N | Y | Y | Y | Y | Y |
| C3: Valid credentials | — | — | — | Y | Y | N | N |
| C4: Account locked | — | — | — | N | Y | N | Y |
| Actions | |||||||
| E1: Button enabled | N | N | N | Y | Y | Y | Y |
| E2: User authenticated | X | ||||||
| E3: Invalid credentials | X | ? | |||||
| E4: Account locked error | X | ? |
The two "?" entries in R7 (valid login attempt, wrong password, account is marked locked) are a requirements gap that the graph forced you to find. The table won't let you hide it.
Why Bother With the Graph?
For simple logic — two or three conditions — skip the graph and draw the table directly. But cause-effect graphing adds value when:
The logic has intermediate sub-expressions. When "condition A AND condition B" feeds into "that result OR condition C", a graph makes the structure explicit. A flat table obscures the hierarchy.
There are constraints between inputs. Radio buttons, mutually exclusive states, required combinations — these are hard to express in a table but natural in a graph. Constraint notation prevents you from writing test cases for impossible states.
Requirements are written as prose. Translating "the system shall do X if A and B, unless C, in which case Y, except when D" into a graph first forces you to parse the logic carefully. Errors show up as disconnected nodes or cycles.
Multiple effects share overlapping causes. A graph shows the shared structure. A table repeats it, making it harder to see.
The Relationship to Decision Tables
Cause-effect graphing is a precursor step, not a replacement. The output of the graphing process is a decision table. Everything in the previous post about limited vs extended entry, collapsing rules, and deriving test cases applies directly.
The graph helps you build a correct, complete table. The table helps you derive concrete test cases. The two techniques are complementary.
For login forms, checkout flows, permission systems, and any feature governed by "if A and B but not C" rules: draw the graph, convert to a table, derive your tests. You'll cover more ground with fewer test cases than any other approach.