One of the challenges I faced as an automation engineer was the need to run my tests in multiple environments that had different site URLs, databases, server locations, etc. Trying to set up tests so they can run ANYWHERE can be difficult.
I had to develop some way to do this, because the company I was working for at the time had many test environments in which these tests had to run. Some aspects of the tests required different information in order for them to work correctly, such as database and server names, file paths, etc. (more than 40 items involved!). Plus, each tester had their own environments (servers, databases, etc.) as initial testing areas as well, so these tests had to run in as many as 20 different environments. These tests also had to be run straight from UFT on the local machine or from ALM.
I want to provide you with one way to overcome this problem. There are many ways you can do this, but I’m going to show you a very easy and efficient way to implement it. This method involves several components. I will discuss each component and show you how to tie them together to enable your UFT to run across multiple environments. I will also include some necessary code.
The Data Sheet
The data sheet is an .xls file containing specific information for each different environment in which you need to run your tests. I named mine DefaultDataLoader.xls. It contains an empty “Global” sheet and a “DataLoader” sheet.
The DataLoader sheet contains columns for each piece of information that would be different from one environment to another. For my project, this included:
- Database DSNs
- Passwords (encrypted, of course)
- Various file paths
- Server names
- Server timezones
- IP addresses
- A variety of other items specific to the project (there were more than 40 in my project)
Each row of the data sheet contains specific information for the different environments in which the test needs to run.
I stored the data sheet in Test Resources of ALM and imported it into the test’s DataTable at run time. Remember, when you import a data sheet into the DataTable, the first row will become the column headers in the DataTable.
The Global Dictionary
One of the best things I’ve discovered is the Global Dictionary (aka Scripting Dictionary). The Global Dictionary is a dictionary of variables that are global in scope. The Global Dictionary can be a dangerous thing, because any action or function library in the test can manipulate the variables. So, you need to be very intentional about what variables you use in the dictionary, and be careful how you reference them in the test. I recommend treating them like constants and never reassigning them in the test, only referencing them.
In order to use the Global Dictionary, two registry keys need to be created on the machine (this can be done differently, but for my purposes, this worked best). I always put the code for this in a function library that runs as soon as the test is executed. This has to be created before running a test that uses the Global Dictionary, or UFT will throw an error.
‘ Create Global Dictionary
‘ Arguments : None
‘ Description : Creates Global Dictionary on computer if not already created.
‘ Return Value: None
‘dim WshShell, bKey, tkey
Set WshShell = CreateObject(“WScript.Shell”)
‘Write keys to registry
WshShell.RegWrite “HKCU\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects\GlobalDictionary”, 1, “REG_BINARY”
WshShell.RegWrite “HKCU\Software\Mercury Interactive\QuickTest Professional\MicTest\ReservedObjects\GlobalDictionary\ProgId”, “Scripting.Dictionary”, “REG_SZ”
Now that the registry keys are made, you can add items (variables) and assign values to those items. One way is to use the .Add method, where the first argument is the item name and the second is the value.
GlobalDictionary.Add “QAServerIP”, “” <– Creates the item with a null value
If the item is already created, but with no value, you can assign a value to it later in code (this is why it can be dangerous and you need to be careful how you use it).
GlobalDictionary.Item(“QAServerIP”) = “10.58.64.85”
Importing the Data Sheet
If you store the data sheet externally, like in ALM Test Resources (and you should!), you’ll need to import it to your test using simple DataTable import commands.
DataTable.ImportSheet FileName, ImportSheet, DTSheet
I incorporated this in a call from the DataLoader (see below) to my Excel operations script that contained an import action and other Excel related stuff. I loaded the data sheet into the DataLoader action’s DataTable.
After your data is imported, you need to tell your script which row of data to use in the current test. Do that by using the SetCurrentRow method.
Now that your data sheet is imported, you need to load the data into the Global Dictionary. This is simple code that reads the column names of the DataTable and creates a Global Dictionary item based on the column name. Then, it assigns the value to the item from the specified row in the DataTable. Here’s the code:
‘Script Name: DataLoader
‘Action Name: DataLoader
‘Description: Loads data from the datatable into the global dictionary
‘Uses the datatable column name as the item name, then loads the data
‘based on the row number supplied. Row 1 is the default row.
‘Application State Required: Page independent
‘Application State Produced: Page independent
‘Created By: Michael Deveaux
‘ On: ##/##/####
‘ The column header will be the
‘ Global Dictionary item name, and the data will be the value.
‘ You can supply the row number to use, so the same spreadsheet can
‘contain multiple data sets.
‘ intRowNum = The row of data to use
‘ strDataSheet = The location of the spreadsheet being imported (Full path!)
‘ strWorkSheet = The name of the worksheet to import
‘ strActionName = The action name to import to.
intRowNum = Parameter(“intRowNum”)
strDataSheet = Parameter(“strDataSheet”)
strWorkSheet = Parameter(“strWorkSheet”)
strActionName = Parameter(“strActionName”)
RunAction “import_sheet [excel_operations]”, oneIteration, strDataSheet, strWorkSheet, strActionName
‘Set DataTable Row. Default to 1
intRowNum = Parameter(“intRowNum”)
If intRowNum = “” Then
For i = 1 To DataTable.GetSheet(dtLocalSheet).GetParameterCount
GlobalDictionary.Item(DataTable.GetSheet(dtLocalSheet).GetParameter(i).Name) = DataTable.GetSheet(dtLocalSheet).GetParameter(i)
Now, you have a dictionary of all your data that is stored in addressable variables that have global scope. Pretty cool and easy to implement. Now, just load up the data sheet rows with the environment information for your various test environments, then just pass the test the row that you want to implement into the test Input Parameters.
This can be done from ALM Test Instance Details>Execution Settings>Automated.
or from the UFT Run dialog, Input Parameters.
This really will enhance your tests by making environment variable dynamic, yet easy to access.