Framework · Python
Test data and configuration
Data-driven tests, configuration files and environments.
Learn: Test data and configuration in a pytest framework8 minute read
Test data is the input a test uses, such as user names, products and expected messages. Configuration is everything that changes between runs, such as the base URL, the browser and timeouts. Interviewers ask how your tests get their data, how you switch between environments (separate copies of the app, such as qa for testers and staging for last checks before release) and where secrets are kept. In pytest the answers are short: data files feed parametrize, a session fixture loads the configuration, and command-line options choose the environment.
Data-driven tests
"Data-driven" means the steps stay the same and only the data changes. With parametrize, each row of data becomes its own test with its own result:
import csv
import json
import pathlib
import pytest
DATA = pathlib.Path(__file__).parent / "data"
def csv_rows(name):
with (DATA / name).open(newline="", encoding="utf-8") as f:
return list(csv.DictReader(f))
LOGINS = csv_rows("logins.csv")
@pytest.mark.parametrize("row", LOGINS, ids=[r["case"] for r in LOGINS])
def test_login(login_page, row):
login_page.login_as(row["user"], row["password"])
assert login_page.message() == row["expected"]
csv.DictReader returns each row as a dictionary from column name to value. Every value is a string (text), so convert numbers yourself. JSON keeps numbers and true/false values: json.loads((DATA / "users.json").read_text()). For Excel, the openpyxl library (installed separately) reads sheets, for example with load_workbook(path).active.iter_rows(min_row=2, values_only=True). CSV and JSON show clear changes in Git and need no extra library, so prefer them unless business people maintain Excel files.
A case column used as the id makes reports readable: test_login[locked-account] says far more than test_login[row3].
Configuration per environment
Keep URLs, timeouts and flags out of the code. Use one file per environment and a session fixture that loads it:
# conftest.py
import json, os, pathlib, pytest
CONFIG_DIR = pathlib.Path(__file__).parent / "config"
def pytest_addoption(parser):
parser.addoption("--env", default="qa")
parser.addoption("--browser", default="chrome")
@pytest.fixture(scope="session")
def config(request):
env = request.config.getoption("--env")
data = json.loads((CONFIG_DIR / f"{env}.json").read_text())
data["browser"] = request.config.getoption("--browser")
return data
Now pytest --env=staging --browser=firefox switches both. pytest_addoption belongs in the root conftest.py. pytest rejects options it does not know, so every custom option must be declared there. Environment variables (named values set outside your program, in the shell or CI) are the other common source. CI means a server that runs your tests automatically, for example after every code change.
Secrets
Passwords and API keys never live in the repository. CI keeps them as secrets and passes them to the job as environment variables:
password = os.environ.get("TEST_USER_PASSWORD")
if not password:
pytest.exit("TEST_USER_PASSWORD is not set", returncode=2)
Locally, developers set the variable in their shell or in a file that Git ignores (one listed in .gitignore). Hide secrets in logs and reports.
Managing data across runs
- Reference data that rarely changes sits in files in version control.
- Accounts per environment sit next to the environment config, with passwords from CI.
- Data a test changes is created by the test, through an API (a way for code to talk to the app's server) in a fixture, with unique values, and removed in the fixture's teardown.
import uuid
@pytest.fixture
def new_user(api):
user = api.create_user(email=f"user_{uuid.uuid4().hex[:8]}@test.example")
yield user
api.delete_user(user["id"])
Data classes with defaults (@dataclass) or small factory functions let a test set only the fields it cares about. For files, the built-in tmp_path fixture gives each test its own empty folder, which suits downloads.
Independence
A test must pass alone, in any order and in parallel. With pytest-xdist (the plugin that runs tests in parallel) each worker is a separate process, so Python variables are never shared, but accounts and database rows still are. Unique data per test keeps parallel runs safe.
How to answer in an interview
When asked how you manage test data, name the three kinds (reference data, accounts per environment, data each test creates) and say where each lives. Give one example of a fixture that creates and removes its own data. Then cover secrets and switching environments in one sentence each.
Common mistakes
- Forgetting that CSV values are text, then comparing
"30"with30. - Reading
sys.argvfor custom options instead of declaring them withpytest_addoption. - Committing a password in a JSON config file.
- One test relying on data another test created. pytest has no built-in test dependencies, which is a hint to move that step into a fixture.
Recap
parametrize turns each data row into its own test. A session fixture loads one config file per environment, chosen with a --env option. Secrets come from CI environment variables. Fixtures create the data a test changes and remove it in teardown, so every test stands alone.
8 questions0/8 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Read test data from a file and drive tests with it (Python) | Medium | Asked in: Accenture, Capgemini, Infosys +4 |
| Not started | Choose browser and environment from the pytest command line | Medium | Asked in: Accenture, Cognizant, TCS +1 |
| Pro+ | Configuration for several environments (Python) | Medium | Asked in: Cognizant, TCS, Wipro |
| Pro+ | Manage and generate test data across runs and environments | Medium | Asked in: Capgemini |
| Pro+ | What csv.DictReader gives you for test data | Easy-Medium | Asked in: Accenture, Capgemini, Infosys +4 |
| Pro+ | Unique test data for every run | Easy-Medium | Asked in: Capgemini |
| Pro+ | Avoid shared state: keep every test independent | Medium | Asked in: Happiest Minds, Honeywell |
| Pro+ | Where do test passwords and API keys belong? | Easy | Asked in: Cognizant, TCS, Wipro |
The first 2 questions of each topic are free. Pro+ opens every question.