This is part 4 in a series of posts on creating and maintaining Coded UI tests with Multiple UI maps. My intent here is to give a little more detail to help those new to Visual Studio.
Part 1: Creating a new Coded UI solution
Part 2: Adding a New UI Map
Part 3: Modifying an Existing Coded UI Map
Part 4: Adding a UI Map to the TestRunUtility
Part 5: Assembling the test
Part 6: Changing Recorded Methods
Part 7: Deleting actions when recording with the Coded UI Test Builder
Part 8: Modifying Generated Code
This technique is an extension of the technique found in the following links by Anu , a Program Manager in the Visual Studio ALM Test Tools group and the MDSN documentation. http://blogs.msdn.com/b/anutthara/archive/2010/02/08/scaling-up-your-cuit-ui-automation-for-real-world-projects.aspx
http://blogs.msdn.com/b/anutthara/archive/2010/02/10/walkthrough-using-multiple-coded-ui-maps-in-test-automation.aspx
http://msdn.microsoft.com/en-us/library/ff398056.aspx
Creating the TestRunUtility
In my last post I mentioned we could reference and call each of these maps individually and successfully test this scenario without a problem. The weakness in doing that is that we have quite a bit of duplicate code in our generated UI maps. Specifically if you do a file search for ?Home - Tailspin Toys? you will see we are using it in each of our generated maps.

This text is being used during by the test execution engine at runtime to search for the correct window that each of the controls reside in (top level ancestor). Imagine a developer changes the title of your window. Every UI map would be broken and must be regenerated to fix the problem. Rather than doing that we are going to create a new Class called TestRunUtility.
Go to solution explorer; right click the Utility Folder -> select Add -> select Class?

Type TestRunUtility.cs into the name field and click the Add Button

The following empty class is displayed:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyWebsiteCodedUITests.Utility
{
class TestRunUtility
{
}
}
Modify the code so it looks like the following:
using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
public class TestRunUtility
{
// Private fields for the properties
private HomePageMap homePage = null;
public TestRunUtility()
{
homePage = new HomePageMap();
}
// Properties that get each UI Map
public HomePageMap HomePage
{
get { return homePage; }
set { homePage = value; }
}
}
}
Now here comes the magic and what we are doing is boiler plate meaning we will repeat the following steps for our other 3 UI Maps AND any new map we add later.
Step 1) Add a using for the new UI Map to the top of the class:
using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
public class TestRunUtility
{
If you use default namespaces, here is how the using statement maps to the project (spaces are removed)

Next add a private field to access the new Map
using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
public class TestRunUtility
{
// Private fields for the properties
private HomePageMap homePage = null;
private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;
public TestRunUtility()
{
homePage = new HomePageMap();
}
Next we will build and expose a property that will allow us to access the FourthCoffeeFlyerDetailsPage. This property will use the same top level window as our home page.
using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
public class TestRunUtility
{
// Private fields for the properties
private HomePageMap homePage = null;
private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;
public TestRunUtility()
{
homePage = new HomePageMap();
}
// Properties that get each UI Map
public HomePageMap HomePage
{
get { return homePage; }
set { homePage = value; }
}
public FourthCoffeeFlyerDetailsPageMap FourthCopyFlyerDetailsPage
{
get
{
if (fourthCopyFlyerDetailsPage == null)
{
fourthCopyFlyerDetailsPage = new FourthCoffeeFlyerDetailsPageMap();
fourthCopyFlyerDetailsPage.UIHomeTailspinToysWindWindow.CopyFrom(
HomePage.UIBlankPageWindowsInteWindow);
}
return fourthCopyFlyerDetailsPage;
}
}
}
}
Here is the mapping between the property and the private field we declared a moment ago (Case is very important!):

Repeat this for the other 2 UI Maps and the resulting class should be as follows:
using MyWebsiteCodedUITests.UIMaps.HomePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.FourthCoffeeFlyerDetailsPageMapClasses;
using MyWebsiteCodedUITests.UIMaps.ModelAirplanePageMapClasses;
using MyWebsiteCodedUITests.UIMaps.ShoppingCartPageMapClasses;
namespace MyWebsiteCodedUITests.Utility
{
public class TestRunUtility
{
// Private fields for the properties
private HomePageMap homePage = null;
private FourthCoffeeFlyerDetailsPageMap fourthCopyFlyerDetailsPage = null;
private ModelAirplanePageMap modelAirplanePage = null;
private ShoppingCartPageMap shoppingCartPage = null;
public TestRunUtility()
{
homePage = new HomePageMap();
}
// Properties that get each UI Map
public HomePageMap HomePage
{
get { return homePage; }
set { homePage = value; }
}
public FourthCoffeeFlyerDetailsPageMap FourthCopyFlyerDetailsPage
{
get
{
if (fourthCopyFlyerDetailsPage == null)
{
fourthCopyFlyerDetailsPage = new FourthCoffeeFlyerDetailsPageMap();
fourthCopyFlyerDetailsPage.UIHomeTailspinToysWindWindow.CopyFrom(
HomePage.UIBlankPageWindowsInteWindow);
}
return fourthCopyFlyerDetailsPage;
}
}
public ModelAirplanePageMap ModelAirplanePage
{
get
{
if (modelAirplanePage == null)
{
modelAirplanePage = new ModelAirplanePageMap();
modelAirplanePage.UIHomeTailspinToysWindWindow.CopyFrom(
HomePage.UIBlankPageWindowsInteWindow);
}
return modelAirplanePage;
}
}
public ShoppingCartPageMap ShoppingCartPage
{
get
{
if (shoppingCartPage == null)
{
shoppingCartPage = new ShoppingCartPageMap();
shoppingCartPage.UIHomeTailspinToysWindWindow.CopyFrom(
HomePage.UIBlankPageWindowsInteWindow);
}
return shoppingCartPage;
}
}
}
}
What we have accomplished here is we set up a utility that told all of our UI Maps to use the same top level window as our Home Page. Now if a developer changes something, we only need to fix our home page. In My next post we will start assembling the coded UI test.