Decision Table Testing: Technique, Examples and Template
Decision table testing turns tangled business rules into a small grid you can turn straight into test cases. Learn the method, a worked example and a template.
- Decision table testing lists conditions and actions in a grid; each column (a rule) becomes one test case.
- With n yes/no conditions a full table has 2^n rules, so merge rules whose outcome does not depend on a condition.
- It fits business rules such as discounts, loans, permissions and shipping fees, not simple single-input checks.
- Pair it with boundary value analysis and automate the finished table with a parameterised test.
Decision table testing is a black-box test design technique for rules that depend on a combination of conditions. You write every condition and every action in a table, and each column of the table becomes a test.
Think about a checkout page. Shipping might be free depending on the order total, the discount depends on membership, and a coupon only works above a minimum spend. Test these one at a time and you will miss the combinations where rules collide.
This guide explains decision table testing step by step, shows a full worked example with eight rules, collapses it to six, and ends with a reusable template and a short automation sample.
What is decision table testing?
A decision table has four parts: conditions (the inputs), actions (the expected results), rules (each column, one combination of condition values) and the cells that record which condition value each rule uses. The ISTQB glossary defines it as a technique where test cases are designed to execute the combinations of inputs shown in a decision table. Some books call the same idea a cause-effect table.
| Part | Meaning | Example |
|---|---|---|
| Condition | An input that can be true or false | Customer is a member |
| Action | An expected outcome | Apply 10% discount |
| Rule | One column: a set of condition values and its actions | Member, order over $50, no coupon |
| Test case | One test per rule | Check the cart total for that user |
When to use decision table testing
- Several conditions together decide the result.
- The requirement is written as “if … and … then …” sentences.
- You need proof that every combination was either tested or deliberately skipped.
It is a poor fit when behaviour depends on a single numeric range (use boundary value analysis) or on a sequence of events (use state transition testing).
How to create a decision table in 5 steps
- List the conditions. Pull them from the requirement, one yes/no question each.
- List the actions. Write what the system should do or show.
- Fill in all combinations. With n conditions you get 2^n columns. Three conditions give 8 rules, four give 16.
- Mark the actions for each rule using the requirement, not the code.
- Collapse the table. If two rules differ in one condition and have the same actions, merge them and mark that condition with a dash (don’t care).
Decision table testing example: online checkout
Requirement for a small shop:
- Orders of $50 or more ship free.
- Members get 10% off.
- A coupon gives an extra 5% off, but only on orders of $50 or more.
Conditions: M = member, O = order is $50 or more, C = coupon entered. Y means yes, N means no.
| Rule | M | O | C | Free shipping | Discount |
|---|---|---|---|---|---|
| R1 | Y | Y | Y | Yes | 15% |
| R2 | Y | Y | N | Yes | 10% |
| R3 | Y | N | Y | No | 10% |
| R4 | Y | N | N | No | 10% |
| R5 | N | Y | Y | Yes | 5% |
| R6 | N | Y | N | Yes | 0% |
| R7 | N | N | Y | No | 0% |
| R8 | N | N | N | No | 0% |
Look at R3 and R4. A member with a small order gets no shipping benefit and 10% either way, so the coupon does not matter. The same is true for R7 and R8. Merge them and the table shrinks from eight rules to six:
| Rule | M | O | C | Free shipping | Discount |
|---|---|---|---|---|---|
| R1 | Y | Y | Y | Yes | 15% |
| R2 | Y | Y | N | Yes | 10% |
| R3-4 | Y | N | – | No | 10% |
| R5 | N | Y | Y | Yes | 5% |
| R6 | N | Y | N | Yes | 0% |
| R7-8 | N | N | – | No | 0% |
That gives six test cases that cover every distinct outcome. One caution: the “-” rows hide a real risk. If a developer accidentally lets a coupon work on small orders, only a test with a coupon on a small order will catch it. Many teams keep one such test for rules where “don’t care” is the interesting part.
Tip: turn the table into test data first. Each rule needs a concrete order, for example a $49.99 and a $50.00 cart, which also covers the boundary at $50. See our guide to writing test cases for the format.
Automating the table with pytest
A decision table maps neatly onto a parameterised test. One row of data per rule means the table lives in the code, and a new rule is one new line. The pytest docs describe parametrize in detail.
import pytest
def checkout(member, total, coupon):
free_shipping = total >= 50
discount = 10 if member else 0
if coupon and total >= 50:
discount += 5
return free_shipping, discount
@pytest.mark.parametrize("member,total,coupon,free,discount", [
(True, 60.00, True, True, 15), # R1
(True, 60.00, False, True, 10), # R2
(True, 49.99, True, False, 10), # R3-4
(False, 60.00, True, True, 5), # R5
(False, 60.00, False, True, 0), # R6
(False, 49.99, True, False, 0), # R7-8
])
def test_checkout_rules(member, total, coupon, free, discount):
assert checkout(member, total, coupon) == (free, discount)
If your suite is in Playwright or Selenium, keep the same idea: a data array drives one test body. Our end to end testing best practices post explains why data-driven tests stay easier to maintain.
Decision table template you can copy
| Item | R1 | R2 | R3 | R4 |
|---|---|---|---|---|
| Condition 1 | Y | Y | N | N |
| Condition 2 | Y | N | Y | N |
| Action 1 | X | |||
| Action 2 | X | X | ||
| Test case ID | TC-01 | TC-02 | TC-03 | TC-04 |
Add one row per condition and action, and one column per rule. Link each column to a test case ID so traceability is obvious in a review.
Common mistakes and limits
- Too many conditions. Ten conditions mean 1,024 rules. Split the requirement into smaller tables.
- Merging rules too early. Check the requirement, not the code, before using a dash.
- Missing rules. Count the columns: they must equal 2^n before collapsing.
- Conflicting rules. If two columns have the same conditions and different actions, the requirement is ambiguous. Raise it with the product owner.
- Using it for everything. Combine it with boundary value analysis, equivalence partitioning and exploratory testing.
Final thoughts
Decision table testing gives you a clear view of which rule combinations you covered and which you skipped on purpose. Start with the conditions in your next feature spec, build the full grid, merge what truly does not matter and drive the result from a parameterised test. Even a small table often exposes a missing requirement before a single line is tested.
Frequently asked questions
What is decision table testing in simple words?
It is a way to list all combinations of conditions and the expected result for each one in a table, then write one test per column.
How many test cases does a decision table give?
A full table has 2^n rules for n yes/no conditions. After merging rules with the same outcome you usually test fewer.
Is decision table testing black box or white box?
It is a black-box technique, because rules come from the requirements, not from the code.
What is the difference between decision table and state transition testing?
Decision tables test combinations of inputs at one moment. State transition testing checks how behaviour changes across a sequence of events.
Can decision table testing be automated?
Yes. Put each rule in a data row and run one parameterised test, for example with pytest parametrize, JUnit or a Playwright data array.
Keep learning
Need help with testing, WordPress or SEO?
We help teams ship better software and grow their sites. Tell us what you are working on and we will suggest a clear next step.