Data Handling in Test Automation: Libraries to Modern Frameworks
In the realm of software testing, test automation has come a long way from its humble beginnings. In the “olden days” of test automation, automation engineers faced unique challenges when it came to reading and writing data during the testing process. This article delves into the libraries and techniques that were commonly used in the past and highlights how the landscape has evolved with the advent of modern test automation tools.
File Input/Output Libraries
In the early days of test automation, reading and writing data to files were fundamental tasks. Engineers relied on language-specific libraries like Python’s open()
function and Java's FileInputStream
and FileOutputStream
. These libraries provided the basic file operations required for test automation.
CSV Libraries
CSV files were a common format for storing test data due to their simplicity and versatility. Automation engineers used libraries like Python’s csv
module and Java's Apache Commons CSV library to work with CSV data. These libraries facilitated the seamless extraction and manipulation of data from CSV files, making them invaluable tools for test automation.
XML and JSON Libraries
As technology advanced, the need to handle data in XML and JSON formats became essential for tasks like configuring test scenarios and working with web service responses. In Python, engineers turned to xml.etree.ElementTree
XML and the json
module for JSON. In Java, libraries like JAXB for XML and Jackson
or Gson
for JSON provided the means to interact with these data formats efficiently.
The Rise of Modern Test Automation Frameworks
It’s important to note that modern test automation has evolved significantly with the advent of specialized test automation frameworks and tools that provide higher-level abstractions and built-in support for reading/writing data, making automation more accessible and efficient. Today, reading and writing files is a common feature of most test automation tools and frameworks. It is used for a variety of purposes, including:
- Reading test data from files
- Writing test results to files
- Logging test steps and failures to files
- Generating test reports from files
Handling data using a library in test automation involves several key steps. First, import the relevant data handling library and open or access the data file. Next, read the data if necessary, perform test actions using the data, and write data back to the file if applicable. Always handle errors, clean up resources as needed, and verify test results. Maintain thorough documentation for reference and follow these steps for each test case and dataset in your automated test suite.
Modern tools have simplified the automation process by offering higher-level abstractions and built-in data-handling support. These tools have made it easier for automation engineers to manage data, leading to more efficient and effective testing processes. Below is an example of how to read and write a JSON file in the playwright world. Both functions, writeJsonFile
and readJsonFile
, are asynchronous and utilize async
and await
to handle promises sequentially.
writeJsonFile = async (filePath: string, jsonData: JSON) => {
try {
const jsonString = JSON.stringify(jsonData, null, 2); // Convert the data to a pretty-printed JSON string
await fs.writeFile(filePath, jsonString, 'utf-8');
console.log('JSON data has been written to the file.');
} catch (error) {
console.error('Error writing JSON data to the file:', error);
}
};
The writeJsonFile
function takes two parameters: filePath
(the path to the JSON file) and jsonData
(the JavaScript object to be written as JSON).
Within writeJsonFile
, the jsonData
object is converted to a pretty-printed JSON string using JSON.stringify
, with three arguments: the data, a replacer function (set to null
), and the number of spaces for indentation (set to 2
). The resulting JSON is then written to the file using fs.writeFile()
with filePath
, jsonString
, and 'utf-8'
encoding.
readJsonFile = async (filePath: string) => {
try {
const fileContents = await fs.readFile(filePath, 'utf-8');
const jsonData = JSON.parse(fileContents);
return jsonData;
} catch (error) {
console.error('Error reading JSON file:', error);
}
};
The readJsonFile
function reads the contents of a JSON file specified by the filePath
parameter.
To read a file’s contents asynchronously, the fs.readFile()
function is used. It takes in two arguments: the file path (filePath
) and encoding ('utf-8'
) to read the content as a UTF-8 encoded string. The fileContents
variable holds JSON data as a string. To work with it more easily, we convert fileContents
to a JavaScript object (jsonData
) using JSON.parse()
. The function returns jsonData
using the return
statement.
Both functions handle any errors that might occur during the process and provide feedback in the form of console messages for success or errors.
const currentDirectory = process.cwd();
fs.readdir(currentDirectory, (err, files) => {
if (err) {
console.error('Error reading directory:', err);
return;
}
console.log('Files in current directory:');
files.forEach((file) => {
console.log(file);
});
});
My recent publication compiled a comprehensive collection of 100 similar typescript programs. Each program not only elucidates essential Typescript concepts and expounds upon the significance of test automation but also provides practical guidance on its implementation using Playwright. This resource will undoubtedly be valuable if you look deeper into similar topics.