Forum Discussion
Thanks for the reply
I have Test Complete setup to auto name-map so everything you're seeing was done by test complete.
I''d love to trim it up a bit to make it easier to understand but there are countless areas of ourapp that has containers and sub containers inside that container and tabs inside that contaier that have their own containers etc.
So usng your example below, there's always something that gets used somewhere among hundreds of tests.
Do you have any suggestions on how to know what sections are not necessary? After years of writing scripts for our appication it seems no matter what I try and manually name map, it's already been mapped by Test Complete.
Thanks again for the reply, really appreciate it.
As mentioned above, I find it tends to be cleaner to map things manually so that you only ever end up with the parts you actually need. That's how I've done it from day 1. Auto-mapping just tends to leave you with a lot of clutter you don't want.
I use a combination of mapping and helper (finder) functions to identify objects on the fly during a run. I try to only map to quite a high level (say - page/panel/tab level .... depending on what you're testing). After that, it depends how easy, or not, it is to identify and object as to whether I map it or not.
For example, I'm currently working on a Delphi application. Two types of control it uses are the usual checkboxes and textboxes. The checkbox has it's caption/label as part of the actual checkbox. So I use a helper function with those to find them at runtime as I know the caption used to seach will be identical to the on-screen label. All my tests are data driven so the user filling out the data sheet only needs to know the caption and control type - my scripts will find it with the suppplied info, or log an error and keep going if the object was not found/does not exist. Whereas, textboxes have a separate label element and there is no direct link (containers are sometimes used, but not always) between the label and textbox. So a helper function is not very practical and I map those objects (manually) and rename them so their Alias name is identical to the label. So again, the user only has to know what it says on screen and populate the data sheet accordingly. Again, I have a function that takes this data, converts it to the right format for the Alias map (having a cut down Alias map so that it makes easy sense of the application is essential here) and ensures it exists, error if not, etc.
In order for this approach to work, a good Alias map is essential.
It's usually pretty obvious which mapped elements you need, and which you don't. As a starter for ten, relate the Alias to what you actually see on screen and the parts of the screen you interact with. If you have multiple containers, it sometimes makes sense to use them, sometimes not. My general rule of thumb is only use extra containers in the Alias map if you have to to avoid duplication.
So if you had two sets of buttons, each inside a container, I would only have the container in my map if I needed it to distinguish between the buttons.
eg.
If I had:
>Page
>>Container
>>>Container
>>>>Tab1
>>>>Tab2
>>>>Tab3
But the two Container elements were only there to maintain page structure, I wouldn't have them in the Alias map. Because, as a user, I neither care nor interact with them.
So the Alias map would be:
>Page
>>Tab1
>>Tab2
>>Tab3
And if I was working on Tab2 and it had:
>Tab2
>>Container
>>>Frame
>>>>Container
>>>>>ButtonPanel1
>>>>>>Button A
>>>>>>Button B
>>>>>>Button C
>>>>>ButtonPanel2
>>>>>>Button D
>>>>>>Button E
>>>>>>Button F
The ButtonPanels may contain some header text for the panel containing the buttons, but as long as the buttons are distinct/and unique, I likely wouldn't bother with it. (I would probably only bother if the button names made absolutey zero sense without them, which is unlikely). So the Alias would look like:
>Tab2
>>Button A
>>Button B
>>Button C
>>Button D
>>Button E
>>Button F
However .... if the buttons were duplicates (in look to the user - captions etc) such as:
>Tab2
>>Container
>>>Frame
>>>>Container
>>>>>ButtonPanel1
>>>>>>Button A
>>>>>>Button B
>>>>>>Button C
>>>>>ButtonPanel2
>>>>>>Button A
>>>>>>Button B
>>>>>>Button C
Then the button containers would be needed to maintain sense/readability. So I would have:
>Tab2
>>ButtonPanel1
>>>Button A
>>>Button B
>>>Button C
>>ButtonPanel2
>>>Button A
>>>Button B
>>>Button C
As otherwise you wouldn't be able to tell the two sets of buttons apart.
I'll also sometimes use multiple copies of a higher level element in order to create a logical distinction in the Alias map. Using the above example, say it looked like:
>Tab2
>>Container
>>>Frame
>>>>Container
>>>>>ButtonPanel
>>>>>>Button A
>>>>>>Button B
>>>>>>Button C
>>>>>>Button A
>>>>>>Button B
>>>>>>Button C
So now all the buttons are in a single container, their labels are separate (Delphi style) so there is no way to easily know which button is which. So I would Alias map that as:
>Tab2
>>Copy of ButtonPanel(1)
>>>Button A
>>>Button B
>>>Button C
>>Copy of ButtonPanel(2)
>>>Button A
>>>Button B
>>>Button C
With the two Aliases of ButtonPanel named differently in order to maintain the distinction between the buttons.
Then it's down to making sure you map the object in such a way that they maintain easily, remain unique, and are easy to read.
This approach, combined with helper functions for objects which are identified on the fly, has always worked well for me. As long as you set it up right in the first place, maintenance should only ever be required on the object map and the Alias map should only need updated in the event of major structural changes to the application.
In other words (TL ; DR), in my world:
The object map (I think of this as TestCompletes map) should (must!) be a direct representation of the object model of the application under test. (Otherwise it won't work!)
The alias map (I think of this as MY map) should be a heavily abbreviated version of the object map which you can relate much more directly to what you actually see and interact with.
:smileyhappy:
- coreyallen10 years agoOccasional Contributor
Thanks for the reply
Sadly I have years and years of tests at this point so unless we get the option to refractor I'll be stuck as-is.
- Colin_McCrae10 years agoCommunity Hero
Bummer.
In which case, it's a case of working your way up the object tree until you get a working object. Then dragging/adding/remapping from there until it works again.
I *assume* the Alias map should reflect the changes as you make them? But I don't do it this way so I'm not sure.
** EDIT **
Mind you .... if you have Alias references in code all over the place, and the Alias chain changes, are the changes automatically propagated out to any code that uses them? If not, you're gonna have a lot of updates to make! Ouch.
This is what I mean about setting out the rules of your Alias map early and keeping it concise and tidy. It pays dividends further down the line in scenarios like this. In my case, the container objects would never be in the Alias map in the first place, and nor would the new one be, so the Alias object (once the Object Map that dives it was tidied up) would never change.
- coreyallen10 years agoOccasional Contributor
Thanks
It appears I'm stuck and will need to make a lot of updates manually.
Related Content
- 3 years ago
Recent Discussions
- 20 hours ago
- 21 hours ago
- 5 days ago