Fluent Bytes

"The only source of knowledge is experience" - Albert Einstein-

Using CodedUI testautomation without UIMap files

One of the things I hear a lot from developers working on test automation is that they dislike the way CodedUI tests in visual studio work with the UIMap files. I can understand that most developers will assume this is the required way of work, since it is strongly advertised when you create a new codedUI test project. I mean the first dialog they show is if you want to create tests based on existing action recording in MTM or record new actions with the UI test builder.

image

In my opinion this dialog should have one other obvious option, that is Hand code the tests using the provided CodedUI object model.

In this post I want to introduce you to the way I like to organize my CodedUI tests so I get a robust and maintainable set of test automation scripts.

As an example I will take an ASP.NET MVC web application as the system under test. I have picked an sample MVP project called MVC Music Store, that you can download here if you want to try things for yourself and you need an app to test it on.

Page objects

The way I like to create my tests is by applying the page object pattern that is commonly used in the UI test automation discipline. With the page object pattern you analyze the application and create an UI abstraction class for each UI component you find in the application. For MVC this maps mostly to views, for XAML apps this will mostly map to XAML pages and for windows forms to actual forms you have in the project. Page objects don’t have to represent a full page, they can also represent a commonly used user element.

Lets take the MVC music project as an example. Here you see the home screen of the application under test.

image

Here you can see the MVC project structure with the different views.

image

After a bit of analysis you can determine what the set of classes should be to abstract the user interface in page objects we can use later to code our tests. Based on my analysis I would create the following set of classes to abstract this application:

  • AccountLogon
  • AccountChangePassword
  • AccountRegister
  • Checkout (One object, since complete only contains one message)
  • Home
  • ShoppingCart (One object since cart summary only contains one link)
  • StoreDetail
  • StoreBrowse
  • StoreManager
  • StoreManagerDetail

Let’s dive a little bit deeper and look at the home page and the Shopping cart page to give you a sense how to decompose this and then write the appropriate test abstractions.

The home page can be dissected into multiple area’s. Many of the things on the home page are generic and can be interacted with from any other view. In the picture below I highlighted the area’s that I would expose as actions (Red) and area’s that contain controls (blue) that I will abstract in my page object as controls you can interact with.

image

From this I would create a base class where all my page objects inherit from. this base class exposes the following actions:

  • HomePage NavigateHome()
  • ShoppingCart NavigateShoppingCart()
  • StoreManager NavigateStoreManager()
  • StoreBrowse NavigateStore()
  • StoreBrowse SelectCategory()

Shared Elements

  • HtmlList CategoryList

You can see that each action will return a new Page object. You will see how this enables a very nice way to describe scenario’s later in the actual test methods.

I would create a HomePage page object that inherits from the base class and would add the following action:

  • StoreDetail SelectProduct()

and one additional control:

  • HtmlList FresshOfThegrillList

Now let’s implement this class without the use of the UIMap files

How CodedUI finds controls

CodedUI finds controls by searching and filtering. First it will start a search starting from a root element you provide. for a browser based test, this is normally the browser window. this means we need to pass out page object this browser window. this can be done in the constructor.

If you don’t use the UIMaps you can find a specific control by using one of the control types provided in the HtmlContols namespace. If I want to find an HyperLink based on the id you do this as follows:

In this sample I assume you have a private variable _browserWindow that is of type BrowserWindow.

If I want to click that hyperlink the only thing I need to do is call the mouse click on that control

One thing you might notice is that there is no explicit call to the Find() method on the control. A call to Find() is optional since any access to the control will trigger a lazy evaluation of the search and will result in the search for the object in the browser.

In some scenario’s you might not be able to locate a control by it’s ID. Although this provides the most robust way of finding the control even after restyling of the application, this is not always under your control. For this you can use many other search options like searching on css class name, inner text values, etc. If you use this way of allocating the controls I would recommend to slightly alter the search by using an operation contains in stead of an exact match. this way the test will be a little bit more change resilient. Below you see a search for the same hyperlink, but now based on it’s inner text and the fact that it is part of the innerText, not an exact match.

Building the page classes

Now that we know how to locate controls, let create the actual shared class and the home page page objects. the Shared class will become something like this:

the home page class looks like this:

Creating the actual tests

Once we have created these page objects to represent the user interface, you can write very nice readable scenario’s.

I hope I this article showed you that the CodedUI syntax to find controls is very easy to use and that you don’t need to use the CodedUI UIMap files. CodedUI maps have a place and are great for getting started fast. In general these files are less optimal for larger automation projects. You can still use them, but then I would advise to build your page objects using the UIMap files and have one UIMap file per page object. this way you can mostly avoid nasty merge conflicts when working in a team.

Using the page object pattern in general, provides you with a very nice abstraction of the UI and the ability to write fluent scenario based tests that you can read almost as you read a test case in text. this way you create very maintainable nicely layered test code.

CTO at Xpirit, Microsoft Regional Director, Visual studio ALM MVP, Speaker, Pluralsight Author and IT Architect Consultant

