Use when a feature has several independent inputs and the honest combination count is too large to run — roles by plans by locales, payment method by currency by coupon, OS by browser by network by font scale. Also when deciding which tier a test belongs in, and when a suite is red often enough that people re-run it instead of reading it.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add connorpham/vteam-harness --skill qa-combinatorial-design --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Qa Combinatorial Design?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/connorpham-qa-combinatorial-design)More formats (shields.io, HTML) on the badges page.
---
name: qa-combinatorial-design
description: "Use when a feature has several independent inputs and the honest combination count is too large to run — roles by plans by locales, payment method by currency by coupon, OS by browser by network by font scale. Also when deciding which tier a test belongs in, and when a suite is red often enough that people re-run it instead of reading it."
---
# Combinatorial design — choosing the case count, and defending the number
## Identity
You never answer "how many cases?" with the exhaustive count or a number you felt
like. You count the combinations, pick a strength you can justify, generate the set,
and have a machine prove it covers what you claimed. A test at the wrong tier is a
liability, and a suite that gets re-run rather than read has stopped being a test.
## When this applies
- Two or more inputs vary independently and their product is large.
- A platform or compatibility matrix must be tested on a budget.
- A decision has several boolean conditions and an outcome table.
- Someone proposes "test all combinations" or only the happy path.
- A test's tier has not been argued, or the suite fails intermittently.
## Decide
| Question | Choose | Because |
|---|---|---|
| Interaction strength | **2-way (pairwise)** by default; 3-way+ on paths that move money, grant access or delete data | NIST, verbatim: *"most failures were caused by one or two parameters, with progressively fewer by three or more"* |
| Upper bound to consider | **4-way to 6-way** | NIST, verbatim: in multiple case studies *"4-way to 6-way combination coverage was able to detect all faults found with exhaustive testing"* |
| Whether pairwise is "enough" | Never claim it is — state the strength and the escalated paths | The quoted "pairwise finds 80–93% of faults" figures are secondary and could not be confirmed in NIST primary sources |
| Ordered numeric or date range | Boundary values; say **2-value** or **3-value**, and match the increment to the data type (0.01 for money) | 2-value = boundary plus one outside (`99,100`); 3-value adds one inside (`99,100,101`) |
| Boolean conditions to outcomes | A **decision table**; collapse rules with identical actions using "don't care" | n conditions give 2ⁿ rules; collapsing is how 4 becomes 3 without losing a case |
| Which tier a test goes in | The **cheapest tier that can hold the assertion** | Fowler: *"Push your tests as far down the test pyramid as you can"* |
| Suite fails intermittently | Measure **your own** flake rate: run it **10×** with no code change | Published figures for large codebases are motivation; your number is the evidence |
| A flaky test blocking CI today | Quarantine to a non-blocking suite with a one-sprint deadline to fix or **delete** | A permanent quarantine is a deleted test that still costs time |
## Rules
- **Count the exhaustive product and write it down before choosing anything.**
*Otherwise:* you cannot say what you cut, so nobody can judge the risk.
- **Name the coverage strength in the plan: "2-way, all pairs covered".**
*Otherwise:* "we tested the combinations" is unfalsifiable.
- **Have a tool prove the coverage, not a person**, and exclude impossible
combinations with an explicit constraint. *Otherwise:* a hand-built matrix silently
misses pairs, or the generator spends cases on unreachable states.
- **Pairwise does not replace boundary analysis — run both.** Pairwise covers
interaction; boundaries cover edges. *Otherwise:* you test 16 tidy combinations and
never send `max+1`.
- **Escalate strength on paths that move money, grant access or delete data.**
*Otherwise:* a partial technique met a total requirement.
- **Argue the tier for every new test in the PR.** *Otherwise:* the suite drifts into
an ice-cream cone and every run costs minutes for coverage a unit test could hold.
- **Test observable behaviour, not internal calls.** *Otherwise:* the test breaks on
every refactor and proves nothing.
- **Measure flake rate before debating it, and quote your number.** *Otherwise:* the
argument is about vibes and the fix is "re-run".
- **Fix the non-determinism, not the symptom** — classify by root cause: timing,
network, state pollution, order dependence, contention. *Otherwise:* you add a
longer `sleep` and move on.
## Rationalizations
| Excuse | Reality |
|---|---|
| "We'll test all the combinations." | Five inputs of 3–4 values is 108–1024 runs. You will not, so decide deliberately. |
| "We'll just test the main flow." | That is 1-way coverage, and NIST puts most of the fault mass at two. |
| "It only fails sometimes." | In large suites most pass→fail transitions are flake, so intermittent red destroys your signal. |
| "Just re-run the pipeline." | You have replaced a test suite with a coin toss. |
## Red flags
- A case count with no stated strength; a matrix maintained by hand.
- Boundary cases absent from a plan that has combination cases, or the reverse.
- A decision table with 2ⁿ rules and no collapsing.
- "Re-run" appearing in a CI discussion more than once.
- A quarantine list with no dates; `sleep` as synchronization; new e2e tests for logic a unit test could assert.
## Example
Ticket: "role, plan and locale all affect the billing screen" — 4 × 4 × 4. Wrong: run
the three the developer mentioned, or ask for 64 runs. Right: state the exhaustive
count (64), choose 2-way, generate an all-pairs set and verify it — **16 cases covering
100% of the 48 required pairs**, machine-checked. A 3×3×3×2×2 payment form collapses to
13. Then add boundary cases for the amount (`0`, `0.01`, `max`, `max+0.01`) and
escalate "downgrade a paid plan" to 3-way because it moves money. The plan now names a
number, a strength and a proof.
## Reviewer lens
- What is the exhaustive combination count, and what strength was chosen?
- What proves the set covers that strength — a tool, or a person's word?
- Are impossible combinations excluded by an explicit constraint?
- Do boundary cases exist alongside the combination cases?
- Which paths were escalated above 2-way, and why those?
- For each new test: why this tier and not one lower?
- What is the current flake rate, and how was it measured?
## Sources
NIST CSRC "Interactions Involved in Software Failures" — two statements verified
verbatim against the primary page. The repeated "93% of NASA failures were 2-way" and
"pairwise finds ~80%" figures were checked in NIST primary sources and could **not**
be confirmed, so nothing here rests on them. Martin Fowler, *The Practical Test
Pyramid* — tier rules quoted verbatim. ISTQB definitions for equivalence partitioning,
2-value vs 3-value BVA and decision tables. Flake figures come from secondary
literature, hence the rule to measure your own. All-pairs generation implemented and
machine-verified. Complements `qa-test-design` and `qa-hostile-inputs`, which cover
boundaries and hostile values but not combinatorial strength, decision tables or
tier choice.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!