Coded UI Test – how to start?

July 19, 2016 Filip Kudroń

Coded UI is a UI Test Automation framework based on Microsoft UI Automation library. It provides tools for easy recording and creation of automated UI tests for web, desktop and mobile apps.

Coded UI Test is supplied with Microsoft Visual Studio Enterprise.

What can I test with CUIT?

Coded UI Test is a very versatile tool because it supports so many different technologies. I have selected it for one particular reason, which is the fact that it supports XAML-based applications for Windows Store, Windows Phone, and Universal Windows App. A complete list of supported and unsupported configurations and platforms for Coded UI Test can be viewed here.

UI Maps and Test recording

Coded UI Test offers tools for recording actions and creating UI maps. Recording is not supported for XAML-based apps.

Writing Coded UI test scripts

The approach I prefer most is to write the so called hand-coded Coded UI Tests; here, I would like to cover the basics of this approach.

The Microsoft Store version of the Calculator app, which we can assume is widely available on Windows 8.1 and higher, will be used as an example.

Launching the app

First, create a Coded UI Test project.

Launching the app - Coded UI Test

Select Coded UI Test Project and then press the OK button.

After Visual Studio is done with preparing the project, you will be prompted “How do you want to create your coded UI test?”. Select Manually edit the test and click OK.

Now, you have a clean Coded UI test project. There is just one CodedUITest1.cs file: open it if it is not open.

To start an application with Coded UI use Launch() method. The way this method is called varies between mobile, desktop and web platfroms.

In our case with an XAML-based app, we need to call static method Launch() on XamlWindow class.

1
XamlWindow.Launch(string uiTileId);

This method returns the locator of the XamlWindow control, which is the main container of our app. As an argument it takes the tileAutomationId string, which allows the method to find the app tile and launch it.

To get this ID, we need to launch Coded UI Test Builder, which is done by moving the cursor to test method and right-clicking to open the context menu, Select Generate code for Coded UI Test -> Use Coded UI builder from the menu. After Test Builder is opened, the Metro UI will be displayed (in the case of Windows 8.1).

Now, select all apps and, using search, find Calculator in the Metro UI.

Click the crosshair tool in Coded UI Test Builder.

Crosshair tool - Coded UI Test Builder

Drag it onto the calculator tile and hold until Test Builder locates it (a blue border will appear).

Dragging onto the calculator tile

Then, the control inspector will be displayed with all the properties of the selected control, and what interests us now is the AutomationId property. Right-click on it, select Copy value… and paste it as an argument to the Launch() method as shown below:

1
XamlWindow appWindow = XamlWindow.Launch("Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");

So, this method launches our app and stores the locator of the app window (XamlWindow) control in the appWindow variable. We need this locator because any other control we define will need its parent control for search.

Locating controls

Now, when the Calculator app is open and, in the same way, we have located the Calculator app tile, it is necessary to locate the buttons in the app, e.g. 9, +, and = buttons and save their automation IDs.

Automation IDs can be added in XAML and are the best way to locate controls in the UI, however they are not the only option. Any property listed in the Search section in the control inspector can be used for a search.

To enable Coded UI to find the control during a test, we need to define the control object in the test, as shown below:

1
XamlButton button9 = new XamlButton(appWindow);

appWindow is passed as an argument in the constructor for XamlButton because it is the parent control for the button. If the button was nested in some other control (e.g., a list), we would then need to first find the list control in the same way as we have found the button, and then pass the list control object to the constructor of the button control. If you don’t point the parent of the control, in most cases, Coded UI will not be able to locate it.

When we have a button control which knows who its parent is, we need to tell Coded UI which button we want to find – there are around 24 different buttons and we want a specific one. That’s what Automation ID is used for (or any other search properties). These properties must be added to the button control as shown below:

1
2
XamlButton button9 = new XamlButton(appWindow);
button9.SearchProperties.Add("AutomationId", "num9Button");

The button control is now ready for interaction. More than one search property can be added.
Now, let’s create such locators for + and = buttons.

1
2
3
4
5
6
7
8
9
10
XamlWindow appWindow = XamlWindow.Launch("Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");
 
XamlButton button9 = new XamlButton(appWindow);
button9.SearchProperties.Add("AutomationId", "num9Button");
 
XamlButton buttonPlus = new XamlButton(appWindow);
buttonPlus.SearchProperties.Add("AutomationId", "plusButton");
 
XamlButton buttonEquals = new XamlButton(appWindow);
buttonEquals.SearchProperties.Add("AutomationId", "equalButton");

Interacting with controls

First, I would like to share some information about the XamlButton and XamlWindow classes, but especially about the Xaml part of their names. As I said before, Coded UI can be used with many different types of apps such as WinForms, WPF, web apps and so on. The test code for each type of control will be the same: 99.9% of the time the only difference in code would be using HtmlControl or WinControl instead of XamlControl and a different Launch() method. Thanks to this, you can write tests for many different applications using and knowing only one tool.

Getting back to interacting with controls, there are three main input classes: Mouse, Keyboard and Gesture, and they provide us with methods to simulate anything a user could do with our app.