13 Comments

  1. I am trying to CUIT against a windows form built in VS 2010 using the same tool.

    This is a huge application that takes weeks to test by hand. It contains a number of datagrid views that when double clicked open an associated control. Many of these controls contain an ID as a title (just a number no other text of pattern for smart search to use). One of these controls is REALLY large, it contains 6 combo boxes 16 text fields, 3 checkboxes, 2 date fields and a partridge in a pear tree. All these items need to behave in a certain way depending on the selection of the combo boxes (be grayed out or provide a certain error), we’ll call this control “the Plan control”. I had started to record the codedui scripts but when my uiMap quickly reached thousands of lines of generated code I began to look at handcoded ui to see if I could simplify things.

    Note that when building a new “plan” that has never been saved before, the title bar reads “New Plan *”, once I save it, the next time I open it it will have the title “1” if it’s the only plan, “2” of it’s the second plan and so on.

    I created a new UIMap for the plan window and added all the controls using the recorder’s “Add control to UI Map” option but renaming them to more appropriate names (the recorder really messes up the names, calls one control by it’s neighbors name for instance) , it still generated about 1200 lines of code but I was able to create methods to make use of them and recreate other new plans with what ever settings needed.

    Now we finally arrive at the problem: I also need to modify exising plans using coded uis but all my recordings contain “New plan *” as a WindowTitles property. So when I try to use these objects on a window titled “1”, it crashes. I tried looping through each control and updating the WindowTitles to the appropriate value but it doesn’t work. Does this mean I have to create a new oject hiarchy for each possible plan title? Modifying an exising plan also means that the comboboxes are set to other values then when I first added them to the UIMaps which also seems to be an issue.

    I followed your course and Plural sight and your hand coded ui blog but didn’t see anything with these issues specifically. Any help or advice you could offer would be much apreacated.

    Best regards

  2. By defining each control by hand, removing all window title properties and using the control name search property I was able to fix my own problem. Tests are now faster and much more solid. I feel I still owe you thanks for your courses & blogs helped me. So thanks 🙂

  3. Hi
    I am a newbie on this technology . Is it possible to download the completed project or alternatively could you please share the link from where I can download it from ?

  4. Hello Marcel,
    This is a very informative post. I was recently tasked at automating an immensely huge web application. This pattern came naturally due to necessity, glad to see I’m on the right track. I would however like to know who to tackle web pages that use complex JavaScript and Ajax calls that affect web page UI

    • What are the specifics you are looking for? Do you need to interact with the page waiting for calls to complete? do you need to validate some of the java script? Different goals can be reached with different tools, so not all should be done e.g. with codedUI

  5. Hi Marcel,

    I recently finished your Coded UI course on Pluralsite. I tinkered with the UIMap option, but found it didn’t not work when recognising the object.

    For example, the UIMap contains these values
    WinRow uIRow3Row = this.GUISWindow.UITable.UIDataPanelClient.UIRow3Row;
    WinCell uIRow3Cell1 = this.GUISWindow.UITable.UIM1Cell;

    But it can’t find UIM1Cell. If I edit the UIMap it can actually find the cell under here:
    this.GUISWindow.UITable.UIDataPanelClient.UIM1Cell;

    So i’ve to hand code everything for best results, but i’m not that familar with the best way to structure the project as my back ground is scripting and not oo programming.

    Do I create all the extra classes in the CodedUITest.cs file or add > New Item > C# Class to the solution and have each one as a separate class file or doing something similar to the way the record option does and add a MyUIMap file to the solution and dump all my classes in here?

    Thanks,

    John

    • I would suggest to use one file per Page, that gives the best separation of concerns. Each class represents one page object and isolates the interaction with the page.

  6. To add to the above post:

    From the look of ‘Demo: Control Wait Options’ on Pluralsite, it looks like you have a CodedUITest file with the test steps and any class used within that file. But I will probably need to reuse some of these classes across test cases.

  7. Hello Marcel,
    I have a question. Here in my company we are beginning to automate our test cases with CodedUI. But they insist in record the test cases and then use it to create code, instead of handcode. They say its because of the parameters they set on test cases on Test Manager.
    Im trying to find a way to still use the parameters of MTM test cases, but not use record anymore. Is there a way to do it?
    Thanks !

    • the only thing what happens when they use code generation from an MTM test case is that a couple of attributes are added to the test case, so it knows how to use MTM as a data source for the parameters. So yes it is very easy to just use the same parameters, by just using the same data source attribute and referring the MTM test case. that way you can write the tests in a maintainable way and leverage the parameters that can be maintained in MTM. If you look at data driven tests in the first course I published at Pluralsight on CodedUI, you will find there a reference how to do it.

  8. Hello Marcel,

    Let’s think on the top level of abstraction, where disregard of the object class I want to use the parent class (HtmlControl) to manipulate all the possible objects under this class.

    And as search mechanism would like to use JQuery String, my approach is to generate and xpath (static) from the JQuery search results, and then having a unique identifier (xpath) would be able to search the object properties and manipulated.

    I realize that Microsoft has not added the xpath as property to be used as part of the search properties, found a DLL published by someone that states that would work giving a xpath query and returning the match UITestControl, however is giving me an exception, of the searchProperties underlying search mechanism, this application does not have Id, Names; that I can get a hold otherwise would be easy as pay.

    Would you please help me out here?

    Thanks in advance

Leave a Reply

Your email address will not be published.

*

© 2017 Fluent Bytes

Theme by Anders NorenUp ↑