Forum Discussion

bduncan's avatar
bduncan
Contributor
15 years ago

Understanding Object Comparisons

I have started experimenting with Objects in TestComplete 7 and I'm having some difficulty understanding how the comparison is supposed to work. For example, my (open) application has a form with a panel on it that contains several text boxes. Using the Object CheckPoint Wizard I select the panel and check "Store Properties Of Child Objects".  When the items are compliled I select Edit and verify that the properties I want to monitor are included.  If finish it by keeping "Report Difference" selected and copy the Code from the Copy Text window into my script.



If I change values in several text boxes, then run the code that was aquired from the Copy Text window the procedure produces a compare error but only shows the difference in the first text box that it encounters that has changed and ignores the rest.  My understanding from reading the help file is that you should get a list of all items that have changed.



I have also used the Database Table Checkpoint to monitor data directly in the tables and it correctly identifies all changes that occur.



I have included images of the panel in question in its original state before capturing the object (image 1), the contents of the CheckPoint Wizard (image 2), the panel after making changes (image 3), and the error message produced by running the code generated by the wizard (image 4).  Notice that only 1 of the changes is indicated in the error log.  Shouldn't I be seeing all of the changes the way I do when doing a database compare?





Is there something I am missing??





Thanks



Bill

10 Replies

  • Hi Bill,




    I have registered your request as a suggestion to show all differences in a report. In the meantime, I can suggest that you use the below custom comparison script:




    [JScript]

    ...

      var obj = // Obtain the target application object

      var storedObj = Objects.StoredObject("MyStoredObj");




      Log.Message(CompareObjects(obj, storedObj, ""));

    ...




    function CompareObjects(obj, storedObj, excludedProps) 

    {

      var prop, child, storedChild;

      var ret = true;

      var errorStr = "";

        

      for(var i = 0; i < storedObj.PropertyCount; i++)

      {

        prop = storedObj.Properties(i);

        if(excludedProps.indexOf(prop.Name) > -1) continue;

        if(!IsSupported(obj, prop.Name))

        {

          ret = false;

          errorStr += "Object doesn't support the '" + prop.Name + "' property\r\n";

        }

        if(!CompareStrings(obj[prop.Name].toString(), prop.Value.toString()))

        {

          ret = false;

          errorStr += "Property value mismatch (" + prop.Name + "):\r\n\tStored value = " + prop.Value.toString() + "\r\n\tActual value = " + obj[prop.Name].toString() + "\r\n";

        }

      }

      

      for(var i = 0; i < storedObj.ChildCount; i++)

      {

        storedChild = storedObj.Children(i);

        child = obj.FindChild("Name", storedChild.Name); 

        if(!child) ret = false;

        

        ret = CompareObjects(child, storedChild, excludedProps);

      }

      

      if(!ret) Log.Error("Objects are not identical", errorStr);

      

      return ret;

    }




    function CompareStrings(str, pattern)

    {

      pattern = StringReplace(pattern, "\\", "\\\\", 1);

      pattern = StringReplace(pattern, ".", "\\.", 1);

      pattern = StringReplace(pattern, "(", "\\(", 1);

      pattern = StringReplace(pattern, ")", "\\)", 1);

      pattern = StringReplace(pattern, "[", "\\[", 1);

      pattern = StringReplace(pattern, "]", "\\]", 1);

      pattern = StringReplace(pattern, "*", ".*", 1);

      pattern = StringReplace(pattern, "?", ".?", 1);

      

      var re = new RegExp("^" + pattern + "$");

      return re.test(str);

    }

  • Hi Bill,




    No problem. Here is the VBScript version of the script - please let me know if it works for you.




    [VBScript]

    ...

      Dim obj, storedObj

      Set obj = ' Obtain the target application object

      Set storedObj = Objects.StoredObject("MyStoredObj")




      Call Log.Message(CompareObjects(obj, storedObj, ""))

    ...




    Function CompareObjects(obj, storedObj, excludedProps) 

      Dim prop, child, storedChild, ret, errorStr, i

      ret = True

      errorStr = ""

        

      For i = 0 To storedObj.PropertyCount - 1

        Set prop = storedObj.Properties(i)

        If InStr(1, excludedProps, prop.Name) <= 0 Then

          if Not IsSupported(obj, prop.Name) Then

            ret = False

            errorStr = errorStr & "Object doesn't support the '" + prop.Name + "' property" & vbCrLf

          End If

          If Not CompareStrings(BuiltIn.VarToStr(BuiltIn.GetValue(obj, prop.Name)), BuiltIn.VarToStr(prop.Value)) Then

            ret = False

            errorStr = errorStr & "Property value mismatch (" & prop.Name & "):" & vbCrLf & "Stored value = " & BuiltIn.VarToStr(prop.Value) & vbCrLf & "Actual value = " & BuiltIn.VarToStr(BuiltIn.GetValue(obj, prop.Name)) & vbCrLf

          End If

        End If

      Next

      

      For i = 0 To storedObj.ChildCount - 1

        Set storedChild = storedObj.Children(i)

        Set child = obj.FindChild("Name", storedChild.Name) 

        if Not child Then ret = False

        

        ret = CompareObjects(child, storedChild, excludedProps)

      Next

      

      If Not ret Then Call Log.Error("Objects are not identical", errorStr)

      

      CompareObjects = ret

    End Function




    Function CompareStrings(str, pattern)

      pattern = StringReplace(pattern, "\", "\\", 1)

      pattern = StringReplace(pattern, ".", "\.", 1)

      pattern = StringReplace(pattern, "(", "\(", 1)

      pattern = StringReplace(pattern, ")", "\)", 1)

      pattern = StringReplace(pattern, "[", "\[", 1)

      pattern = StringReplace(pattern, "]", "\]", 1)

      pattern = StringReplace(pattern, "*", ".*", 1)

      pattern = StringReplace(pattern, "?", ".?", 1)

      

      Dim re

      Set re = New RegExp

      re.Pattern = "^" & pattern & "$"

      CompareStrings = re.test(str)

    End Function

  • Hi Bill,




    Sorry for the confusion. Replace the line below:




        if Not child Then ret = False




    with the following code:




        If child is Nothing Then

          ret = False

        End If




    and let me know whether the script works for you now.

  • David,



    Thank you for the quick reply it is appreciated as is the code sample you provide.  Unfortunately I'm not familiar at all with JScript and was wondering if you would be able to post this in VBScript format?  Sorry for the inconvenience.





    Bill
  • Hi David,



    Thanks again for the prompt reply but I'm getting an error trying to run this code. This is the setup code for the test:


    Sub TestPropertyObjects

      Dim obj, storedObj

     

      Set obj = Sys.Process("smartwin").VCLObject("StockForm").VCLObject("pagMain").VCLObject("tabDetails").VCLObject("panDetailsMain").VCLObject("panPricingOtherSwitchesTaxes").VCLObject("panPrices")

     

      Set storedObj = Objects.StoredObject("StockPrice")


      Call Log.Message(CompareObjects(obj, storedObj, ""))


      Set obj = nothing

      Set storedObj = nothing



    End Sub



    I get an "Object Does Not Support This Property or method" exception when the script tries to execute the line "if Not child Then ret = False" in the CompareObjects function.



    At the point of executing this line child.FullName evaluates to Sys.Process("smartwin").VCLObject("StockForm").VCLObject("pagMain").VCLObject("tabDetails").VCLObject("panDetailsMain").VCLObject("panPricingOtherSwitchesTaxes").VCLObject("panPrices").VCLObject("edtCostRate")



    which appears to me to be correct because edtCostRate is the first field on the form that is being checked.



    Any help would be appreciated.







    Thanks again

    Bill


  • Hi Dave,



    Works perfectly!  Thanks for all of your help, I couldn't have done otherwise.





    Thanks

    Bill
  • Hi Dave,



    One last question and there is no hurry for an answer on this.  If I start creating Object Checkpoints and Database Checkpoints to use in my scripts, does TestComplete have to load all of the (baseline) information for each checkpoint into memory when it starts or does it read from disk as the comparisons are called? 





    Thanks

    Bill
  • Hi Bill,




    There is no standard behavior for checkpoints, and the moment when they load data depends on their internal implementation. Could you please tell me what you need this information for?

  • No particular reason.  I was just curious if using these objects would require more memory for TestComplete to load.





    Thanks

    Bill

  • Hi Bill,





    Thanks for the information. The basic information on the checkpoints is loaded when the project is opened. However, the actual checkpoint baseline data should be loaded only when the checkpoint is activated.