Product documentation
Updated July 6, 2026

Data-Driven Testing

Run a test once per row of data—from an internal table, a saved dataset, a data source, or a generator—binding columns to request fields with {{row.COLUMN}} tokens.

Overview

Data-driven testing runs a single test once for every row of data. You attach data to a test, bind columns to request fields, and Shift Left Studio iterates the test across the selected rows. This guide walks the Data-driven testing panel in the test editor exactly as it appears in the UI. Explore the capability at data-driven testing.

This panel uses {{row.COLUMN}} tokens (and generator {{ … }} tokens). It is a different system from Data Sources, which use [[variable]] tokens — never mix the two. For reusable external connections, see Data sources.

Before you begin

  • Open the test you want to iterate (a test inside a project → feature → endpoint).
  • Scroll the test editor to the Data-driven testing panel. It shows a heading Data-driven testing with an On / Off toggle on the right and the subtitle "Run this test once for every row of data — a CSV/Excel file, a saved dataset, an internal table, or generated data."
  • To use a Saved dataset, you first need a dataset in this project (see Datasets below). To use a Saved data source, create one first — see Data sources.

Step 1 — Turn on data-driven testing

  1. Click the toggle at the top-right of the panel. It flips from Off to On and the configuration area expands beneath a divider.
  2. Leaving it Off runs the test normally (a single execution).

Step 2 — Choose a data source

Under Data source, pick one of four options from the dropdown:

OptionWhat it does
Internal data tableType columns inline and add rows by hand — no file or saved object needed.
Saved data source (CSV / Excel / DB / API)Reuse a saved data source. Columns load automatically.
Saved datasetReuse a versioned, project-scoped dataset created in the Datasets area.
Random generatorGenerate synthetic rows on the fly from generator field types.

Switching the source clears the others so a leftover empty source can't conflict with your selection.

Internal data table

  1. In the Columns (comma separated) field, type your column names, for example name, age, token.
  2. A grid appears with one column per header. Click + Add row to add rows, and fill each cell. Use the at the end of a row to remove it.

Saved data source

  1. Choose a source from the Select a data source… dropdown (each entry shows its name and type, e.g. Customers (CSV)).
  2. Columns and a preview load automatically. The panel reminds you: "Bind columns with column → target, or reference them as {{row.COLUMN}} in any field. Tip: enable 'has headers' on the data source so columns are named."

Saved dataset

  1. Choose a dataset from the Select a dataset… dropdown.
  2. Use Refresh to reload the list (for example, after creating a dataset in another tab), or Manage datasets ↗ to open the Datasets area in a new tab.
  3. If the project has none, the panel shows "No saved datasets in this project yet." with a Create one ↗ link.

Random generator

  1. Set How many rows (the row count, default 5) and an optional Seed (for repeatable data) — the same seed always produces the same rows.
  2. Click + Add field for each column. Give it a column name (e.g. email) and pick a generator type from the dropdown.
  3. Available generator types include: uuid, sequence, int, float, bool, firstName, lastName, fullName, email, phone, city, country, address, company, postalCode, creditCard, cvv, iban, time, date, pastDate, futureDate, word, words, lorem, and pattern.

Step 3 — Choose which rows run (iteration mode)

Set the Iteration mode dropdown to control which of the source rows are used:

ModeExtra inputRuns
everyevery row
firstNNumber of rowsthe first N rows
lastNNumber of rowsthe last N rows
rangeFrom row (0-based) and To row (inclusive)a contiguous slice
specificRow index (0-based)one specific row
randomHow many random rowsa random sample
uniquede-duplicated rows
filtereda Filter JSON fieldrows matching the filter

For filtered, enter a small JSON filter, for example [{"field":"status","op":"eq","value":"active"}].

Step 4 — Bind columns to the request

Map each column to a place in the outgoing request. Under Bind columns to the request:

  1. Click + Add binding to add a mapping row, or Auto-map columns to create one binding per detected column at once (this appears once a preview has loaded columns).
  2. Each binding row reads column → target · target path · transform:
FieldWhat it does
columnThe source column name to read from each row.
targetWhere to place the value: query, path, header, cookie, body, or form.
target (key or body.path)The parameter name or a dotted body path (e.g. user.id).
transformOptional value transform: uppercase, lowercase, trim, base64, number, or no transform.
  1. Use the at the end of a row to remove a binding.

Alternatively (or in addition), reference any column directly inside any parameter, header, or body field as {{row.COLUMN}} — for example {{row.token}}. Typing {{ in a request field opens autocomplete listing your data columns and the generator tokens; use ↑↓ to navigate and Enter or Tab to insert. Unknown tokens are left untouched.

Step 5 — Set execution options and preview

At the bottom of the panel:

ControlWhat it does
Parallel threadsHow many rows run concurrently (default 1).
On row failureWhat happens when a row fails: continue, stop, or skip.
Preview iterationsRuns a dry preview without sending real requests.

Click Preview iterations. The panel reports how many rows are selected — for example "5 of 12 rows selected → 5 iteration(s)" — and shows a sample table of the first rows (up to 10). Errors appear in red; a "Loading data…" note shows while it fetches.

Expand Dynamic values you can use ({{ … }}) to see a cheat-sheet listing {{row.COLUMN}} for each of your columns plus the generator tokens.

Step 6 — Manage datasets

Datasets are reusable, project-scoped, versioned data tables. Open the Datasets area (the Manage datasets ↗ link from the panel, or #/datasets). There you can:

  • Create an internal data table — enter a Dataset name, Columns (comma separated), and rows (one row per line, comma-separated values), then click Create dataset.
  • Import a dataset — enter a Dataset name, choose a format (CSV, JSON, or YAML), paste the file content into the Paste file content box, and click Import.
  • Export CSV / Export JSON — download a dataset in either format.
  • Archive — archive a dataset you no longer need (confirmation required).

Each dataset row shows its source type, version (e.g. v3), and cache policy. Back in the test, select the dataset under Saved dataset and click Refresh if it isn't listed yet.

Step 7 — Review the results

After a data-driven run, the Data-driven iterations grid shows one row per iteration, with a header count such as "4/5 passed". Columns are:

ColumnShows
#Iteration number (1-based).
StatusPASSED, FAILED, ERROR, or SKIPPED.
RowA short label of the row that was used.
HTTPThe HTTP status code returned.
Failed fieldThe first failing assertion's field (blank when the row passed).
TimeResponse time in milliseconds.

Troubleshooting

  • No columns to bind — for a data source, make sure Has Headers is enabled so columns are named; otherwise click Preview iterations to detect columns.
  • A column shows blank in the request — confirm the binding column name matches the header exactly, or that your {{row.COLUMN}} token spells the column exactly.
  • Wrong number of iterations — check the Iteration mode and its arguments (for example a firstN value or a range that is out of bounds).
  • Preview error — the source may be unreachable or misconfigured; open the underlying dataset or data source and verify it loads.

Related articles

Next steps

Still stuck?

Tell us what you’re trying to accomplish and we’ll point you to the right setup—installation, auth, or CI/CD wiring.