# Parameterize Tests

You can simply parameterize tests on a test level, via simple `for` loops e.g.:

```
const people = ['Alice', 'Bob']
describe('my tests', () => {
    for (const name of people) {
        it(`testing with ${name}`, async () => {
            // ...
        })
    }
})
```

or by extracting tests into dynamic functions, e.g.:

```
import { browser } from '@wdio/globals'

function testComponent(componentName, options) {
  it(`should test my ${componentName}`, async () => {
    await browser.url(`/${componentName}`)
    await expect($('input')).toHaveValue(options.expectedValue)
  })
}

describe('page components', () => {
    testComponent('component-a', { expectedValue: 'some expected value' })
    testComponent('component-b', { expectedValue: 'some other expected value' })
})
```

## Passing Environment Variables[​](#passing-environment-variables "Direct link to Passing Environment Variables")

You can use environment variables to configure tests from the command line.

For example, consider the following test file that needs a username and a password. It is usually a good idea not to store your secrets in the source code, so we'll need a way to pass secrets from outside.

```
it(`example test`, async () => {
  // ...
  await $('#username').setValue(process.env.USERNAME)
  await $('#password').setValue(process.env.PASSWORD)
})
```

You can run this test with your secret username and password set in the command line.

* Bash
* Powershell
* Batch

```
USERNAME=me PASSWORD=secret npx wdio run wdio.conf.js
```

```
$env:USERNAME=me
$env:PASSWORD=secret
npx wdio run wdio.conf.js
```

```
set USERNAME=me
set PASSWORD=secret
npx wdio run wdio.conf.js
```

Similarly, configuration file can also read environment variables passed through the command line.

```
export const config = {
  // ...
  baseURL: process.env.STAGING === '1'
    ? 'http://staging.example.test/'
    : 'http://example.test/',
  // ...
}
```

Now, you can run tests against a staging or a production environment:

* Bash
* Powershell
* Batch

```
STAGING=1 npx wdio run wdio.conf.js
```

```
$env:STAGING=1
npx wdio run wdio.conf.js
```

```
set STAGING=1
npx wdio run wdio.conf.js
```

## `.env` files[​](#env-files "Direct link to env-files")

To make environment variables easier to manage, consider something like `.env` files. WebdriverIO loads `.env` files automatically into your environment. Instead of defining the environment variable as part of the command call, you can define the following `.env`:

.env

```
# .env file
STAGING=0
USERNAME=me
PASSWORD=secret
```

Run tests as usual, your environment variables should be picked up.

```
npx wdio run wdio.conf.js
```

## Create tests via a CSV file[​](#create-tests-via-a-csv-file "Direct link to Create tests via a CSV file")

The WebdriverIO test-runner runs in Node.js, this means you can directly read files from the file system and parse them with your preferred CSV library.

See for example this CSV file, in our example input.csv:

```
"test_case","some_value","some_other_value"
"value 1","value 11","foobar1"
"value 2","value 22","foobar21"
"value 3","value 33","foobar321"
"value 4","value 44","foobar4321"
```

Based on this we'll generate some tests by using the csv-parse library from NPM:

```
import fs from 'node:fs'
import path from 'node:path'
import { parse } from 'csv-parse/sync'

const records = parse(fs.readFileSync(path.join(__dirname, 'input.csv')), {
  columns: true,
  skip_empty_lines: true
})

describe('my test suite', () => {
    for (const record of records) {
        it(`foo: ${record.test_case}`, async () => {
            console.log(record.test_case, record.some_value, record.some_other_value)
        })
    }
})
```
