Namemapping nightmare
SOLVED- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-20-2014
10:27 AM
02-20-2014
10:27 AM
Namemapping nightmare
Hi,
I am new to Testcomplete and having trouble with namemapping. I am using Testcomplete to test a WPF based application. The issue is that UI on the application keeps changing, and each time I have to update the namemapp as well as the tests that use onscreen actions. This is a nightmare as it takes a lot of time, and most of my time is spend on updating namemapping and the tests.
1) Namemap is like a tree, so if something is added near the root then I need to remapp all the child nodes even when they did not change. There is no mechanism to copy paste the nodes or to insert a node in between the tree. Is there a workaround or feature to do this easily?
2) Also, even after updating the namemapping I need to update the refereneces in the tests and onscreen actions. Is there a better way to do it?
Is there a better alternative to namemapping or a better way to handle this scenario?
I am new to Testcomplete and having trouble with namemapping. I am using Testcomplete to test a WPF based application. The issue is that UI on the application keeps changing, and each time I have to update the namemapp as well as the tests that use onscreen actions. This is a nightmare as it takes a lot of time, and most of my time is spend on updating namemapping and the tests.
1) Namemap is like a tree, so if something is added near the root then I need to remapp all the child nodes even when they did not change. There is no mechanism to copy paste the nodes or to insert a node in between the tree. Is there a workaround or feature to do this easily?
2) Also, even after updating the namemapping I need to update the refereneces in the tests and onscreen actions. Is there a better way to do it?
Is there a better alternative to namemapping or a better way to handle this scenario?
Solved! Go to Solution.
21 REPLIES 21
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-20-2014
07:32 PM
02-20-2014
07:32 PM
Forget name mapping and use small scripts that search your entire app for the object you need, sending as parameters the properties they have, for example (this works for me because i'm testing a webapp, but I think it works for anything):
function clickObject(propName, propValue,depthOfSearch)
{
Sys.Process("yourApp").FindChild(propName,propValue,depthOfSearch).click(0,0);
}
Now you can use this for any action your object supports, use object spy to see all the details about the object you're looking for.
This solves your issue because it always finds your object, unless their properties change, wich they shoudn't.
Name mapping is only usable if your app will never change, otherwise you need to take a crash course on how to be able to configure it to work with wildcards and stuff....
function clickObject(propName, propValue,depthOfSearch)
{
Sys.Process("yourApp").FindChild(propName,propValue,depthOfSearch).click(0,0);
}
Now you can use this for any action your object supports, use object spy to see all the details about the object you're looking for.
This solves your issue because it always finds your object, unless their properties change, wich they shoudn't.
Name mapping is only usable if your app will never change, otherwise you need to take a crash course on how to be able to configure it to work with wildcards and stuff....
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-20-2014
10:56 PM
02-20-2014
10:56 PM
After spending some time investigating name mapping for testing a rather large and complex web app I ended up taking the same approach as Jose suggests. I wrote a small function that searches the page for an object by its property value and then returns the associated property name. Returning the property name is useful because I call the function in other routines I wrote to perform different actions on the found object.
My function for locating objects stores property names in an array. When I find I want to support a new property name I can simply add it to the array.
When writing the tests I use object spy to get a supported property value from the object I want to interact with.
This lets me write test scripts like this:
Call Click("PropertyValue")
Call AddText("PropertyValue","some_text")
Call KeyPress("PropertyValue","Enter")
My function for locating objects stores property names in an array. When I find I want to support a new property name I can simply add it to the array.
When writing the tests I use object spy to get a supported property value from the object I want to interact with.
This lets me write test scripts like this:
Call Click("PropertyValue")
Call AddText("PropertyValue","some_text")
Call KeyPress("PropertyValue","Enter")
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-21-2014
01:19 AM
02-21-2014
01:19 AM
If I am understanding you correctly, the development team is making changes to the UI that changes your mapping such that the tests you've written no longer work.
I had the same issue and asked dev to find a property on each form that is decriptive in nature and not being used. I had them put a unique 'name' in this property (frmLogin, scrnEntry) and used this plus a FEW other properties that will not change to map the screen.
As you have noted the closer the form/screen is to the root of the app, the more critical it is that this property is maintained as poorly executed changes here definitely screw up the mapping.
I also asked dev to ensure that if a control on a screen is deleted, replaced, or modified that the unique property carry the same name as the one used for mapping.
The company spends good money for TC and your paycheck, dev can help you and the company maximize the return on this money by doing this. Good luck!
Jon
I had the same issue and asked dev to find a property on each form that is decriptive in nature and not being used. I had them put a unique 'name' in this property (frmLogin, scrnEntry) and used this plus a FEW other properties that will not change to map the screen.
As you have noted the closer the form/screen is to the root of the app, the more critical it is that this property is maintained as poorly executed changes here definitely screw up the mapping.
I also asked dev to ensure that if a control on a screen is deleted, replaced, or modified that the unique property carry the same name as the one used for mapping.
The company spends good money for TC and your paycheck, dev can help you and the company maximize the return on this money by doing this. Good luck!
Jon
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2014
08:13 AM
02-24-2014
08:13 AM
+1 both for using small utility functions to search for the objects dynamically and for Name Mapping on unique properties and then searching down the tree rather than mapping every single object in the tree branch (Extended Find option would be your friend here).
If you decide to write script functions to find the objects for you, you can always move them out into a Script Extensions Runtime Object, which can make them much like Aliases in TestComplete. I've done this on a few different products to allow sharing the functions between multiple TestComplete Projects.
If you decide to write script functions to find the objects for you, you can always move them out into a Script Extensions Runtime Object, which can make them much like Aliases in TestComplete. I've done this on a few different products to allow sharing the functions between multiple TestComplete Projects.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2014
10:36 AM
02-24-2014
10:36 AM
After writing a utility function to search for objects and return select properties I realized it woud be better to return the object rather than its values. Now I can peform whatever operations I need on the returned object (click, add text, delete text... and so on).
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2014
06:52 PM
02-24-2014
06:52 PM
I completely agree with everything said above.
The only thing I'd like to add is that in my opinion NameMapping object must not be used in the test code but Aliases must be used instead. The reason is that hierarchy of the namemapped objects might change as the application evolves, but the chances are higher that the structure of Aliases can be kept unchanged, thus keeping test code not modified.
For example, let initial namemapping for some button was like this:
NameMapping.Sys.browser.page.panelOuter.panelContainer.buttonSave
In the Aliases tree this button can be moved higher in the hierarchy, for example:
Aliases.browser.page.buttonSave
Note, that internally Aliases maps the button to the real object through the namemapping, but this is hidden from the test code. So, if later developers decide to move the button on the additional panel, e.g.:
NameMapping.Sys.browser.page.panelOuter.panelContainer.panelButtons.buttonSave
the only thing that will have to be done will be to adjust the namemapping. But this correction will leave Aliases unchanged and thus require no modifications to the existing test code.
Obviously, to be able to implement such approach, the initial Aliases structure should be considered from the very project start.
The only thing I'd like to add is that in my opinion NameMapping object must not be used in the test code but Aliases must be used instead. The reason is that hierarchy of the namemapped objects might change as the application evolves, but the chances are higher that the structure of Aliases can be kept unchanged, thus keeping test code not modified.
For example, let initial namemapping for some button was like this:
NameMapping.Sys.browser.page.panelOuter.panelContainer.buttonSave
In the Aliases tree this button can be moved higher in the hierarchy, for example:
Aliases.browser.page.buttonSave
Note, that internally Aliases maps the button to the real object through the namemapping, but this is hidden from the test code. So, if later developers decide to move the button on the additional panel, e.g.:
NameMapping.Sys.browser.page.panelOuter.panelContainer.panelButtons.buttonSave
the only thing that will have to be done will be to adjust the namemapping. But this correction will leave Aliases unchanged and thus require no modifications to the existing test code.
Obviously, to be able to implement such approach, the initial Aliases structure should be considered from the very project start.
Regards,
/Alex [Community Champion]
____
[Community Champions] are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Posts made by [Community Champions]
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
The [Community Champion] signature is assigned on quarterly basis and is used with permission by SmartBear Software.
https://community.smartbear.com/t5/Community-Champions/About-the-Community-Champions-Program/gpm-p/252662
================================
/Alex [Community Champion]
____
[Community Champions] are not employed by SmartBear Software but
are just volunteers who have some experience with the tools by SmartBear Software
and a desire to help others. Posts made by [Community Champions]
may differ from the official policies of SmartBear Software and should be treated
as the own private opinion of their authors and under no circumstances as an
official answer from SmartBear Software.
The [Community Champion] signature is assigned on quarterly basis and is used with permission by SmartBear Software.
https://community.smartbear.com/t5/Community-Champions/About-the-Community-Champions-Program/gpm-p/252662
================================
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-24-2014
06:58 PM
02-24-2014
06:58 PM
"R. Gratis
If you decide to write script functions to find the objects for you, you can always move them out into a Script Extensions Runtime Object, which can make them much like Aliases in TestComplete. I've done this on a few different products to allow sharing the functions between multiple TestComplete Projects."
Yesterday I was investigating this option but I found some forum entry saying that you can't debug \ catch errors from Script Extensions. Haven't tried it yet, but I don't think I'm willing to.
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-27-2014
01:04 PM
02-27-2014
01:04 PM
I don't think you all understand how painfull it is to write scripts for testing WPF applications, specially large ones.
WPF by nature wraps every single control with many layers of useless things (useless for testing purposes). Now.... this things are the ones that make finding things difficult.
In my case I have to use both mapping and searching tools in order to find objects.
Those I can mapp well... they are the easiest.
Those I have to find.... not always have a good result.
I'll give you an example:
in this example tree
|- region
|- wrapper
|- button
|- wrapper
|- wrapper
|- name = "Button1"
when you search using FindAllChildren you look for the button name right? Well the function returns the actual path to the name property or if you are lucky the parent (wrapper). Now the wrapper is not clickable since is not visible or enabled (sometimes) which makes it really difficult to climb up in the tree since there's not FindParent method to call.
Now HD, try to mapp as much as you can. Make sure you don't mapp properties that change every time you run the program and for searching purposes try to make your own functions calling FindAllChindren inside, so you can add parameters and search from different parts in the tree.
Good luck
WPF by nature wraps every single control with many layers of useless things (useless for testing purposes). Now.... this things are the ones that make finding things difficult.
In my case I have to use both mapping and searching tools in order to find objects.
Those I can mapp well... they are the easiest.
Those I have to find.... not always have a good result.
I'll give you an example:
in this example tree
|- region
|- wrapper
|- button
|- wrapper
|- wrapper
|- name = "Button1"
when you search using FindAllChildren you look for the button name right? Well the function returns the actual path to the name property or if you are lucky the parent (wrapper). Now the wrapper is not clickable since is not visible or enabled (sometimes) which makes it really difficult to climb up in the tree since there's not FindParent method to call.
Now HD, try to mapp as much as you can. Make sure you don't mapp properties that change every time you run the program and for searching purposes try to make your own functions calling FindAllChindren inside, so you can add parameters and search from different parts in the tree.
Good luck
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
02-27-2014
07:27 PM
02-27-2014
07:27 PM
Leandro Poblet-> In my webapp, when I use the find function, sometimes I must set the "depth" property to 50, so don't try to explain how hard it is!! 🙂
you have a lot of workarounds for those problems you said:
If you need the code for any of this options shout, but please, be specific in what you need.
you have a lot of workarounds for those problems you said:
you can send an array of properties in order to focus your search, search the object with the object spy to see wich properties are make it unique
you can use Find or FindChild and then, in the returned object, do "object.Parent" if you need to find the parent, and you can do that as many times you want "climbing up the tree"
In the beggining of a script you can find the container wich has the objects you'll be working on and use it to find the rest of the objects from that point on
If you need the code for any of this options shout, but please, be specific in what you need.
