Data-Driven Testing with Eggplant Functional
The data-driven approach to testing provides an efficient, easy-to-manage method of performing repetitive tests that use a set of test data. Eggplant Functional and SenseTalk include various features that make data-driven testing simple.
Eggplant Functional supports the use of test data from various data sources, such as plain-text files, Microsoft Excel files, and databases, and SenseTalk includes commands and functions to access, manipulate, and parse data in powerful ways. This article demonstrates how to use Eggplant Functional to incorporate data-driven testing into your scripts.
You can also perform data-driven testing by using the Tables feature in Eggplant Functional and associating a data file with a Table test.
For information about using data files to create a keyword-driven framework, see Creating a Custom Keyword-Driven Framework.
On this Page:
What Is Data-Driven Testing?
Data-driven testing is the concept of using an external data set as test input. The test might use input data in various ways, such as to specify text that is entered into a form on the application under test, to validate displayed values against expected values, or to establish a set of test constants.
The test is written generically using parameterization, such that it is able to receive the data in the data source. The data used by the test can be altered by manually editing the original data source, pointing the test to a new data source, or automating updates to the data source.
In the sections below on connecting to data sources, the sample SenseTalk code shows examples of using external data for data-driven testing.
Data Sources
A data source, which contains the test data for use in automation, is required for data-driven testing. Eggplant Functional supports the following data source types:
- Plain text (.txt, .csv, .xml, etc.)
- Excel (.xlsx)
- Open Database Connectivity (ODBC) databases
The data source you use determines both how you use SenseTalk to access the data source and how you parse the data.
Data Source Storage
When you use plain-text or Excel data sources, the file must be accessible to the local file system of the Eggplant Functional machine, which can include networked or shared drives.
Note: If you're using Eggplant Functional on Windows, shared drives must be mapped to letters (e.g., D:\). UNC paths are not supported.
The suite Resources pane provides a simple method for storing plain-text and Excel data files within your suite. You can then easily reference those files from your scripts by using the ResourcePath() function.
For databases, communication between Eggplant Functional and the database is managed by an ODBC Administrator configured on the Eggplant Functional machine.
Plain-Text File Interaction
Using a plain-text file is often the simplest way to implement a data-driven testing strategy with Eggplant Functional.
File Access
For background on accessing the contents of plain-text files, see the documentation on File and Folder Interaction and Accessing a File as a Container.
When accessing the content of plain-text files, using the open file and close file commands is not required. However, if you're performing many rapid read/write events against the file, using the open file and close file commands is recommended. In most cases of data-driven testing, the file is accessed only once, or it is accessed infrequently, so these commands are not needed.
The easiest way to interact with a plain-text file is to access it as a container by using the put or set command. Include the file extension (e.g., .txt, .csv) when referencing the file. For example:
Set MyPrices to file ResourcePath("prices.txt") -- The data file is stored in the Resources of the suite
Set MyProducts to file "C:\Users\Carrie\Desktop\products.csv" -- The data file is stored elsewhere on the Eggplant machine
You can use chunk expressions to access parts of the file contents as containers. For example:
Set MyPrice to line 3 of file ResourcePath("prices.txt")
Parsing File Contents
The SenseTalk method you use for parsing a plain-text file's contents depends on whether the data is formatted as CSV or is in another format.
CSV-Formatted Files
For plain-text files that follow a CSV format, including a header row, the CSVValue() Function provides the easiest method to work with the file's contents because it automatically parses header rows. You can use CSVValue() to access data based on header names within a SenseTalk script.
The contents of a basic plain-text file named LoginCredentials.csv that follows CSV format might look like this:
username,password
admin,adminpass
user,userpass
CSVValue() converts the CSV-formatted contents of a file into a list of property lists, where the header row of the contents is used to specify the property names, and the subsequent rows are used to specify the property values. Each row below the header has its own property list within the list of property lists. For example:
put CSVValue(file resourcePath("LoginCredentials.csv"))
Creates the following list of property lists:
((password:"adminpass", username:"admin"),(password:"userpass", username:"user"))
Individual property lists can be accessed using the list item chunk type:
Set Credentials to CSVValue(file resourcePath("LoginCredentials.csv"))
Log the first item of Credentials -- Logs '(password:"adminpass", username:"admin")'
Property values can be accessed in various ways, such as by using the possessive form with the header, or property, name:
Set FirstLogin to the first item of CSVValue(file resourcePath("LoginCredentials.csv"))
Log FirstLogin's password -- Logs 'adminpass'
Use repeat with each to iterate based on the items in the list, and access the properties:
Set Credentials to CSVValue(file resourcePath("LoginCredentials.csv"))
repeat with each item CredentialSet of Credentials
Set Username to CredentialSet's username
Set Password to CredentialSet's password
Click "UsernameField"
TypeText Username
Click "PasswordField"
TypeText Password
end repeat
Non CSV-formatted Files
Plain-text files such as the example file contents of SmokeTest.txt below can also be parsed based on the lines and text item chunk types.
TestName,Smoke
RemoteWorkInterval,.3
MouseClickDelay,.1
ImageUpdate,auto
According to the default values for the lineDelimiter and the wordDelimiter local properties, SenseTalk sees this file as having four lines, with each line having two text items, separated by commas. Chunk expressions can be used to access individual lines or text items. For example:
log the first item of line 3 of file resourcePath("smoketest.txt") -- Logs 'MouseClickDelay'
Often the container is instead parsed by a repeat loop so that the entire file contents can be iterated through. The repeat with each repeat loop allows easy iteration through a file based on chunks, such as lines. For example:
set SmokeTest to file ResourcePath("SmokeTest.txt")
repeat with each line myline of SmokeTest
log myline
end repeat
You can use a repeat loop to access text items from each line in the file:
set SmokeTest to file resourcePath("smoketest.txt")
repeat with each line myLine of line 2 to -1 of SmokeTest -- Starts iterating on the second line of the file and continues to the last line of the file
set SettingName to the first item of myLine
set SettingValue to the second item of myLine
Set the (SettingName) to SettingValue -- Sets an Eggplant global property value based on the global property name and value specified on the current line of the file
end repeat
Excel File Interaction
Microsoft Excel files provide a versatile and extensible method for storing data, which makes them well suited for data-driven testing scenarios.
File Access
You can store Excel (.xlsx) files either in the suite Resources pane or elsewhere on the Eggplant Functional machine's file system.
You can access Excel files by two methods:
The method you choose affects the format of the retrieved Excel file contents, and therefore affects how you use SenseTalk to parse the contents.
Here is an example of an Excel file's contents:
To access the contents of the file as a database, use code such as this:
set myExcelDB to (type: "excel", file: ResourcePath("LoginCredentials.xlsx"))
Set Credentials to the records of myExcelDB
The records are returned in the form of a list of property lists:
((password:"adminpass", username:"admin"),(password:"userpass", username:"user"))
Note how the header row of the Excel file is used to determine the property names (password and username).
You can use where expressions to limit which records are gathered from the Excel file:
Set Credentials to the records of myExcelDB where "username" is "admin" -- Stores the list of property lists ((password:"adminpass", username:"admin")) into Credentials
To access the contents of the Excel file as an Excel file, use code like the following, combining the workBook(), workSheet(), and cellRange() functions:
set Credentials to WorkBook(ResourcePath("LoginCredentials.xlsx"))
set myCredentials to Credentials.Worksheet("LoginSet")
set CredentialList to cellRange("A:B") of myCredentials
log CredentialList
The rows are returned as a list of lists, also known as a nested list:
((username,password),(admin,adminpass),(user,userpass)).
Note how the header row is included in the returned contents as the first item in the list.
Parsing File Contents: Excel as a Database
When you connect to an Excel file as a database, you can access specific records based on their position in the list of returned records, and access individual column values based on property names:
set myExcelDB to (type: "excel", file: ResourcePath("LoginCredentials.xlsx"))
set Credentials to the records of myExcelDB
set secondRecord to the second item of Credentials
log secondRecord's password -- Logs 'userpass'
Use repeat with each to iterate based on the items in the list, and access the properties:
set myExcelDB to (type: "excel", file: ResourcePath("LoginCredentials.xlsx"))
set Credentials to the records of myExcelDB
repeat with each item CredentialSet of Credentials
Set Username to CredentialSet's username
Set Password to CredentialSet's password
Click "UsernameField"
TypeText Username
Click "PasswordField"
TypeText Password
end repeat
Parsing File Contents: Excel as an Excel File
If you open an Excel file directly as an Excel file, you access specific rows based on their position in the list of returned rows, and values from specific cells in a row can also be accessed based on their position in the list representing a specific row:
set Credentials to WorkBook(ResourcePath("LoginCredentials.xlsx"))
set myCredentials to Credentials.Worksheet("LoginSet")
set CredentialList to cellRange("A:B") of myCredentials
Set secondRecord to the third item of CredentialList
Log the second item of secondRecord -- Logs 'userpass'
Use repeat with each to iterate based on the nested list's items.
set CredentialList to cellRange("A:B") of myCredentials
repeat with each item CredentialSet of item 2 to -1 of CredentialList
set Username to the first item of CredentialSet
set Password to the second item of CredentialSet
Click "UsernameField"
TypeText Username
Click "PasswordField"
TypeText Password
end repeat
ODBC Database Integration
You can use SenseTalk to access Open Database Connection (ODBC) databases for data-driving testing. For background in interacting with databases, see Working with Databases. For more in-depth information on ODBC database interaction see ODBC Administration.
Database Access
Eggplant Functional communicates through an ODBC Administrator in order to work with a number of databases.
Here's an example of a database table named logincredentials:
Use a database connection to access the records in a particular database table:
set myDB to (type:"odbc", DSN:"mySQLDB", user:"root", password:"eggPlant")
set Credentials to table "logincredentials" of myDB
set CredentialList to the records of Credentials -- Stores all records from the table in variable CredentialList
The records are returned in the form of a list of property lists:
((password:"adminpass", username:"admin"),(password:"userpass", username:"user"))
You can use where expressions to limit which records are gathered from the database table:
set CredentialList to the records of Credentials where "password" contains "admin" -- Stores '((password:"adminpass", username:"admin"))' into variable CredentialList
Parsing File Contents
For database connections, you access specific records based on their position in the list of returned records, and access individual column values based on property names:
set myDB to (type:"odbc", DSN:"mySQLDB", user:"root", password:"eggPlant")
set Credentials to table "logincredentials" of myDB
Set CredentialList to the records of Credentials
set firstRecord to the first item of CredentialList
log firstRecord's username -- Logs 'admin'
Use repeat with each to iterate based on the items in the list, and access the properties:
Set CredentialList to the records of Credentials
repeat with each item CredentialSet of CredentialList
Set Username to CredentialSet's username
Set Password to CredentialSet's password
Click "UsernameField"
TypeText Username
Click "PasswordField"
TypeText Password
end repeat
Data-Driven Testing: Use Case Example
The scripts here work together to open the Google Finance page in a web browser, search for a variety of companies by using their ticker symbols, and then use OCR to read the stock value for that company and store it in a variable in the script.
The main script references a data file that includes the following data in CSV format:
TickerSymbol,CompanyName
GOOG,Google
AAPL,Apple
RTN,Raytheon
FB,Facebook
F,Ford
UAL,United
Main Script: DataDrivenTest.script
// Runs script to navigate to Google Finance page OpenGoogleFinance
// Loads variable with data file
set datafile to CSVValue(file resourcePath("tickersymbols.csv")) // Loads data into variable 'datafile'
// Perform ticker symbol search for each company and log price for output
Repeat with each Ticker of datafile // Starts with the second line to skip the header row
DoubleClick global FinanceButton
TypeText Ticker's TickerSymbol // Enters the ticker symbol
Click "Magnifying Glass" // Performs search
WaitFor 10.0, "Refresh"
WaitFor 10.0, text: Ticker's CompanyName // Uses OCR to validate that the expected company name appears when searching for the symbol
Put ReadText("Top Left", "Bottom Right", validcharacters: "1234567890.") into Price // Uses OCR to read current share price
Put Ticker's CompanyName && Price & return after output // Uses Company Name and price in output
End Repeat
//Closes browser
Click "CloseBroswer"
// Logs the contents of output
Log output
Called Script: OpenGoogleFinance.script
This script opens the Google Finance page and gathers coordinates of the search box for use during ticker symbol searches.
// Navigates to finance page
DoubleClick "ChromeIcon"
WaitFor 30.0, "LuckyButton"
Click "More"
Click "Finance"
// Gathers coordinates of search box for repeated Google searches
WaitFor 30.0, "SearchFinance"
Put FoundImageLocation() into global FinanceButton