skip to content

Data-Driven Variants

One case run once per row of a stored variant table: where the values sit, how a placeholder in a step binds to one, and why a failing row is one failing execution, not a failing case.

on this pageshow

explore

questions

4

In a TestRail- or Xray-class test case repository, what does attaching a variant table to one stored case do, and how does a placeholder in a step get its value?

level: juniorimportance: must knowfreq 72%

answer

  1. one stored case, many rows
  2. steps authored once, values vary
  3. placeholder names a column
  4. expansion happens at run generation
  5. one row, one execution record

basics

~20 s

A variant table holds one row of values per run of the same stored case. Placeholders in the step text name a column, and the repository substitutes that row's value, producing one execution per row.

solid answer

~40 s

A data-driven case is one stored case with a small table of values bound to it: each column is named, each row is one variation. The steps are authored once, with placeholders that name a column instead of holding a literal value. When the case goes into a run, the repository expands it into one execution per row, substituting that row's values into the step text so the tester reads concrete values and records an outcome for that row alone. Binding is by column name, so the same placeholder can appear in several steps and again in an expected result. The point is leverage: twelve rows give twelve executions but still one set of steps to maintain, one place to fix a typo, and one case in the inventory.

go deeper

for a junior

Be able to say plainly that one case plus a twelve-row table runs twelve times, and that a placeholder in a step is replaced by the value from that row's named column.

for a middle

Explain the mechanics: binding is by column name rather than position, expansion happens when the executions are generated, and the same placeholder resolves identically everywhere it appears in that row.

for a senior

Show where the shape breaks in practice - renamed columns leaving unresolvable steps, rows that quietly need an extra step, and the linear tester cost of a wide table on a manual case.

for a principal

Own the economics: the table multiplies executed volume without multiplying maintained artefacts, which also means case counts stop describing the work. Say how you would keep sizing honest.

## What a data-driven case actually is A **data-driven case** — a variant case, a parameterised case, an iteration case; the label differs by product — is **one** stored case with a small table of values attached to it. The table has named columns and one row per variation. The steps are authored once. Nothing about the steps is repeated per row, and nothing about a row is repeated inside the steps. Four terms carry the whole idea: - **Variant table** — the rows of values bound to the case. Each **column** has a name; each **row** is one complete set of values. - **Placeholder** — a marker inside a step's action text, its expected result, or a precondition that names a column instead of holding a literal value. - **Binding** — substituting, for one row, that row's value into every placeholder that names that column. - **Execution** — one recorded attempt of that case with one row bound in. ## How a placeholder gets its value 1. The author writes the steps once, putting a placeholder wherever the value varies. 2. The author fills the table: one column per varying value, one row per variation. 3. The case is put into a run or cycle, and the repository **expands** the single case into as many executions as the table has rows. 4. Each execution renders its own step text with its own row substituted, so the person testing reads concrete values rather than markers. 5. An outcome is recorded against that execution — that is, against that row — and not against the stored case. Two properties of step 4 matter more than they look. First, **binding is by column name, not by position**: the same placeholder may appear in several steps and again in an expected result, and every occurrence resolves to the same value for that row. Reordering columns changes nothing; renaming a column breaks every step that referenced the old name. Second, the substitution normally reaches the text the execution is listed under, which is what lets a reader tell row four from row nine in a list of results without opening either one. Notice what the author never does: they never copy the steps, and they never edit the case between rows. The repetition is the repository's job, and it happens at the moment executions are generated, not at the moment the case is saved. ## What multiplies, and what does not | Thing | With a twelve-row variant table | |---|---| | Stored cases in the inventory | 1 | | Sets of steps to maintain | 1 | | Places to fix a typo in a step | 1 | | Executions produced by one run | 12 | | Outcomes recorded | 12 | | Rows that can fail independently | 12 | That asymmetry is the whole reason the shape exists. The count of **what you ran** multiplies; the count of **what you maintain** does not. Adding coverage becomes appending a row instead of cloning a case, and cloning is exactly what turns a repository into a place where the same wrong expected result is stored eleven times and corrected in one of them. ## Where the arrangement stops paying - **A row that needs an extra step is not a row.** As soon as the step text starts saying things like *if this row is a closed account, skip step four*, the variation has outgrown the table. - **A renamed or deleted column** leaves placeholders naming something that no longer exists. Depending on the product the run either refuses to expand that row or renders the marker as literal text, and the tester meets an instruction with a hole in it. - **Manual execution cost is linear in rows.** Authoring a row is nearly free; performing one is not. Forty rows on a case a person works through by hand is forty times the tester minutes. - **Values that mean something only in one environment** quietly turn a portable case into a local one, and it fails everywhere else for reasons that have nothing to do with the product. ## Three things this shape is not - **It is not a way of storing many cases.** Rows never surface in the inventory as cases. Anyone sizing the work by counting cases will undercount the executions by the size of the tables. - **It is not where the values come from.** Deciding which rows are worth having, and producing or protecting the values inside them, are separate concerns. The table is only where the chosen values sit and how they reach the steps. - **It is not a way to fail a case.** One bad row is one failed execution. The rows that passed passed, and re-running the whole case to re-check a single row is wasted effort that the per-row record exists precisely to prevent.

  • A column in the variant table is renamed but a step still names the old one. What does the run show?
    The placeholder resolves to nothing. Depending on the product the row either refuses to expand or renders the marker as literal text, and the tester is handed an instruction with a hole in it. Either way it is an authoring defect against the case, not a product failure, and the fix is to bring the step text and the column name back into agreement before the cycle starts.
  • Does appending rows to the table change how many cases the repository holds?
    No. The inventory still shows one case however wide the table gets. Only the execution volume grows. That is worth saying out loud, because anyone sizing a cycle by counting cases will undercount the real work by the size of every variant table in scope.

It is a mail merge. One letter is written, an address list supplies the rows, and printing produces one letter per address; a smudged copy of the third letter is a bad print, not a broken template.

saying these in an interview costs you the question

  • Says each variant row is a separate stored case
  • Expects the tester to edit steps between rows
  • Thinks placeholders bind by column position
  • Confuses the table with where values are sourced
  • Assumes one outcome covers the whole table
open as a page

A single row of a data-driven case fails during a run in a TestRail- or Xray-class repository. What has actually failed, and what should the run's record show?

level: seniorimportance: must knowfreq 62%

basics

~10 s

One execution failed, not the case. Each row produces its own execution record, so the failure carries that row's values, its own evidence and its own defect link, and only that row is retested.

open as a page

In a TestRail- or Xray-class case repository, what changes when a case's variant rows are stored inside the case itself rather than in a shared table several cases point at?

level: middleimportance: should knowfreq 55%

basics

~20 s

Rows stored inside the case make it self-describing and independent, at the cost of duplicating the same values across cases. A shared table gives one edit for every case bound to it, but changes their meaning invisibly.

open as a page

In a TestRail- or Xray-class case repository, how do you decide whether a variation belongs as another row in a case's variant table or as a stored case of its own?

level: principalimportance: nice to knowfreq 40%

basics

~20 s

Keep it as a row when only the values differ and the steps and expected result are identical. Split it into its own case when it needs different steps, a different expected result, or its own attributes.

open as a page