Forum Discussion

negative_zero's avatar
negative_zero
New Contributor
6 years ago

Sharing test scripts between multiple projects

I am testing a WPF application with TestComplete and already have a couple of tests for "manual" use. Now I want to execute these tests in a continuous integration environment, and for that I need different event handling code.

 

In order to get two distinct event handling mechanisms without having to duplicate the tests, I thought it would be a good idea to create a second "Project" within the same "ProjectSuite", and add references to my tests there.

 

For the most part, this seems to be feasible, since I could add references to the name mappings and the test scripts. However so far I see two problems:

 

1.) I ended up essentially adding every single file from projectA to projectB manually. This is of course now an unstable setup, because changing stuff in projectA in the future now requires projectB to be manually updated. Is there any way to dynamically/automatically add all dependencies that are required due to "//USEUNIT"?

 

2.) Similar situation for the project settings, in particular the list in "Open Applications" -> "WPF" -> "Composite Controls". I ended up copy/pasting this list from projectA to projectB, which obviously will lead to problems upon future modifications to projectA. Is there any other way to recycle that list other than copy/pasting?

 

I am wondering if I am missing something, or if using a test from different projects is really such an exotic usecase. Because with what I know, all of this feels rather clunky. Maybe there also is a different approach that is more practical (i.e. manual tests and continuous integration tests in the same project, but I am unsure how I would implement the required differences then).

  • AlexKaras's avatar
    AlexKaras
    6 years ago

    Hi,

     

    If I got you right...

     

    > Seeing that "//USEUNIT" apparently can't do what I thought it could do [...]

    Every nation has its customs... :)

    Yes, #include/import directives do not require an entity to be explicitly included into the project. Instead they are utilizing some internal search logic that is usually based on the values from either OS environment (Path/ClassPath/...) or the values stored in the IDE/project file.

    This definitely easies your work as you are not forced to fully qualify required file. But on the other hand it creates a risk that some other file but not expected one is used. And you may be really surprized of why things are working not as expected until you dig into debugging.

     

    One of the possible approaches is to consider the structure of your test code and make it 'linear-dependent'. For example: units of 'utils' type that do not contain any code that is specific to the tested application. Then units of 'helpers' type that contain specific, but generic code. Like selection from the list, button click, waiting for the control, etc. And, finally, the units of 'test' type that contain actual test code.

    With the proper design, the set of 'utils' and 'helpers' units is quite stable. These units can be put on the same level of folders structure on the disk where test projects are located. And then you may reference them from test projects.

    Like this:

    |

    +Libs\

      +Utils\

      +Helpers\

    +Project1\

      + ...

    +Project2\

      +...

     

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    There is no way, currently, of adding all dependencies to every project.  However, completely duplicating a project JUST for an event handler....  any developer would tell you that you don't write two different programs for two different environments, you just modify the existing program to be "smart" and detect the environment.  So, in your case, what I would do is build in some sort of "Detection" to your event handler that it would recognize whether or not it's being called from your CI environment.  If it is, handle the event one way.  If it isn't, do it another way.

     

    There are a number of techniques you could use for this.  One would be to parse the commandline used for running TestComplete/TestExecute to detect whether or not it's being run with commandline switches (a pretty clear indicator that you're running from a CI).  

    Another would be to have some sort of variable that updates on the project level (Project.Variables) that would contain a value that changes depending upon how the test is run and have the event handler look for that.   

     

    This would be a LOT more efficient than completely duplicating a project.

     

    You CAN share code between projects... that's a common practice.  But duplicating an entire project?  That's an exotic case that, honestly, I think should be avoided.

    • negative_zero's avatar
      negative_zero
      New Contributor

      Thanks for your reply!

       

      With all your information however, I somewhat disagree with your conclusion that you "can share code between projects". It seems to be more of a "you kind of can, but not really" situation. The fact that you used the phrase "duplicating an entire project" synonymously with what my intention was ("using large chunks of a project"), says it all.

       

      No one would argue that utilizing "#include" in C, "import" in Java or "using" in .NET is synonymous with "duplicating" anything, even if those are applied to a top level item that depends on the entirety of a different project. I was under the false impression that TestComplete's "//USEUNIT" provides a similar functionality.

       

      Seeing that "//USEUNIT" apparently can't do what I thought it could do, I agree that a library style organization of scripts is not effective in TestComplete. I don't particularly like the solution of having one humongous project for everything  (otherwise I would have decided for that right away), but it seems to be the only practical one.

      • AlexKaras's avatar
        AlexKaras
        Champion Level 3

        Hi,

         

        If I got you right...

         

        > Seeing that "//USEUNIT" apparently can't do what I thought it could do [...]

        Every nation has its customs... :)

        Yes, #include/import directives do not require an entity to be explicitly included into the project. Instead they are utilizing some internal search logic that is usually based on the values from either OS environment (Path/ClassPath/...) or the values stored in the IDE/project file.

        This definitely easies your work as you are not forced to fully qualify required file. But on the other hand it creates a risk that some other file but not expected one is used. And you may be really surprized of why things are working not as expected until you dig into debugging.

         

        One of the possible approaches is to consider the structure of your test code and make it 'linear-dependent'. For example: units of 'utils' type that do not contain any code that is specific to the tested application. Then units of 'helpers' type that contain specific, but generic code. Like selection from the list, button click, waiting for the control, etc. And, finally, the units of 'test' type that contain actual test code.

        With the proper design, the set of 'utils' and 'helpers' units is quite stable. These units can be put on the same level of folders structure on the disk where test projects are located. And then you may reference them from test projects.

        Like this:

        |

        +Libs\

          +Utils\

          +Helpers\

        +Project1\

          + ...

        +Project2\

          +...