Forum Discussion

kroe761's avatar
kroe761
Contributor
10 years ago

Call a function as a parameter from another function?

I am maintinaing a lot of legacy test code, and it uses the Runner.CallMethod() function to call methods from other files.  One of the advantages here is that CallMethod uses a string as parameters, so calling a bunch of different functions in a for loop is easy:

 

function test()
{
  functions = new Array("button_one", "button_two", "button_three")

  for (i = 0; i < functions.length; i++)
  {
    button = Runner.CallMethod("My_File." + functions[i])
    button.Click()
  }

 

However, I am writing a bunch of new tests for a new application.  I don't want to use deprecated codes, but I really like the functionality above.  Is there any way I can do this using USEUNIT?  Something like this:

 

//USEUNIT My_File

function test()
{
  functions = new Array(button_one, button_two, button_three)

  for (i = 0; i < functions.length; i++)
  {
    button = My_File.functions[i]()
    button.Click()
  }

}

 

Or maybe this (actually what I would prefer)

 

//USEUNIT My_File

function test(function_name)
{
  button = My_File.function_name()
  button.Click()
}

test(button_one)
test(button_two)
test(button_three)

 

Thanks a lot!

  • Functions that reside in other scripts, and that are linked with USEUNIT, effectively become part of the current script.

    You can call them "dynamically" as in your first example like so:

    //USEUNIT My_File
    function test(){
      var functions = ["button_one", "button_two", "button_three"]
      for (var i = 0; i < functions.length; i++){
        var button = My_File[functions[i]]();
        button.Click()
      }
    }

     

  • Ryan_Moran's avatar
    Ryan_Moran
    Valued Contributor

    Functions that reside in other scripts, and that are linked with USEUNIT, effectively become part of the current script.

    You can call them "dynamically" as in your first example like so:

    //USEUNIT My_File
    function test(){
      var functions = ["button_one", "button_two", "button_three"]
      for (var i = 0; i < functions.length; i++){
        var button = My_File[functions[i]]();
        button.Click()
      }
    }

     

    • kroe761's avatar
      kroe761
      Contributor

      Excellent!  That completely answered my question!  Kudos to you good sir!

      • Ryan_Moran's avatar
        Ryan_Moran
        Valued Contributor

        Not a problem :).

         

         

        P.S. Don't forget to declare your variables with var when you mean to use them only within said function!

        [updated my original post so I wouldn't set a bad example]

        Find out why!

  • Hi

    I can't see why it wouldn't pretty well work with things close to as you had them set out as in your example and without magic strings:

     

    ie. assuming

    button_one, button_two, button_three 

      are functions in My_File

     

    //USEUNIT My_File
    
    function test()
    {
      var functions = [button_one, button_two, button_three];
    
      for (i = 0; i < functions.length; i++)
      {
        var button = functions[i]()
        button.Click()
      }
    
    }

    I would expect this to call each of the functions in your other unit.

     

    Be aware that exception handling will not work if one of the functions from the other unit throws an exception.

     

    Also it is quite easy to grab a copy of underscore and adapt it for TC. This can help make things a lot cleaner for scenarios like this. Something like:

     

    function clickIt(btnFunc){

        btnFunc().Click();

    }

     

    _.each([button_one, button_two, button_three],  clickIt);

     

    John

    • Ryan_Moran's avatar
      Ryan_Moran
      Valued Contributor

      John,

      I think the magic strings were just used as an example, but you are correct to say that you can also assign the function itself to the array and iterate. That is of course assuming you already know the full name of said function. In the scenario provided the function names passed in the array may be incremental (Function1,Function2,Function3) and thus need to be passed as a string value.