Your language · Python
Files and input/output
Reading and writing files, paths, and reading test data.
Learn: Files and input/output in Python8 minute read
Input/output (I/O) means reading data into a program and writing data out. In a Python test framework that mostly means files: settings, CSV (comma-separated values) and JSON (a text format for structured data) test data, expected responses, logs and downloaded reports. The standard library covers all of it. Interviewers usually ask you to read a file line by line, read a config file, and explain why with matters. The standard library means the modules that come with Python.
Step 1: open() and with
open(path, mode, encoding=...) returns a file object. Use it in a with block, which closes the file when the block ends, even if an exception is raised. The mode says what you want to do:
"r"(the default) reads; a missing file raisesFileNotFoundError."w"writes; it creates the file or empties an existing one."a"appends to the end, which suits logs."x"creates a new file and raisesFileExistsErrorif it already exists.- Add
"b"for binary data (raw bytes, not text) such as images or PDFs.
Always pass encoding="utf-8" for text. An encoding is the rule that turns bytes into characters, and in Python 3.12 the default comes from the system settings, so it can differ between machines. Reading bytes with the wrong encoding raises UnicodeDecodeError or gives wrong characters.
Step 2: reading line by line
Looping over a file object reads one line at a time, so it works for files of any size. Each line still ends with "\n", so strip it. For small files, Path.read_text().splitlines() gives a list without line endings.
from pathlib import Path
Path("users.txt").write_text("asha\nravi\n\nbea\n", encoding="utf-8")
with open("users.txt", encoding="utf-8") as f:
for number, line in enumerate(f, start=1):
name = line.strip()
if name:
print(number, name)
lines = Path("users.txt").read_text(encoding="utf-8").splitlines()
print(lines)
with open("run.log", "w", encoding="utf-8") as log:
log.write("start\n")
with open("run.log", "a", encoding="utf-8") as log:
log.write("done\n")
print(Path("run.log").read_text(encoding="utf-8").splitlines())
try:
open("missing.txt", encoding="utf-8")
except FileNotFoundError as e:
print("FileNotFoundError:", e.filename)
1 asha 2 ravi 4 bea ['asha', 'ravi', '', 'bea'] ['start', 'done'] FileNotFoundError: missing.txt
Step 3: pathlib and where a path points
pathlib.Path is the modern way to handle paths (a path is the location of a file or folder). You join parts with /, as in base / "data" / "users.csv", and use .exists(), .name, .parent, .mkdir(parents=True, exist_ok=True), .read_text() and .write_text(). It works the same on Windows, macOS and Linux.
A relative path (one that does not start at the drive or root, such as data/users.csv) is resolved against the current working directory, which is the folder pytest (the usual Python test tool) was started from, not the folder of the Python file. If you start pytest somewhere else, open("data/users.csv") fails. Anchor paths to the test file instead (__file__ is the path of the current Python file):
DATA_DIR = Path(__file__).parent / "data" users_file = DATA_DIR / "users.csv"
Step 4: CSV, JSON and config files
csv.DictReader reads rows as dicts keyed by the header and handles quoted commas, which line.split(",") does not; open CSV files with newline="". json.load(f) reads a file into dicts and lists, turning null into None. configparser reads .ini files (text files with [section] headers and key = value lines); values are strings unless you use getint or getboolean, and fallback= gives a default.
import csv, json, configparser
from pathlib import Path
Path("users.csv").write_text('name,role\nAsha,admin\n"Ravi, Jr",viewer\n', encoding="utf-8")
with open("users.csv", newline="", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
print(rows[1]["name"], "|", rows[1]["role"])
Path("expected.json").write_text('{"status": "ok", "items": [1, 2], "error": null}', encoding="utf-8")
with open("expected.json", encoding="utf-8") as f:
body = json.load(f)
print(body["status"], body["items"], body["error"])
Path("config.ini").write_text("[qa]\nbase_url = https://qa.example.com\ntimeout = 15\nheadless = yes\n", encoding="utf-8")
cfg = configparser.ConfigParser()
cfg.read("config.ini", encoding="utf-8")
qa = cfg["qa"]
print(qa["base_url"], qa.getint("timeout"), qa.getboolean("headless"), qa.get("browser", fallback="chrome"))
Ravi, Jr | viewer ok [1, 2] None https://qa.example.com 15 True chrome
How to answer in an interview
Write the with open(...) loop and explain each part: "with closes the file even on an error, iterating the file reads one line at a time, and I strip the newline." For test data, name the module per format (csv, json, configparser, PyYAML or openpyxl), say that paths are anchored to the test file, and that rows reach tests through pytest.mark.parametrize (a pytest feature that runs one test once per row of data).
Common mistakes
- Opening files without
with, so they stay open after an error. - Leaving out
encoding="utf-8"and getting different results on Windows. - Opening with
"w"when you meant"a", which wipes the file. - Splitting CSV lines on commas by hand.
- Using relative paths that depend on where pytest was started.
Recap
Open files in a with block, pick the right mode and always pass the encoding. Loop over the file object to read line by line. Use pathlib, anchored to Path(__file__).parent, for paths. Use the csv, json and configparser modules instead of parsing by hand, and keep secrets in environment variables.
8 questions0/8 solved
| Status | Question | Difficulty | Asked in |
|---|---|---|---|
| Not started | Read lines without the newline characters | Easy | Asked in: Infosys |
| Not started | Read a text or config file line by line | Easy-Medium | Asked in: Infosys |
| Pro+ | File modes: r, w, a and x | Easy-Medium | Asked in: Cognizant, Infosys |
| Pro+ | Reading CSV test data | Easy-Medium | Asked in: Infosys |
| Pro+ | Where does a relative path point? | Medium | |
| Pro+ | What json.load gives back | Easy-Medium | |
| Pro+ | Text encoding when reading files | Medium | |
| Pro+ | Reading test data from CSV, JSON, YAML and Excel in Python | Medium | Asked in: Infosys |
The first 2 questions of each topic are free. Pro+ opens every question.