Forum Discussion

mfoster711's avatar
mfoster711
Regular Contributor
11 years ago

Maybe variables are not my solution

I thought using network, project or projectsuite variables were my solution but aparently this is not the case. Here is what I am trying to accomplish:



I have a single Testcomplete project that is saved on a network drive. I use this project in shared mode on multiple PCs. When I run my testing, I open the project on PC#1 and have it execute my tests on 10 other PCs using distributed testing and TestExecute. 



I need to set some variable data values when I run my testing and this data is used amongst the different PCs. This data is unique for each PC, it is specific to the application I am testing and varies during different test runs.



For example, UserID & Password is one of the pieces of data that needs set for my testing. I use a form to select which UserID gets assigned to each PC that will be used in this processing. PC#2 might be assigned UserID X, PC#3 gets UserID Y, etc. I then begin my testing by starting the distributed testing process on PC#1. 



Frequently, I might need to go to one of the test PCs and troubleshoot an issue with the testing. Let's say PC#3 had an issue and this issue required me to reboot the PC. After rebooting PC#3, I need to sign back into my application to peform the testing. I open TestComplete on PC#3 and open the same project that was used on PC#1. I now need to know which UserID to use on PC#3. I need to know the UserID that was selected when I began the distributed testing process from PC#1. 



How can I do this??



I thought variables would work but they don't. In the past I would save this data to a simple text file on my network and then each of the test PCs would open the text file to get the information needed for that specific PC. It seems like I will need to keep using a text file which really makes me wonder what is the point of network, project or projectsuite variables.

7 Replies

  • Ryan_Moran's avatar
    Ryan_Moran
    Valued Contributor
    So to keep this simple it sounds like you want to run the same project with different cases for each machine.

    In the past I have done this just by computer name:



    JScript Ex.:

    //using global variables outside a function

    net = new ActiveXObject('WScript.Network');

    switch (net.ComputerName){

     case 'Computer1':

      userName = 'testmonkey';

     break;

     case 'Computer2':

      userName = 'testmonkey2';

     break;

     default:

      userName = 'testmonkeygodmode';

     }

    //etc etc
  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor
    As mentioned in my reply on my other post, because there is a "Local Value" on persistent variables, you need to populate that value locally.  It's not something that persists across network shares.  The "persistant" has to do with persisting between runs on the same box.



    As noted, you can use the Storages object to create and populate INI, XML, or other similar files that will allow you to set values based upon locality.  This has worked very well for me in the past.  It's even automated in that your master machine which you use to launch the tests can write out the INI file that then the remote machines use to read it in.  And, once the remote machines read it in, you don't have to re-open the INI... it will be populated in the Persistant Variable.



    Give me a bit of time, I can even get the script code written up but that should be a good way forward to transfer settings across boxes.  Heck, just take Ryan Morgan's code and, instead of assigning static values, read the values in from keys in an XML file organized by machine name.
  • Ryan_Moran's avatar
    Ryan_Moran
    Valued Contributor
    "Heck, just take Ryan Moran's code and, instead of assigning static values, read the values in from keys in an XML file organized by machine name."



    As Robert says you can use this approach to help organize data by machine name.

    The key point being that you need a unique identifier to each machine to identify which value belongs to which machine.

    The second part is that you want to update a persisting variable belonging to that machine and you essentially want to know which of the usernames are currently being used or were previously used by other machines.

    I would agree with Robert's approach to create an XML file with the computer name, status, last username used, etc.


  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor
    In a way yes... and in a way no.  From what I understood (and correct me if I'm wrong), you would, previously, manually open the text file, read what's there, and manually enter it on the machine in question.



    What Storages.INI or Storages.XML does for you is allows you to, within the scripts, read and write the contents of the files to automate the transfer of information from one machine to another.  It removes a good chunk of the manual stuff and automates it.



    So, for example, you could have a routine on your Master box that looks something like this where the names Slave1 and Slave2 are actually replaced with the machine names of the different remove boxes.  Also, your SetOption calls could still get the values from your entries on the UserForm:



    function CreateXMLTransfer()

    {


        var XMLFile


        XMLFile = Storages.XML(Project.ConfigPath + "//Script//Test.xml")


        var Section = XMLFile.GetSubSection("Slave1")


        Section.SetOption("TestItem1", "Value1")


        Section = XMLFile.GetSubSection("Slave2")


        Section.SetOption("TestItem1", "Value2")


        XMLFile.Save()


    }



    Then, on your remote machines, you'd do something like this.



    function GetXMLSettings()


    {


        var XMLFile = Storages.XML(Project.ConfigPath + "//Script//Test.xml")


        var Section = XMLFile.GetSubSection(Sys.HostName)


        Project.Variables.test = Section.GetOption("TestItem1")


        XMLFile.Save()


    }



    The effect would be what you're looking for... values set by the master project and then transfered to the slave projects.  They would then persist on the slave projects for you to reference as well as for any re-executions.



  • mfoster711's avatar
    mfoster711
    Regular Contributor
    Martin - Thanks for your information. I am looking at the Storages object but, correct me if I am wrong, it is really just doing the same thing I would normally do using a simple text file on the network?



    Ryan - That is not correct. Your solution assumes that computer1 would always use the same UserID. It varies from day to day.
  • Do YOU need to know, or do your tests need to know?

    Are you logging back in manually and then resuming tests?  Or are the tests logging in?



    If it's just you, then the information you seek is most likely in the test logs.  Look for a line that says something like "USER#3 was entered into the text box"



    You might be able to avoid a lot of unneccessary coding...



    On the other hand, if the tests need the information, then the suggestions above are where to look.
  • I've been trying to write the code to do this, but I keep running up against walls.



    I was going to take the suggestions here and create an XML that will store the variables needed for each machine, then read those in at the start of a test.



    Then I got the idea that when a workstation opens the project, as long as they open it in shared mode, there is a folder created with their workstation id already. 



    So...



    I wanted to create a Master XML that is stored at Project.Path that has all the variable information in it. Then when a user opens the project, it checks to see if they already have a workstation.xml file in their share folder. If not, copy the Master.xml to  workstation.xml at Project.ConfigPath, set the variables, then run the tests. If it exists already, just run the tests.



    For variables that won't change often, I wanted to set the Category property for that variable to "Fixed". If it's something that will vary from machine to machine, like AppPath or testbed locations, I was going to set the Category to "User". Then when the XML is parsed the first time, it would pop up a form allowing the user to configure their own machine settings the first time, and never have to do it again.



    The first problem I found was that NetworkSuite variables can't be created this way.

    Then I found that the Category and Description properties can't be addressed this way.



    Note that all of this could be simplified with an interface to change a workstation's variables. Having to write all this code to bypass that lack is frustrating enough, but it is beginning to look like even that approach has been purposefully hobbled.



    Is there some exploit that people might take advantage of if they had access to configure the variables in a workstation's share folder? It looks like TestComplete goes out of its way to make variable configuration impossible.



    Can anyone think of a workaround for this workaround approach to work? Or a better approach altogether?