Walkthrough: Using multiple Coded UI maps in test automation
This post will continue the previous post of Scaling up your CUIT UI automation for real world projects and walkthrough a sample test project using multiple UI maps.
For this walkthrough, I illustrate writing tests for an e-business website called TailSpin Toys that is an asp.net web application. The application is a regular shopping site that has different model planes for sale and users can login, view model plane details and purchase those that they are interested in.
The test project testing it contains 11 UI maps, each for different portions of the GUI. The test project is available for download here. I suggest readers download the code and look through as they read along the doc.
Since the application has several web pages and a number of user scenarios going through each of those pages, we structure our test project like this:
- One UI map per each UI construct that can be treated separately. Eg: billing page, order details page, shopping cart etc.
- Corresponding .cs and .designer.cs files for each UI map
- One class called TestRunner in the testrunner.cs file that acts as a single point interface to all the test methods and contains instantiations of the UI maps
- Tailspintestcase.cs file containing the test methods for each of the tests
The approach to writing test automation in this case will be slightly different from the one we use in our current Coded UI default model where you use the builder to record actions and add validations to compose the test. In this case, we will first create the building blocks in the form of different UI maps and then use those to compose a test method that acts on each of the different UI blocks.
To construct a UI map, just add a new Coded UI map from the “Add New Item” menu and open the coded UI test builder. Now, record actions on the desired UI or drag and drop controls using the cross hair. Once you are done with the operations on that particular UI component, generate code and save. As you navigate to a new UI component, again create a new UI map and load it into Coded UI builder and repeat the same process. In the Tailspin example, I create a UI map called “HomePage” and drag and drop controls like the different hyperlinks for plane options, hyperlink for cart etc. You can either record a set of actions or compose an action in the HomePage.cs file by creating a new method and adding actions on the controls captured inside the method. I’ve added a couple of navigate methods in the homepage UI map .cs file.
Once we have built all UI maps necessary for a scenario, we are now ready to start testing. In this case, my test scenario is a simple one – buy the “Contoso” Paper Model airplane in the site and ensure order receipt is delivered post billing. You can break this down into the following steps:
- Launch TailSpin
- Clean Up existing shopping cart items
- Go to “Paper Model” page
- Select “Contoso” plane
- Add it to the Shopping cart
- Go to shopping cart and proceed to check out
- Fill out billing and shipping details
- Verify you have order receipt
This scenario has to act on controls from different UI maps. Therefore, we need to instantiate the UI map objects for each of the controls to act on. To make the test method readable and easily maintainable, we add a utility class called test runner that contains properties per each UI map in the test project. When you add a new UI map, you just need to go add a new property in this class to access the instance of the UI map. In the test runner class, we add methods that are thin wrappers over the UI map’s methods containing the recorded actions. Eg: NavigateTopaperModel, SelectaPlane etc.
Now, in order to run this scenario, the test method only has to access the common utility class:
Likewise, we can compose more tests in different test classes, instantiate the utility class and act on different UI maps via the utility class object. Note that you could have very well skipped creating the utility class and directly instantiated each of the UI map objects in every test method and called them directly. That approach will also work, but the test code may look a bit more cluttered. Functionally, however the 2 approaches are equivalent.
Note that since we are testing a web application, the top level window, which will the browser displaying this web site, will be the common ancestor for all controls in the web site. Therefore, we will have at least one instance of the top level window control per each UI map. This leads to duplication of controls across maps, since there are 11 instances of the same top level window across the test project. To fix this, we use the CopyFrom() API to copy the TLW from the HomePage’s UI map into the TLW of each of the new UI maps. This API is called in each of the properties returning UI map instances so that during construction of the new UI map object, we equate the TLWs across all UI maps.
For a data driven test method, the only change would be to pass the desired values as parameters to the calling function in the utility class (which will in turn set the values in the parameters of the object passed into the method defined in the UI map) or directly pass to the UI Map objects themselves . For eg:
Comments
Anonymous
February 17, 2010
Hello Anutthara, I've been trying to add all of the controls of a particular application to a UI Map, but this is proving to be fairly difficult and tedious. Sofar I've been manually finding every single control in the application and performing some kind of action or assert on it in order to get the control into the UI Map. Is there a faster or even automated way of mapping all of an application's controls? Regards, Sander [Anu] Hi Sander - you don't need to add validations to add controls to the UI map. Just drag the cross hair to the control you wish to add, press the "add control" button on the UI test builder (the first icon on the UI map) and it gets added to the map. It would be nice to have a single click that would capture all controls in a given UI - we might just do a power tool for that.Anonymous
February 28, 2010
The comment has been removedAnonymous
March 02, 2010
Hi Anutthara,so you manually changed the files *.designer.cs? Wouldn't any change to the UIMap lead to loss of the CopyFrom() API calls? This scenario doesn't seem very unlikely as applications change quite often and so the tests have to change as well (adding new controls, removing unused controls, etc...)Any ideas how to avoid losing the CopyFrom() calls?ThanksAlbert HofmannAnonymous
March 02, 2010
Never mind. Just saw that the CopyFrom() statements are in testrunner.csSorry.Anonymous
March 11, 2010
Hi Anutthara! Very helpful artical. The CopyFrom method works well for applications have common top windows. But what can we do to handle common "sub windows"? In my application, we have many common tab pages shared by different windows. How can I avoid duplicating these shared "Low level window"? [Anu] In that case, I would recommend you have 2 top level windows per UI map and update both windows using the CopyFrom. You can reduce the tedium by eliminating other windows between top level window and low level window so that the number of windows to update are restricted to 2Anonymous
April 27, 2010
How do you update the various UIMaps? Your description only talks about the initial recording of the 11 UIMaps. If you need to go back and update any of these maps, how do you select the one to work on? When I have launched the coded ui builder, I have not seen any way of selecting a specific map. [Anu] Good q, Hal. Just right click on the UIMap file you want to open and choose to open the file in Coded UI test builder. This will bring up the builder with your UIMap file loaded. thanks, HalAnonymous
May 10, 2010
Hi Anu,Thanks for this informative post.My question is not related to multiple UIMaps but to how VS uses CopyFrom() API when adding objects to a single UIMap.Currently I have a problem where VS is creating multiple copies of parent objects and top level windows whenever I go back and record an interaction with a new object or just add the object to the UIMap. I realize that this is happening because some parent object (or top level window) dynamic property has changed e.g. the Window Title, or the Login that I am using. Is there a way to tell VS to use CopyFrom in this case?Or do I have to manually add that code to UIMap.cs file and add calls to CopyFrom there?What would be the best way to go about this?Thanks,TanvirAnonymous
June 21, 2010
The comment has been removedAnonymous
July 06, 2010
I am getting an error "An item with the same key has already been added" when create a new coded UI test , before opening coded UI builder. I have reinstalled VS 2010 still the issue exists.Please give me a solution.[Anu] Neha - this is a known issue with multiple maps :( The workaround is to create a new UI Map and continue working from there. Is this an acceptable workaround for you?Anonymous
August 26, 2010
Hi,I have problem in accessing separte UIMap files.. Here is the info..1) I added a new folder "Screen1" under my Project (TerraScan)2) Then added new CodedUI test by right-clicking that 'Screen1' folder. ---> Screen1TEST.cs3) Then added new CodedUI map item by right-clicking that 'Screen1' folder --> Screen1UIMap.uitest4) Then recorded some actions ,Generated Coded as "Method_AddScreen1". Here it created two files under "Screen1UIMap.uitest" - Screen1UIMap.cs and Screen1UIMap.Designer.cs5) Then came to 'Screen1TEST.cs' and added new [TESTMETHOD] and trying to call recorded method "Method_AddScreen1".Here i am unable to get "Screen1UIMap" UIMAP file under my project namespace.I am expecting as Terrascan.Screen1UIMap.Method_AddScreen1();But under TerraScan this UIMAP file not listing... Can u give an idea... Anything i went wrong?[Anu] I'll need to see your code or the .uitest file along with the other classes. Can you please post this q on the MSDN forums for a quicker response?Thanks in advanceShanmugavelAnonymous
August 26, 2010
Hi anutthara,I need help on using separate UIMAP.uitest files... Here is my scenario.1) I have created a new folder "Screen1" under my project "TSApp".2) I added new CodedUI test by right-cliking "Screen1" folder --> "Screen1TEST.cs"3) then added new CodedUIMap item by right-cliking "Screen1" folder --> "Screen1UIMAP.uitest" and recorded some actions --> saved as "Method_Add". Here it created "Screen1UIMAP.cs" and "Screen1UIMAP.Designer.cs" files4) then i went to "Screen1TEST.cs" file and trying to call recorded "Method_Add" asTSApp.Screen1.Screen1UIMAP.Method_Add()but here it not listing out this "Screen1UIMAP" file under TSApp.Screen1..Anything i went wrong? Can u give me an idea on this...ORTell me the approach to use separate UIMAP file and creating TEST based on that...Thanks in advance,Shanmugavel.Anonymous
September 08, 2010
Hi,I need to make my TEST RESULT to FAIL through my code after some conditions what i am expecting.How to code this?[Anu] You can use the TCM OM to do this. Look up MSDN help for more info. Search for string "TCM API"What method i have to use?thx...SCSVELAnonymous
October 12, 2010
Shanmugavel.c assert.fail("Message").Anonymous
October 14, 2010
Hi Anu,After reading your guidance i have a few concerns about the scalability of CUIT. In the article you use a helper class to instantiate and get the correct UIMap for the section of the application you are testing. I can see how this is the best way to handle multiple UIMaps with the current system but it rases a few concerns. 1. By doing this it requires you to reaproach the way you create recordings. You can no longer record via creating a new CodedUI Test and then selecting "Record actions, edit UI map or add assertions" because this will create and record into the UIMap.uitest (default)2. Recording needs to be done by right clicking the UItest file and select "Edit with Coded UI Test Builder". My biggest concern here is that Action recordings from MTM can no longer be converted into a CodedUI Test without recording every step. This goes against what makes MTM good, by converting manual tests into automated with ease. 3. It drastically increases maintainability of the Coded UI tests as it requires a lot of restructuring of any recorded tests just to be able to scale it. Is this correct? if it is our time spent on correctly designing tests in MTM would be better spent directly coding CUIT[Anu] Ryan - I'll follow up offline with you with a detailed responseAnonymous
November 16, 2010
Hi Anu,Is it desirable to have only one UIMap.designer.cs file in a Solution or we can have multiple? The problem i am facing is when i create another UIMap.designer.cs file it gives error while comiling that methods or properties already exist in desiner.cs file?So what is the best recommendation for this?[Anu] Nitin - you can have multiple UI maps, but each will create it's own designer file - you don't need to explicitly create any designer.cs filesAnonymous
November 22, 2010
Hi Anu,In Tailspin project we have UI Folder under which UIMaps are placed .1.We have to explicitly make UI Folder and create UI Maps in it .Is to make hierarchy only?2.How to create UI Map file explictly... is it from Add new Item>?(which item)?3.How to make UI Map Designer files explicitly? Arey they readonly tooo?Anonymous
December 09, 2010
I am interested in your response to nitro52. I too have the same concerns. Any way I could get from info from your offline discussion?[Anu] Hi Rodney - I just wrote a comment to Subbu saying our feature pack addresses a lot of Nitro's concerns. We are trying to put together more comprehensive docs around this. Meanwhile, the team blg post should helpAnonymous
December 21, 2010
Hi Anu,we are attempting to Automate functional tests for one of our web project, i ran through various blogs to understand what it take to scale up CUIT for big projects, i do agree with your demonstrations here but i also stuck with similar thought like 'nitro52' had, can you please provide me your view on his comments, i also see provide your view on how Feature pack 2 can help us to scaling up CUIT [Anu] Hi Subbu - with the feature pack 2, we address a large part of nitro's concerns. Editing the UI test xml and parameterizing search queries etc. become pretty easy to do. Check out the post on our team blog at http://blogs.msdn.com/vstsqualitytools for more info on FP2. We are working on additional docs for CUIT - I don't have a release date for those yet ;-) thankssubbuAnonymous
January 16, 2011
I would just like to add some comments on my experience with Feature Pack 2. Firstly the UIMap editor is a great start, It allows you to visually manage your UIMaps and makes it easy to Delete methods or move them from the UIMap (xml) to the code behind (c#/vb) for editing.However i found it still needs some improvements to be fully functional with Scalability. It does not fix one of the key aspects to scalability and that is managing multiple UIMaps. Converting an Action recording into a coded UI Test will always use a default UI Map with the name "UIMap.uitest" There is no way to change which UIMap it gets created in. To add to this there is no way to move the method/controls from the UIMap.uitest file into another UI Map, for example "GeneralUIMap.uitest". Due to these limitation it unfortunately means that you can not use Action recordings as templates from Test Manager and still have your Coded UI Tests Scalable [Anu] Thanks for the review, Ryan. I agree that we have not fixed scalability completely with this. We are trying to prioritize a bunch of backlog items, and unfortunately, this did not meet the bar for the FPAnonymous
January 31, 2011
Hi Anu,I am working with a large app that I have built a bunch of UIMaps for. My issue is that the namespace being generated on these maps is too specific for my needs. Is there a way to change how this is generated?[Anu] Sorry Cam - AFAIK, there is no way to control that right now. Can you post this on the Coded UI forums as well just to confirm?Thanks,CameronAnonymous
March 28, 2011
Hi Anu,This information is really helpful for me. I have a question which is our framework requirement.Is it possible to call a coded UI test into other Coded UI test in same project.[Anu] Ram - yes, you can, but that's not advisable. You'd rather refactor into a function and call that functionThanks,RammohanAnonymous
June 08, 2011
I can't seem to get the sample to work. The website sampletailspin.net/Tailspin.Web is no longer available and I can't seem to get the code to work with the VSTS 2010 ALM VM that Brian Keller just released. It makes it really hard to figure out multiple UI mapps when you guys don't have samples that work. How can I get the sample code to work on a machine where I have tailspin toys working?[Anu] Hi Allen - sorry for the late reply. Can you please write to me at anutthar @ microsoft dot com so I can have someone engage with you until your problem is resolved.Anonymous
June 30, 2011
Anu,Your posts have been very helpful. Thank you for sharing your knowledge and expertise with us.I have a large ASP.NET application that I need to test. I have made a lot of progress, and much of the testing is data-driven. But I have run into a problem that I'm hoping you could help out with. On many pages, there are datagrids with multiple rows. Each row has a column that would uniquely identify the row, and another column with a drop down list. I want to be able to pass in the unique identifier to ID the row, then interact only with the row's drop down list. I hope that makes sense. I would appreciate any suggestions you may have.Thanks,Rich[Anu] Hi Rich - you can use the Instance property to uniquely identify the cells in the data grid. Note that this will mean your properties might have to change when the table gets reordered thoughAnonymous
July 06, 2011
The comment has been removedAnonymous
July 23, 2011
HelloI walked in your way on my application . works fine,but,im trying now to add recording in one of the UIMap with the CUIT editor .after the recorded function added to uimap.designer.cs , all the "old" function in TestRunner class are not recognized any more...can you help ?[Anu] Doron - what does "not recognized" mean? Can you not make calls to those functions?Anonymous
July 28, 2011
The comment has been removedAnonymous
August 01, 2011
Where can I get resource links that shows me how to do data driven testing as you indicate above?[Anu] Try http://msdn.microsoft.com/en-us/library/ee624082.aspxAnonymous
August 29, 2011
Hello Anu,I would like you ask you a question about UI map. Do we have any option that add something to UI map without record. Right now, I just see we can rename or delete but not add something without using record. Thanks[Anu] Unfortunately not - having a page maker sort of functionality would help - that could be a great project for a partner!Anonymous
November 24, 2011
Hi Anu,While trying to record the application VSTS2010 showing "Access Denied" message and the code was not generated.its displaying as below mentioned.could you assist us to solve this problems. // Access is denied. // The control for this action was not recorded. // The control for this action was not recorded. // The control for this action was not recorded. // The control for this action was not recorded. // The control for this action was not recorded. // The control for this action was not recorded. // Access is denied. // Access is denied. // Access is denied. }[Anu] Are you running the app as admin but VS as regular user?Anonymous
November 29, 2011
@SenthilUAC will cause this issue if MTM or Visual Studio is not running as administratorAnonymous
May 15, 2012
Hi AnuI have a question about the updating the uitest file. After creating the UI elements in the uitest file, if I need to update the same to add new controls, what is the best approach?For ex: I got to a webpage and add some controls to the UIMap, the controls are added to the UI Map under a tree kind of view where Window being the root node. After some time, if I wish to edit the UI Map to have more controls, I edit the UI MAp using "Edit with Coded UI Test builder". However, The new controls get created under a different tree with another window being the root node. Now, both the windows have same name and it leads to lots of confusion. I am not sure, how the TestRunner should be configured to handle 2 or more windows with same name.Please advice.Thank You.Anonymous
August 13, 2012
Hi Anu,Thanks for the post! I tried to download the test project. Seems to be its not available. Could you please provide me the working link.Anonymous
November 21, 2012
Hi AnuHow do you add a recording to an existing UI Map in an Multi UI map coded UI?RegardsAnonymous
April 16, 2013
Hi Anu,The information posted by you is very helpful.Following your article i have created multiple UI Map files but not able to data drive. Could you please elaborate on how to apply data driven method.Thanks,SreeyaAnonymous
June 12, 2013
Hi Anu,How can we select custom range in Data Driven Testing. Iteration property shows disabled for a Test. I read somewhere that this feature not supported. Can you please suggest any workaround?Anonymous
August 20, 2013
I too tried to download the test project but it's not available. Can you provide a working link?Anonymous
September 16, 2013
Where can I download the sample test project?