Reading test data from JSON in Selenium Python - Build an Automation Script
import json from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException # Load test data from JSON file def load_test_data(filepath): with open(filepath, 'r', encoding='utf-8') as file: return json.load(file) def test_login_with_json_data(): data = load_test_data('testdata.json') username = data['username'] password = data['password'] driver = webdriver.Chrome() wait = WebDriverWait(driver, 10) try: driver.get('https://example.com/login') # Wait for email input and enter username email_input = wait.until(EC.element_to_be_clickable((By.ID, 'email'))) email_input.clear() email_input.send_keys(username) # Wait for password input and enter password password_input = wait.until(EC.element_to_be_clickable((By.ID, 'password'))) password_input.clear() password_input.send_keys(password) # Wait for login button and click login_button = wait.until(EC.element_to_be_clickable((By.ID, 'loginBtn'))) login_button.click() # Wait for URL to change to dashboard wait.until(EC.url_to_be('https://example.com/dashboard')) assert driver.current_url == 'https://example.com/dashboard', f"Expected URL to be dashboard but got {driver.current_url}" except TimeoutException as e: assert False, f"Timeout waiting for element or URL change: {e}" finally: driver.quit() if __name__ == '__main__': test_login_with_json_data()
This script starts by loading the username and password from an external JSON file named testdata.json. This keeps test data separate from code, which is a good practice.
We use Selenium WebDriver to open the login page. Explicit waits ensure the script waits until the email and password fields and the login button are clickable before interacting with them. This avoids errors from trying to use elements too early.
After entering the credentials and clicking login, the script waits until the URL changes to the dashboard URL. Then it asserts that the current URL is exactly the dashboard URL, confirming successful login.
Try-except blocks catch timeout exceptions to fail the test gracefully if elements do not appear in time.
Finally, the browser is closed in the finally block to clean up regardless of test outcome.
Now add data-driven testing with 3 different sets of login credentials read from the JSON file
Practice
Solution
Step 1: Understand test data separation
Reading test data from JSON separates data from test logic, making code cleaner.Step 2: Recognize flexibility advantage
Updating test data in JSON does not require changing test scripts, improving flexibility.Final Answer:
It keeps test code clean and makes data easy to update without changing code. -> Option DQuick Check:
Data separation = Clean code + Easy updates [OK]
- Thinking JSON speeds up test execution
- Believing JSON auto-generates tests
- Confusing data storage with encryption
data.json into a variable test_data?Solution
Step 1: Identify correct json module usage
The json.load() function reads JSON from a file object, so open() must be passed to json.load().Step 2: Check syntax correctness
import json test_data = json.load(open('data.json')) correctly imports json and uses json.load(open('data.json')) to read the file.Final Answer:
import json\ntest_data = json.load(open('data.json')) -> Option AQuick Check:
json.load + open(file) = correct JSON read [OK]
- Using json.loads() on filename string
- Forgetting to import json module
- Calling non-existent json.read() function
user.json with content:{"username": "testuser", "password": "pass123"}and the code:
import json
with open('user.json') as f:
data = json.load(f)
print(data['username'])What will be the output?
Solution
Step 1: Load JSON data into dictionary
The json.load(f) reads the JSON file and converts it into a Python dictionary with keys 'username' and 'password'.Step 2: Access dictionary value by key
data['username'] accesses the value 'testuser' from the dictionary.Final Answer:
testuser -> Option CQuick Check:
data['username'] = 'testuser' [OK]
- Printing the whole dictionary instead of key value
- Using wrong key causing KeyError
- Confusing json.load() with json.loads()
import json
file = open('data.json')
data = json.load(file)
file.close()
print(data['email'])Assuming
data.json does not contain the key email.Solution
Step 1: Understand json.load() behavior
json.load() correctly reads JSON from an open file object, so no error here.Step 2: Identify missing key issue
Accessing data['email'] when 'email' key is missing causes a KeyError at runtime.Final Answer:
The code will raise a KeyError because 'email' key is missing. -> Option AQuick Check:
Missing key access = KeyError [OK]
- Thinking json.load() fails on open files
- Ignoring possible missing keys in JSON
- Assuming file.close() is missing or wrong
login.json contains:{"username": "user1", "password": "pass1"}Which code snippet correctly reads the JSON and uses Selenium to fill the form fields with ids
user and pass?Solution
Step 1: Correctly read JSON file
json.load(f) reads JSON from file object correctly; json.loads() expects a string, so import json with open('login.json') as f: data = json.loads(f) driver.find_element_by_id('user').send_keys(data['username']) driver.find_element_by_id('pass').send_keys(data['password']) is wrong.Step 2: Use correct Selenium locator method
driver.find_element('id', 'user') is the modern syntax to find element by id; find_element_by_id() is deprecated.Step 3: Match locators with element ids
The form fields have ids 'user' and 'pass', so locating by id is correct, not by name.Final Answer:
import json with open('login.json') as f: data = json.load(f) driver.find_element('id', 'user').send_keys(data['username']) driver.find_element('id', 'pass').send_keys(data['password']) -> Option BQuick Check:
json.load + find_element('id', ...) = correct usage [OK]
- Using json.loads() on file object
- Using deprecated find_element_by_id()
- Using wrong locator type (name instead of id)
Ready to prove it?
Pass the test and this pattern moves unknown
