> For the complete documentation index, see [llms.txt](https://docs.drizz.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.drizz.dev/writing-tests/which-variable/datasets.md).

# Datasets

A **dataset** is a named set of values bound to your tests at run time. One script covers many environments and accounts.

|                 |                                                                          |
| --------------- | ------------------------------------------------------------------------ |
| **Platforms**   | Android · iOS                                                            |
| **Authored as** | YAML key/value, in the Datasets area                                     |
| **Types**       | string · number · list · object                                          |
| **Nesting**     | **2 levels overall.** Deeper is rejected on save                         |
| **Watch out**   | Binding happens when a **test plan** runs, not when you write the script |

## Prerequisites

* Drizz desktop app installed and signed in
* A project containing the tests the dataset will drive
* A test plan, to bind the dataset to

## Copy this

The dataset — `shopease_staging`:

```yaml
app_package: com.shopease.android
phone: "9000000000"
otp: "123456"
city: Bangalore
search_term: running shoes
```

The test that uses it:

```
# ShopEase — login and search, driven by a dataset

OPEN_APP {{app_package}}
Wait Until 5 Seconds

Type {{phone}} in the mobile number field
Tap on Get OTP
Wait Until 2 Seconds

Type {{otp}} in the OTP field
Tap on Continue
Wait Until 5 Seconds

Tap on the search icon
Type {{search_term}} in the search field
Tap on the first search result
Wait Until 3 Seconds

Validate that the product detail page is visible
```

A second dataset pointed at production, bound instead, runs the same test there.

## Create and bind a dataset

1. Open the **Datasets** area of the desktop app.
2. Author the dataset as YAML key/value pairs.

   ```yaml
   app_package: com.shopease.android
   phone: "9000000000"
   otp: "123456"
   max_items: 5
   categories: [shoes, bags, watches]
   user:
     email: qa@example.com
   ```
3. Save the dataset. Save rejects more than two levels of nesting.
4. Reference each key in the script as `{{key}}`.
5. Open the test plan that runs those tests and select the dataset on its **Data set** tab.
6. Confirm the unresolved-variable counter reads zero. A plan can't be saved or run while a variable is unresolved.

## Value types

| Type   | Written as                                       | Notes                                                |
| ------ | ------------------------------------------------ | ---------------------------------------------------- |
| String | `city: Bangalore`                                | Quote anything that must stay a string               |
| Number | `max_items: 5`                                   | `otp: 012345` unquoted is read as the number `12345` |
| List   | `categories: [shoes, bags, watches]`             |                                                      |
| Object | `user:` then an indented `email: qa@example.com` | Reference as `{{user.email}}`                        |

## Nesting limit

Nesting is capped at **two levels overall**. This is accepted:

```yaml
user:
  email: qa@example.com
```

This is rejected on save:

```yaml
user:
  address:
    city: Bangalore
```

Flatten a third level into the key — `user_address_city: Bangalore`.

## Referencing a variable

| Form            | Resolves to                                                  |
| --------------- | ------------------------------------------------------------ |
| `{{key}}`       | The value of that key, anywhere a value goes, in any command |
| `{{key.field}}` | A field of an object value                                   |

```
OPEN_APP {{app_package}}
Type {{phone}} in the mobile number field
Validate that {{city}} is visible on the address bar
Type {{user.email}} in the email field
```

Names are **case-sensitive** and must match the dataset key exactly.

## Binding

Binding happens on the **test plan**, not in the script. Every `{{variable}}` in every test in that plan resolves from the bound dataset. The same test case is used by different people testing different cases, so the data belongs to the run rather than the file.

Running a single test from the editor prompts for its variable values for that one run.

A plan that contains variables but has **no test data bound at all** can misread `SET` steps. Bind a dataset — an empty one is enough — to any plan whose tests use variables.

## Editor behavior

| Signal               | Meaning                                                                                                                                                                       |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Green** token      | The variable exists in the selected dataset. Hover shows the bound value                                                                                                      |
| **Red** token        | The variable doesn't exist in the selected dataset. It resolves to nothing, and the run fails several steps later — most often as "element not found"                         |
| Autocomplete on `{{` | Suggests variables visible in the current context. Suggestions are fetched when typing pauses, not on every keystroke. Selecting one places the cursor after the closing `}}` |

Autocomplete isn't a complete list of everything a plan might bind. The dataset is the source of truth.

## Data that can't be shared

Login credentials, phone numbers and accounts mid-flow can't be used by two runs at the same time. Mark the dataset a **lockable pool** so each parallel run leases its own row. See [Lockable pools](/writing-tests/which-variable/lockable-pools.md).

## Common mistakes

<table data-search="false"><thead><tr><th>What you write</th><th>What happens</th></tr></thead><tbody><tr><td><code>otp: 012345</code> unquoted</td><td>Read as the number 12345. The leading zero is gone</td></tr><tr><td><code>{{Phone}}</code> when the key is <code>phone</code></td><td>Renders red, resolves to nothing</td></tr><tr><td>Three levels of YAML nesting</td><td>Rejected on save. Flatten the key</td></tr><tr><td>Picking a dataset while writing the script</td><td>There's nothing to pick. Binding happens on the plan</td></tr><tr><td><code>OPEN_APP {{shopease_staging}}</code> — the dataset name</td><td>Corrupts the value. Reference the key, not the dataset</td></tr><tr><td>A plan with variables and no dataset bound</td><td><code>SET</code> steps can be misread. Bind one, even an empty one</td></tr></tbody></table>

## Next

* [Lockable pools](/writing-tests/which-variable/lockable-pools.md)
* [Which variable do I use?](/writing-tests/which-variable.md)
* [Test plans](/running-tests/test-plans.md)

***

*Last updated: 6 August 2026*
