Why Data Drive? A basic introduction into the advantages data-driving. Data Volatility Levels The different places to store different types of data. Storing Data in Properties Files How to store data in properties files. Using CSV Data in Test Scripts How to store data in CSV files. Using a Data Stored in Databases in Test Scripts How to Use Data from a Relational Database Management System (RDBMS). Referencing or Using Data in Test Scripts How to Reference Data Obtained from Various Data Sources in Jameleon Scripts.
Having an automated script do one thing well is nice, but the one scenerio is still just one of thousands of possibilities. One of the powers of automation is the ability to exercise the same script with different data. Data-driving an automated script could help find bugs never before imagined.
In Jameleon, data can be placed in several different places, depending on the how often the data changes. This is not a requirement, only a feature that could end up saving maintenance time in the future.
When creating more than one script, it is likely there will be data that is shared across multiple scripts. This makes the test cases less maintainable when a change to that particular value occurs.
The following is a simple list of how Data Volatility Levels differ in an automated script:
This type of data is data that changes between iterations of the script. Some examples of this might be the username used to log onto the application being tested. Another example might be the type of product to choose when ordering something; maybe the shopping cart behaves differently, depending on the product ordered. This data type would be considered highly volatile and might exist in and external data source like a database or a CSV file.
This type of data is not likely to change. Some examples of this data type might be the screen title, form field names, or even some text on a given screen. Jameleon has a mechanism to pull this type of data outside of the script. It can be stored in a file with the same name as your appplication, followed by .properties and it must be in the root of your CLASSPATH. For example, to test a customer support application, a good name for that application might be csr. Therefore a file named csr.properties would be created and put in the root of the CLASSPATH. This type of data could be considered low to non-volatile.
See the Variable Naming Standards section for more information on the format of this file.
This step can be skipped for applications existing only in one environment.
There is usually data that differs depending on the evironment the scripts are running against. For example, the way to start an application or to browse an application may differ between environments. Maybe a connection to a database to search for possible test data is required. This will likely also change when testing against the sandbox environment versus the QA test environment. This type of data will be shared across functional points that don't test the same areas of the application. Because these settings will likely be very small between applications, they are all listed in the same file.
See the Environment-specific Data section for more details and examples.
This step can be skipped for applications that function the same no matter where they are deployed or who uses them.
Sometimes there are applications with behavior that can be changed or configured. These type of applications have the same basic feature set, but the business rules may change for each organization.
Let's use a shopping cart as an example. A shopping cart's basic functionality is to sell products and manage orders. However, usually there are several other features that can be turned on/off and/or must be configured against a specific environment to work properly. Most good shopping carts are designed to be configured and changed according an organization's needs and branding. Usually, the first thing businesses will do is change the title, logos, categories, products offered, shipping and sales tax calculations, and available shipping methods.
If the basic functionality and usually the workflow are the same, why write separate test scripts for each organization? Why not just have the scripts use different data that drive the test execution?
For more details and examples, see the Using Organizations section.
Jameleon uses several ways to send data to functional points. One of these ways is through a properties file. The rules for these files are:
The following features are for use only when needed. If the application is deployed to a single environment and there is only one instance of this application in production, then don't use the organization and/or environment features.
To store application-specific static data that can be used by Jameleon scripts, the file name must be the name of the application followed by .properties. For example, if testing a customer service representive admin tool, one might call that application csr. This means that the file with the name csr.properties would be created. This application name is then referenced in the session tag of the test script.
Currently, all properties files are loaded via the CLASSPATH. This means that in order to use them, they must be placed in the root of the CLASSPATH. For example, if the files end up in a directory named Build, then Build must be in the CLASSPATH. This is accomplished in the jameleon-test-suite package by placing all properties files in the res directory.
If organizations are used, it is likely that there will be data that is the same across the different organizations. To do this, simply create keys that don't begin with an organization. Keys with an organization override keys without the organization. This way a default value can be specified and overridden.
There is only one variable-value pair per line in the file. The variable name should be unique. An example of setting this variable in csr.properties might look like:
logonTitle=Customer Service Tool logonFormName=csrLogon logonUsernameField=j_username logonPasswordField=j_password
For those applications that are basically the same, but have some modifications due to different affiliate requirements, Jameleon supports this by naming the organization and starting all keywords with the name of the organization followed by a ,. For example if the the logon title of a csr application is different between Company A and Company B, then the following would work:
A.logonTitle=Company A - Customer Admin Tool B.logonTitle=Company B - Customer Admin Tool
To use organization-specific data, Jameleon must know about the organization. This can be set as a global variable, in the test case tag, or in the session tag. If defined in the session tag, then the global setting will not override the session tag's setting. This is useful when a test case spans multiple applications and one of those applications is deployed against only one of the organizations.
Data can differ between the different environments the scripts run are against. For example, the way to start an application or to browse an application may differ between environments. A connection to a database to search for possible test data will likely change when testing against the sandbox environment versus the QA test environment.
Because these settings will likely be very small between applications, they are all listed in the same file. The naming standard for this file is the name of the environment followed by -Applications.properties. For example, to test an applicatoin deployed in test environment, simply create a file named test-Applications.properties, following the guidelines in File Naming Standards. Setting this variable is almost the same as explained above. The only difference is that this file represents all applications. Therefore the variable name must start with the application name followed by a .. For example, setting the baseUrlof the CSR application would look like:
csr.baseUrl=http://localhost:9123/tutorial
To use environment-specific data, Jameleon must know about the environment This can be set as a global variableor in the test case tag.
To use environment-specific data against an organization, simply preprend the variable with the name of the organization. For example, to set the above baseUrl variable for the csr application in the test environment for the acme organization, the file name would be the same as the above example, but the variable would be defined with csr.baseUrl:
acme.csr.baseUrl=http://localhost:9123/tutorial
This file can also handle variable substitution. So in the above example of company A and company B, Customer Admin Tool is the same in both organizations. A new variable with that value can be created and used in a latter variable. For example:
appName=Customer Admin Tool A.companyName=Company A B.companyName=Company B logonTitle=${companyName} - ${appName}
Properties variables can be used in test case scripts by surounding the variable name with ${}. For example:
<ju-assert-equals functionId="compare ${var1} against ${var2}" expected="${var1}" actual="${var2}"/>
Properties variables can also be accessed, changed and created in Java via the getVariable and setVariable methods of the FunctionTag.
Jameleon can use a Comma Separated Value (CSV) file format to make test cases data-driven. This is a very simple format, but Jameleon has some features to allow for a more robust data set. Basically, if useCSV is set to true in the testcase tag, then a file with the same name as the test case name followed by a .csv is used for data values. This can also be accomplished with the csv tag. For every row of data, except the first row which simply names the variables names to be set, the test case will be executed. The test case only passes if all of the rows of data passed.
Jameleon uses a uses the following rules to locate the CSV file used for a particular test case:
For a test case that is run in the testEnvironment "beta" against the organization "sourceforge" and with the name "SearchWithNoQuery", the Jameleon engine will look for data/beta/sourceforge/SearchWithNoQuery.csv and run the test case once for every row in the CSV file. The ./data directory is the directory relative to where Jameleon was executed from.
Because the CSV file name is based on the test case name, each test case should have a unique name unless it is desired that multiple test cases share the same data file. The reporting tool may be confusing since it shows the results based on the test case name and it will look like the same test case was executed multiple times.
When using a CSV file in Jameleon, the first row must be a comma separated list of variable ( or attribute ) names needed by each functional point listed in the test case. The following rows should be a comma delimited list of the values for each of the variables in the same order as the first row. A line starting with "#" is a comment and will be ignored. So if we had a test case that used "searchTerm", "searchTitle", "resultsTitle", "numOfResults", "singleResultsText", the CSV file might look something like:
#This is a legal comment searchTerm,searchTitle,resultsTitle,numOfResults,singleResultsText Food,Google,Food,15,"Eat food, It's good" #And this is also a legal comment Gift,Google,Gift,9231,Christmas is upon us! Jameleon,Google,Jameleon,80,Jameleon - Home
Jameleon can also use a Relation Database (RDBMS) to drive scripts from. The use of this tag is documented here..
There are no real standards or rules to accomplish connecting to a different database, depending on the environment and/or organization. This can all be accomplished by setting variables in the appropriate properties file. In other words, while it would be perfectly okay to put the database connection settings in the script itself, they could also be placed in a properties file with the correct environment name and application name.
The only cavaet to defining the database connection settings in a properties file is that, as mentioned above, in order to use a properties file, the application setting of the sesion tag must be set. This means that if properties file is used to store data in that a sql tag cannot be used outside of a session tag because Jameleon won't know which application to get the properties for. However, Jameleon does somewhat support nested session tags. The automated documentation won't be exactly correctly (the inner session tag will be ignored), but it will execute fine.
Values retrieved from sources external to the script (properties files, CSV files, databases), are all stored in the scripting engine's context for the script.being executed. This means that you define a variable with the same name in a properties file and in a CSV file that the value will get overwritten depending on when the CSV file is read in. This is why it is best to keep the variable names distinct. One trick that I use is to end all variable names read in from different datasources with different letters. For example, variables defined in a CSV file end in _c, variables defined from a database end in an _s and variables defined in properties files have no special ending.
Using context variables in your script is very simple. Simply surround that context variable with ${}. For example, a variable named firstName_c, stored in a CSV file, would be referenced by ${firstName_c} in the script. This would look something like:
<testcase xmlns="jelly:jameleon" useCSV="true"> <junit-session> <csr-customer-profile functionId="Change the customer's first name to ${firstName_c}" customerFirstName="${firstName_c}"/> </junit-session> </testcase>
<testcase xmlns="jelly:jameleon" useCSV="true"> <junit-session> <csr-customer-search functionId="Find all customers with ${firstName_c} ${middleInitial_c} ${lastName_c} as their full name." customerFullName="${firstName_c} ${middleInitial_c} ${lastName_c}"/> </junit-session> </testcase>
<testcase xmlns="jelly:jameleon" xmlns:jl="jelly:core" useCSV="true"> <jl:set var="fullName" value="${firstName_c} ${middleInitial_c} ${lastName_c}"/> <junit-session> <csr-customer-search functionId="Find all customers with ${fullName} as their full name." customerFullName="${fullName}"/> </junit-session> </testcase>