Mouse and Keyboard are self-explanatory; most of the time you will be using Mouse.Click(UIControl) or Mouse.DoubleClick(UIControl) and Keyboard.SendKeys(UIControl, string). In Visual Studio, when you type Keyboard. or Mouse., a list with all available methods will be provided and I doubt you will have any trouble finding the one you need.

Gestures are sometimes more complicated but are thoroughly explained here.

So, we have controls which Coded UI can find, we know methods to interact with them, and finally we can write a test script.

My test will perform the operation of 9+9.

We already have the launching method, we have defined the controls we are going to use and added search properties to them. All we need to do now is to perform a few clicks. So we write:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[TestMethod]
      public void addTwoNumbersAndVerifyResult()
        {
            XamlWindow appWindow = XamlWindow.Launch("Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");
 
            XamlButton button9 = new XamlButton(appWindow);
            button9.SearchProperties.Add("AutomationId", "num9Button");
 
            XamlButton buttonPlus = new XamlButton(appWindow);
            buttonPlus.SearchProperties.Add("AutomationId", "plusButton");
 
            XamlButton buttonEquals = new XamlButton(appWindow);
            buttonEquals.SearchProperties.Add("AutomationId", "equalButton");
 
            Mouse.Click(button9);
            Mouse.Click(buttonPlus);
            Mouse.Click(button9);
            Mouse.Click(buttonEquals);
}

Then, select Build solution in the Build menu. After the build process is finished, Test Explorer should be displayed, listing CodedUITestMethod1.

Coded UI Test Method 1

Right-click the test method, select Run selected tests

Run selected tests

and watch the magic happen. After all the actions have been performed, the app closes and the test is marked as passed. But it’s not a test yet, because a test needs to test something. I’d like my test to check if the output after adding 9+9 is actually 18. To do so, I need to locate the output control. As with the button:

CalculatorResults

In the inspector, we can see it’s a Text control and its automation ID is CalculatorResults, so in our test, we create an XamlText control with search property.

1
2
XamlText resultText = new XamlText(appWindow);
resultText.SearchProperties.Add("AutomationId", "CalculatorResults");

Now, Coded UI can find this control. To find out whether the value displayed in the result control is 18, we need to get its displayed value. In the inspector, we can see that the result control has the DisplayText property.

Add Assertions

To get this property value in our test, we need to use UITestControl GetPropert(string propertyName) method. This method doesn’t return a string so we need to use the ToString() method:

1
string resultString = resultText.GetProperty("DisplayText").ToString();

But, as we could see in the inspector, the value of DisplayText property isn’t just 18. For some reason, there’s something like Display content is … and the value we want.

We need to get the string with only the number. Usually, I would think about what values can be displayed and write a proper converter (or, in the first place, ask why there is this redundant text in the control and make the developers remove it, unless it serves any purpose). In this example, I’ll use the fact that the text I want to remove is always the same. It can be easily removed with:

1
2
string resultString = resultText.GetProperty("DisplayText").ToString();
resultString = resultString.Replace("Wyświetlana zawartość to ", "");

and in the case of any leading or trailing whitespaces left in the string:

1
2
3
string resultString = resultText.GetProperty("DisplayText").ToString();
resultString = resultString.Replace("Wyświetlana zawartość to ", "");
resultString = resultString.Trim();

After the above steps, I have a clean string with the value I initially wanted. The solution I used here is sufficient for this case, but in other cases a more elegant solution might be needed.

Now I need Coded UI to test whether the condition is met. I do that with the Assert method.

1
2
decimal expectedResult = 18;
Assert.IsTrue(Convert.ToDecimal(resultString) == expectedResult);

The whole test is given below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[TestMethod]
        public void addTwoNumbersAndVerifyResult()
        {
            XamlWindow appWindow = XamlWindow.Launch("Microsoft.WindowsCalculator_8wekyb3d8bbwe!App");
 
            XamlButton button9 = new XamlButton(appWindow);
            button9.SearchProperties.Add("AutomationId", "num9Button");
 
            XamlButton buttonPlus = new XamlButton(appWindow);
            buttonPlus.SearchProperties.Add("AutomationId", "plusButton");
 
            XamlButton buttonEquals = new XamlButton(appWindow);
            buttonEquals.SearchProperties.Add("AutomationId", "equalButton");
 
            Mouse.Click(button9);
            Mouse.Click(buttonPlus);
            Mouse.Click(button9);
            Mouse.Click(buttonEquals);
 
            XamlText resultText = new XamlText(appWindow);
            resultText.SearchProperties.Add("AutomationId", "CalculatorResults");
 
            string resultString = resultText.GetProperty("DisplayText").ToString();
            resultString = resultString.Replace("Wyświetlana zawartość to ", "");
            resultString = resultString.Trim();
 
            decimal expectedResult = 18;
 
            Assert.IsTrue(Convert.ToDecimal(resultString) == expectedResult);
        }

Now, just build it, run it and watch the magic happen.

Last posts