Ask a Question

Assigning Variable Values to Remote Machines

SOLVED
kirk_bottomley
Contributor

Assigning Variable Values to Remote Machines

Our test structure is one authoring machine writing tests using TestComplete, and TestExecute licenses on the machines that will run the tests. Each machine can install the software to any AppPath, and each machine runs the tests in their own sandbox. Consequently, I need to be able to set the variables for each machine.

I know a better solution is to use XML or some file that lists the variable values for each machine and read those in, but until that framework is implemented, I've been trying to do it this way: 

 

In the Project.Variables collection, there is AppPath, Sandbox, SQLServer, etc. Our machines are named like ABCDE-1234. You can't use dashes in variables, so I just strip those out. So I also have AppPath_ABCDE1234, AppPath_FGHIJ5678, etc. 

I have an initialize routine that passes in a variable name, like Sandbox. It then appends _ and hostname to variable name, and uses VariableByName to assign the value. Ideally, this should just need to be run once when a machine connects for the first time, but it's quick enough I just have the routine run at the beginning of our test suite, and just use Project.Variables.Sandbox, for instance, in the tests from then on.

 

Sorry for the length of this question, but the problem is that the strategy works fine on the authoring machine, but when a remote machine using TestExecute runs the routine, the values are not assigned. I'll post the code below, can anyone tell me why this isn't working?

 

function AssignVariables(VarName)
{
var MachineName = aqString.Replace(Sys.HostName, "-", "");
var ConcVar = VarName + "_" + MachineName;
if (Project.Variables.VariableByName(VarName)= Project.Variables.VariableByName(ConcVar))
  {
    Log.Message(Project.Variables.VariableByName(VarName) + " now equals " + Project.Variables.VariableByName(VarName + "_" + MachineName) )
  }
else
  {
    Log.Message(VarName + " not assigned.")
  }
}

As I said, when run on the authoring machine, it works fine. When run with TestExecute, it always returns back with VarName not assigned. 

17 REPLIES 17

Just write all your variables to the test log during the test run and then check the logs. I suspect one of the variables is your problem and it will be obvious when you check the logs. As for triple equals I was suggesting using that in your 'if' statement to avoid type coercion. Something that has certainly caused me an issue at least once.

"Put some logging in your test to write the machine name and VarName"

 

Thanks for the suggestion!

 

"Also, I think you could simplify the way you do your logging message in the if statement."

 

I had considered that, but thought that by rebuilding the string again, I could also verify that it was building the string correctly and eliminate that as a factor. 

Perhaps this example might be of interest. I compare host names in my project against a list of host names to decide whether to send an email notification at the end of a test run. I do it by having a script file for all project configuration called project_config in my project. Inside this script I have one object literal that contains all my project configuration. 

I then include the script file in any script where it is needed '//include project_config'. Then I can access any of the properties of the project configuration object in my tests. 

 

var projectConfig = {

 

emailNotifications: {

   hosts: ["host_one","host_two"]

}

 

}

 

 

//include project_config

 

//send email notifications if test run was executed on an 'approved host'


var hosts = projectConfig.emailNotifications.hosts;
var currentHost = Sys.HostName;

 

//look for a match between hosts and current host


for (i = 0; i < hosts.length; i++) {
var hostName = hosts[i];
if (currentHost === hostName) {
var match = true;
break;
}

 

}

if (match !== true) {
TerminateIEProcesses();
return;
}

kirk_bottomley
Contributor

I figured out a solution.

 

You can't assign the value of a persistent variable to a persistent variable, it seems. But you can assign a temporary variable to one.

 

So simply...

 

function AssignVariables(VarName)
{
var MachineName = VarName + "_" + aqString.Replace(Sys.HostName, "-", "");
Project.Variables.VariableByName(VarName) = Project.Variables.VariableByName(MachineName);
}

...allows me to populate the Temporary Variables section with Variable_Machine-0123, call the routine as needed, and pass in the variable name to be assigned. Then I can just continue using the original variable in the rest of the tests and scripts.

 

I know the better way would be to maintain a database or XML file with the machine names and their needed values, but until that is implemented, this will work.

Thank you everyone who responded trying to help. Much appreciated.

> You can't assign the value of a persistent variable to a persistent variable, it seems. But you can assign a temporary variable to one.

 

Huh?  I don't think so.  You can easily verify that you can assign the value of a persistent variable to a persistent variable.  I think it is more likely that the variable named by ConcVar contains the empty string.  Assignment of an empty string evaluates to 'false' so the following:

 

if (Project.Variables.VariableByName(VarName)= Project.Variables.VariableByName(ConcVar))
  {
    ...
  }
else
  {
    Log.Message(VarName + " not assigned.")
  }
}

 

assigns the empty string to the variable named by VarName, and then falls to the else clause.

 

"You can easily verify that you can assign the value of a persistent variable to a persistent variable.  I think it is more likely that the variable named by ConcVar contains the empty string.  Assignment of an empty string evaluates to 'false'."

 

When I ran it on the TC machine, it worked as intended. When I ran it on the TE machine, it would fail.

 

In trying all kinds of different ways to do it, this way was the only way that actually worked. It might be unique to my setup here, but the authoring machine usually seems to work different than my TE test machine. When I tried assigning persistent to persistent, it would work on TC, but never on the remote. 

In checking this again, it appears that I am mistaken on the difference between the persistent and temporary. I believe what I was doing wrong was trying to alter default values and getting sidetracked by several test functions I was writing trying to solve the issue. 

The code I posted first still seems to work on the TC machine, and I just verified that it still doesn't work on the remote. However, the second function I posted works on both, and works on all variables. It is still advantageous, in this schema, to keep the individual machine's values in temporary and the "root" variables in persistent, though. I can see them easier, and only see the one value that would need to be altered. Ultimately, the best solution would be to strip the individual machine values out of the project variables altogether, but that's for another day.

> ...The code I posted first still seems to work on the TC machine, and I just verified that it still doesn't work on the remote...

 

There were suggestions earlier to log the value of the variables at different points in your script to see what is happening.  I think that would help pin down the problem.

"There were suggestions earlier to log the value of the variables at different points in your script to see what is happening.  I think that would help pin down the problem."

 

I was trying to fix this two years ago, and the threads just kind of died off. I've got it working now, even if it isn't the ideal way to do it. 

I've got thornier problems, like MSHFlexGrids not being recognized (open thread here) and object mapping losing scope. 

I have marked this as solved, and will revisit the issue when I'm able to implement the XML framework.

 

Thank you for the suggestions! 

cancel
Showing results for 
Search instead for 
Did you mean: