Forum Discussion

amarr1143l's avatar
amarr1143l
Contributor
10 years ago

Add Unit References (USEUNIT) programatically


Hi,


 


Is there a way I can Add Unit References (USEUNIT) in different units, programatically? I am using AddUnit Method of IntegrationObject to add a unit in my project.


 


If someone could suggest what is the best alternative of QTP's LoadFunctionLibrary in TestComplete? My end goal is to achieve that.


 


Thanks.

4 Replies

  • Philip_Baird's avatar
    Philip_Baird
    Community Expert
    Hi Amar, I don't think it is possible to do what you require as from what I have observed it appears that Test Complete evaluates all USEUNIT statements before executing any Test scripts.

     


    What I have done which may be of interest is devising a proof of concept pattern of a Script Register and self registering Script Units that remove the need for USEUNIT.


     


    The first step is to create a Temporary variable of Object Type named ScriptRegister, in this case at ProjectSuite level, but it could be duplicated an Project level if a degree of separation is desired.


     







    Then, to accommodate global self registering. create a Persistent self initialisation String Type variable named InitScriptRegister


     







    Set the Default and Local Values of this variable to the following code:


     


    (function() {


      try {


      if( ! ProjectSuite.Variables.ScriptRegister ) {


        ProjectSuite.Variables.ScriptRegister = {};


      }


      ProjectSuite.Variables.ScriptRegister[ "%s" ] = %s;


      } catch( exObj ) {


        Log.Warning( "Could not register %s" );


      }


    }());


     


    This is the source for a self invoking anonymous function that will:


    1. Create the ScriptRegister if it does not exist


    2. Add the Script Unit to the ScriptRegister


     


    This is then used by Script Units to self register using eval().


    For example, if it were required to register two Script Units, "Unit1" and "Unit3" the following would be placed at the top of each Script Unit, as global code, respectively. As the call to eval() is at the global level if will add a reference to the ScriptRegister before any Test Scripts run.


     




    eval( aqString.Replace( ProjectSuite.Variables.InitScriptRegister, "%s", "Unit1" ) );


    eval( aqString.Replace( ProjectSuite.Variables.InitScriptRegister, "%s", "Unit3" ) );



     


    Then, from any Script Unit, the following can be called, if these functions are defined in the appropriate Script Unit, from any Script Unit without a need to have a USEUNIT.


     




    ProjectSuite.Variables.ScriptRegister.Unit1.callUnit1();


    ProjectSuite.Variables.ScriptRegister.Unit3.testScriptRegister();



     


    As I said, this is a proof of concept, it works but I don't know how scalable or stable it is, though I can't see any reason why it shouldn't be.


     


    Regards,


    Phil Baird





  • Thank you for the reply, Phil. Isn't it same as Runner.CallMethod("<unit>.<method>")?



    At run time, I wouldn't know name of the unit which is holding the method I am calling. I have a wrapper written over TestComplete which gives calls to TestComplete for execution (and I have just the method name to be called with me!). The called method could be held by any of the added units in the project. 

  • Philip_Baird's avatar
    Philip_Baird
    Community Expert
    Yeah, it pretty much is the same as Runner.CallMethod("<unit>.<method>"), I just don't like the fact Smartbear has marked Runner.CallMethod() as obsolete and I am loathed to use it.

     


    It's actually a slight tweek on a register of function Constructors (instead of complete Script Units) I put in place so I could create instances without needing a USEUNIT.


     


    I'm not to sure what you are attempting, are you trying to dynamically build a Project Suite prior to execution?


     


    Regards,


    Phil Baird

  • Yeah. Kind of. Hence, was looking for something similar to QTP's LoadFunctionLibrary.