A decision table is a grid: one row per combination of input conditions, one column per condition, one final column for the decision. Writing the table forces enumeration of every case; missing rows become visible at a glance. The implementation becomes a lookup against the table. This is the lowest-cost formal method in the catalog; the technique requires no specialist notation beyond a labeled grid. Hillel Wayne's Decision Tables is a clear, accessible introduction (Wayne 2018)1.
What it catches¶
- Missing rows in decision logic. Three boolean conditions produce eight rows; eligibility logic that handles seven of them ships a policy gap.
- Inconsistent rows. Two rows that match the same inputs but prescribe different decisions are a contradiction; the table surfaces them as duplicates.
- Dead conditions. A condition that never affects the outcome shows up as a column whose values don't change the result. Often a sign of dead code or over-specification.
- Stakeholder ambiguity. Product, legal, compliance, ops can read a table where they cannot read source code. Decision tables are often the one formal method non-engineers will engage with.
- Drift between policy and code. When the table is the source of truth, the implementation tests against the table; any divergence is a code bug, not a policy bug.
On a markdown table or spreadsheet these checks are done by eye at review time; on a table in DMN (Decision Model and Notation) format they can be run automatically: dmn-check statically flags missing and overlapping rules, and an in-source enumeration hands the completeness check to the compiler.
Decision tables catch nothing outside the case space they enumerate.
Tools¶
The right form depends on who needs to read and edit the table.
- A markdown table in the repo. The recommended baseline. The PR review surfaces missing rows; the table lives next to the code that implements it.
- A spreadsheet (Excel, Google Sheets). When stakeholders outside engineering need to read or edit the table. A CSV export carries the rows back to the test suite or into a markdown doc.
- DMN — an Object Management Group (OMG) standard for decision tables; used by rule engines and business-process-management (BPM) platforms.
- Drools, OpenL Tablets, and Operaton: open-source rule engines that execute DMN tables directly. Operaton is the Apache-2.0, community-owned fork of Camunda 7; the commercial Camunda 8 platform's DMN engine does the same job. Useful when business analysts own the rules.
- dmn-check — static analysis for DMN files: detects missing rules (completeness gaps), overlapping or conflicting rules, and type errors, and merges redundant rows. Runs in CI or as a Camunda Modeler plugin.
- In-source enumerations. A typed sum type that enumerates the
rows, plus an exhaustive
match/switch, gives the same guarantees the table does, and the type checker enforces them.
When to use, when not¶
Use:
- For any feature whose decision combines two to five conditions. The cost is minutes, and a missing combination shows up as a missing row.
- For regulated decisions where stakeholders outside engineering must read and approve the rules. The table is the contract.
- When porting eligibility or pricing logic across implementations. The table is the durable artifact; the code is not.
- As an entry point to formal methods on a team that has none. The notation is a labeled grid, nothing more.
Don't:
- When the case space is large. Past ~5 binary inputs the table has 32+ rows and is no longer scannable. Use a rule engine or hierarchical decision tables.
- For continuous conditions. Bucket the range first (e.g., "age < 18", "18–64", "65+") and write the table over the buckets.
- For control-flow decisions that have state. Use state machines instead.
Evidence¶
Empirical literature directly comparing teams that adopt decision tables to teams that don't is sparse: the technique is too small and pre-dates the modern empirical-SE era. The case rests on the definitional point that the table is exhaustive by construction.
Related¶
Exhaustive enumeration of a bounded input space, compressed several ways
These methods all exhaustively enumerate a bounded input space; each compresses
the exponential blow-up a different way. Decision
tables compress losslessly: a "don't-care"
entry folds together combinations that share an outcome, so every case still
maps to one rule, and the row carries its own expected decision. Combinatorial
and pairwise testing sample: a
covering array keeps every t-way interaction and drops the higher-order ones,
with the oracle supplied separately. Bounded-exhaustive property
testing bounds the size: it
enumerates every value up to a depth/size k (SmallCheck), relying on the
small-scope hypothesis that faults surface small. Exhaustive
coverage runs from MCC (the full 2ⁿ
truth table) down to MC/DC's n+1 independence criterion, and audits an
existing suite rather than generating one. Type systems reach the same
completeness by construction: an exhaustiveness check on a match / switch
over a sum type has the compiler verify every variant is handled, with no case
written by hand. State-, path-, and schedule-space
enumerators such as model checking, symbolic execution, and systematic
concurrency testing share the idea over a different space; see the reachability
clusters.
Classification¶
- Quality dimensions: Functionality: conformance (a regulated rule set is a declared standard, and the table is the artifact stakeholders outside engineering read and approve).
- Area: Eligibility rules, pricing, access control, regulatory rules, insurance and tax logic, feature-flag decisions, anywhere business logic combines several conditions into one decision.
- Guarantee: Exhaustive — by construction, no case is missing.
Referenced by¶
- Guarantee · The axes
- Exhaustive coverage (MC/DC, MCC) · Methods
- Formal methods · Methods
- Model checking · Methods
- Requirements quality checking · Methods
- State machines and statecharts · Methods
- How AI fits into software quality · AI
- Choosing methods · Overview
References¶
-
Wayne, Hillel. 2018. Decision Tables. https://www.hillelwayne.com/post/decision-tables/. ↩