Forum Discussion

rperneel's avatar
rperneel
Occasional Contributor
9 years ago

Best Practices

Hi All,

 

We have a project suite that contains 13 subprojects.  we have setup each project to have any references to files in other projects as needed.  We have been having alot of issues around the speed of the code editor (mainly the intellisense) lately, and I am wondering if we have shot our selves in the foot with the project setup.  Based on the Code Metrics, we have:

  • Number of Routines: 27610
  • Number of Lines: 1093254
  • Number of Units: 819

My biggest annoyance is the circular reference issue we are running into trying to extend our framework.

 

Does anyone have any best practices for large project that they want to share?  

 

Thanks

 

  • 1. Get a fast machine with plenty of ram and an SSD disk. Sounds obvious but it is amazing how a project can snap to life with relatively up to date hardware. Often testers don't have good machines because they are transitioning from a manual testing and haven't been performing processor / memory / IO intensive tasks. If you build gradually massive TC projects over time the slowdown in the work flow can be like boiling a frog until one day you realise your spending half your time waiting on syntax checkers or projects to load.

     

    2. I have seen this in JScript projects but it may apply to some other scripting languages: Be on the look out for variable assignments in the global namespace. i.e. in the script not inside a function:

         // anywhere in any script not inside a function

         var testData = readMassiveSpreadsheet();

        

         readMassiveSpreadsheet will be invoked every time you run anything and TC will block until it is finished.

     

    3. I've noticed that a syntax check time seems to be related to project size so keep the size of each project reasonable even if that means more projects in one suite. Loading a massive project suite can chew up memory but it does not seem to affect the syntax check time like having massive projects.

     

    4. If you are using name mapping files and they are getting massive periodically remove property info from the xml file this massively reduces the file size and memory footprint of  (haven't done this for ages as I stopped using name mapping files years ago but there will be a how to somewhere in help or on the forum). Doing this can reduce both the memory footprint and load time of a project suite a lot.

     

    5. Create simple understandable standards for modularising your scripts and and stick to them so it is easy to find and reuse functions. Here's what I use:

     

    i) Test cases are in their own file and named with a namespace like style and end in the word test eg.  ACME_Florist_Management_Payroll_Test,

    ACME_Florist_Management_POS_Test, 

    ACME_PowerStationControl_Temparature_Test

     

    test cases are not allowed to be referenced by any other file

     

    ii) Helpers - script units named after the domain are application specific and can be used by Test cases and other helpers. Usually only used within a single project. e.g TemperatureControl, Payroll.

     

    iii) Utils - Very Generic functions can be used by other Utils , Helpers or Test cases. Named after their function with the word Utils on the end; StringUtils, DateTimeUtils. Utils are not allowed to reference helpers or test cases. They can be shared between projects and project suites.

     

    6. Use a duplication detection tool like Simian to keep your codebase DRY (I am sure there would be open source offerings available as well but this is the one I have used). Name and shame the offenders if they do not respond to counselling.

     

    • Manfred_F's avatar
      Manfred_F
      Regular Contributor

      I also created a library to deal with our application under test AUT.

      The objective is to provide as much as possible Standard System functions to simplify the genuine test coding. There is a layered architecture: technical System functions - TC specific System functions/classes - AUT specific System functions/classes - Standard test functions - detailled test functions.

       

      The libraries are fine now, but I spent much too much time creating them. I used script Extensions in vbs and, of necessity, js also. I was forced to use js, as I learnt that objects created in vbs and kept in global variables in a native TC vbs module will never more be released.

      Some TC libraries are not available in script extensions, but i solved that. If I had to do it again, I would not use a script language for the libraries, but use a more reliable Environment, e.g. visual Studio, and use the SDK. The reason is, that the Scripting is not type safe, and that there is no reliable Syntax check at "compile time". So, if You have a typo, this will Show up as soon as it is reached, some hours from now. VBA is an example of a Scripting language being typesafe and having a perfect compile-time Syntax check.

       

      Name mapping I use only to identify dialogs. On our AUT, there are table dialogs having several hundreds of fields, so Name mapping the fields would not have been an Option. Adressing is done by the libraries, e.g. "myDlg.Frame().Subframe(0).Button("ok")". As a result, the Name mapping remains controllable. the libraries also deal with multiple instances of a Dialog, which is not easily possible using aliases.

       

      It works fine now, but There are some issues left:

      - TC Memory leaks

      - they cancelled ODT, which is the very Basis of my test sequence control..

    • mgroen2's avatar
      mgroen2
      Super Contributor

      rperneelManfred_FTheGhosttristaanogreMarsha_R: One best practise to do! : Vote for the feature request to upgrade TestComplete to support x64 architecture. Only then TC can make use of all the RAM available on these fast machines!

       

       You can find the feature request here

       

    • ulTam's avatar
      ulTam
      Occasional Contributor

      You mentioned that you have stopped using name mapping.

      I also read somewhere that some users only map windows or dialow windows and not all the needed UI elements.

      Can you help me understand how this is done? Or can you point me to the forum that discusses how this is done?

      • Manfred_F's avatar
        Manfred_F
        Regular Contributor

        Well, I did not stop use Name mapping. I just limited ist use to the identification of Dialogs.

         

        The controls on the Dialogs are identified via their captions (if possible) or via their hierarchical structure (as mentioned above). There can be hundreds of controls on a Dialog, I really can't Control this via Name mapping.

         

        If a Control has got a caption (static Control or table header), my library uses the caption Name to give me Access to the Control (e.g: myDlg.Frame().EditBox("Name")).

        If no caption is present, the library lets me Access the Control via structure and sequence (e.g: myDlg.Frame().EditBox(0)).

  • Rather than having the projects refer to each other, can you pull out the bits that are being referenced in all the projects and make a separate library project out of just those?  I think that would help your circular reference.

    • tristaanogre's avatar
      tristaanogre
      Esteemed Contributor

      With that many routines and lines of code, I wonder if there isn't some duplication of effort in there somewhere? Are there segments of code that are, basically, doing the same thing as others that, with a bit of parameterization, can be pulled out and put in a library? That would reduce, incredibly, the amount of code you actually have as well as make maintenance a bit easier.

       

      Additionally, how much of your code is "do step 1 with data 1, do step 2 with data 1, do step 3 with data 1" followed by another test that uses data 2, and another with data 3 and so forth? You might want to look at moving the data outside of the code in these instances into some sort of externalized data storage (like a CSV file, an Excel sheet, or a TestComplete DBTable variable) that you can then use some sort of DDT loop to cycle through.

       

      Finally (and this might be more drastic), you might want to consider converting your project (slowly, mind you), into an entirely data driven framework where the code being executed is extremely genericized and modularized and the order of execution and the data used for the execution are all contained within data tables.  Plenty of examples out there of such a thing and, for heavy automation with a lot of tests, it might be the way to go.

      • rperneel's avatar
        rperneel
        Occasional Contributor

        Thanks for the suggestions.  I am in the process of auditing our framework, so I am sure i will find issues that need to be fixed.