Ask a Question

Day 1 - API Testing vs. UI Testing

SmartBear Alumni (Retired)

Day 1 - API Testing vs. UI Testing

Hello TestComplete Community,


I’m happy to welcome you to our API Testing vs. UI Testing competition. We aren’t going to fight. We are going to identify what it is like - “Doing UI Testing”.

Each day, we will publish a new topic to discuss. Leave your comments in topics - you and your UI Team will be rewarded.


Today, let’s introduce ourselves to the Community! Post a high-level description of the project you are working on.


Leave your comments here.


UI Testing Score

Track the current score and daily conversations on this page:


Bonus Tasks

Accomplish any of the bonus tasks to earn more points:

  1. +2 points - Invite your colleague to the competition.

Mention a nickname of this person by using @ in the competition’s daily topics. You can invite as many people as you wish. NOTE: A person you invite should be a new Community member registered after the event start.


  1. +2 points – Make a post on social media about your participation in the competition.

Your post should contain: @SmartBear, the #APIvsUITesting hashtag and the link to your comment in the Community.

Simple tweet: API Testing vs UI testing! Which one is more important? Join me in the @SmartBear Community to talk about this: #APIvsUITesting


Event Rules

  1. Leave your comments on a conversation of the day. 1 comment = 1 point to the team score.
  2. The competition will be held on March 25-29.
  3. Join the competition any day and participate in any daily conversations.
  4. Feel free to leave comments for any teams.
  5. Rewards! A team with the biggest score will win. Active participants from each team will be rewarded.


Let's start!

Tanya Yatskovskaya
SmartBear Community and Education Manager


Hi @dpaulus , I'm also testing Delphi applications that use Virtual String Trees a lot and struggle with it. As of yet I have not been able to work out which Object Mapping on the project property to use in order to identify properties within the VST. When I use the object spy and select an VST object it returns the error "Error: An exception occurred: 0x0EEDFADE; class: EComponentError; description: 'TVirtualStringTree has not been registered as a COM class'" on the ComObject property. Are you able to share how you have been handling them?

Occasional Contributor

Oh man - yeah, those are a pain.  Currently, we ended up having our developers write a little function to do the dirty work for us (see code below), and then we call the function from our TC scripts as needed.  I'm not a big fan of this method, and I did write a script that could handle it at one point, but it didn't work for every situation.  I don't think this does either, but it's a bit easier to call.  If you choose to use this, then you'd have to have your developer put it in their code (obviously, not ideal), and then call it from a debug version of the app your testing.  Regarding your error, seems like there's a possible problem there, but a general idea here is to use the Object Browser, instead of Object Spy, because it'll give you a lot more detail about all the components, not just the one you highlighted.  I almost exclusively use the Browser now when trying to lookup an object.


Delphi Code:


// Data can look like any of 'Value' or '[Value]' or '[Value][SubValue]' as many levels deep as needed.
// The result they want back is |[n1]|[n2], etc.
//   where n1 is the node index of Value,
//         n2 is the child node index of SubValue, etc.
//   note the pipe.  |[x] for each value returned.
function TVirtualStringTree.GetNodeIndex(Data: String; VisibleColumnIndex: Integer): String; // for QA
  Path: String;
  Column: Integer;

  function FindChild(aNode: PVirtualNode; aData: String): PVirtualNode;
    Node: PVirtualNode;
    Idx: Integer;
    Result := nil;
    idx := -1;

    if aNode = nil then
      Node := GetFirst
      Node := aNode.FirstChild;

    While Node <> nil do
      idx := idx + 1;
      if Text[Node, Column] = aData then
        Path := Path + '|[' + IntToStr(idx) + ']';
        Result := Node;
      Node := Node.NextSibling;

  lData: String;
  Node: PVirtualNode;
  aTS: TStringList;
  ColumnsArray: TColumnsArray;
  if Data <> '' then
    aTS := TStringList.Create;
      ColumnsArray := Header.Columns.GetVisibleColumns;
      Column := ColumnsArray[VisibleColumnIndex].Position;
      Path := '';

      lData := Data;
      if lData[1] = '[' then
        lData := Copy(lData, 2, MAXINT);
      if lData[Length(lData)] = ']' then
        lData := Copy(lData, 1, Length(lData) - 1);

      aTS.Text := Trim(StringReplace(lData, '][', #13#10, [rfReplaceAll]));

      Node := FindChild(nil, aTS[0]);
      while (aTS.Count > 0) and
            (Node <> nil) do
        Node := FindChild(Node, aTS[0]);

      if Node <> nil then
        Result := Path
        Result := '';


Not sure what language your scripts are in, but ours is in Python, and below is how it's called...

# Process TVirutalStringTree
def Process_TVirtualStringTree(ItemObjStr, ItemValue): 
    ColIndex = '0'  
    # if '>' is found, split    
    if ItemValue.find('>') != -1:       
      ColName, ItemValue = ItemValue.split('>') 
      # get list of column headers      
      ColumnList = ItemObjStr + ".ContentToText(3,',')"
      ColumnList = eval(ColumnList)    
      ColumnList = ColumnList.split(',')  
      # loop through header list until value is found, then set index                       
      index      = 0                                                            
      index2     = 0
      ColIndex   = -1   
      for item in ColumnList:
        index = index + 1
        item = item.strip()
        if item == ColName:
          ColIndex = str(index2)
        index2 = index2 + 1    
      # if ColIndex is never updated, then the column was never found - log error  
      if ColIndex == -1:
        Log.Error('Column not found')
    # pass column value and column index to John's routine         
    NodeIndex = ItemObjStr + '.GetNodeIndex(' + '\'' + ItemValue + '\'' + ',' + ColIndex + ')'
    NodeIndex = eval(NodeIndex)
    # if john's routine returnes -1 then we log an error
    if NodeIndex == '':
      Log.Error(ItemValue + ' not found')
    ItemValue = NodeIndex
    return ItemValue
  except Exception as Error:
     TerminateDueToError('Process_TVirtualStringTree', str(Error))

Hope this helps.

Thanks for this. I use JScript for scripting but I'll discuss this with our Delphi developers and see if we can come up with a similar solution. 

Showing results for 
Search instead for 
Did you mean: