Abstract- In this paper we present a new technique to automate a windows application called the UI Automation Framework. The importance of software testing and its impact on quality of software cannot be under estimated. Automation is a good way to cut down time and cost. There are various tools available in market to accomplish the same, here we demonstrate how we can use the Automation Framework to automate a user interface and will explain why it is different from other approaches. Microsoft provides an accessibility framework for Microsoft Windows, Microsoft UI Automation. It is available on all operating systems; it comes with the .net framework 3.0.
Keywords- UI Automation, Testing, User Interaction, Windows Automation.
Introduction
Today testing plays a major role for any industry. An industry cannot afford a substantial defect in its product and loose its business. Now computerized system has taken over most of the operations in a business which was used to be done manually, so is testing. Hence the Automation Testing has come into scene. Automated testing is running test cases where manual intervention is not required to run each one. Unlike any automation process automation testing also has many benefits:
Reliable: Tests perform precisely the same operations each time they are run, thereby eliminating human error
Repeatable: We can test how the software reacts under repeated execution of the same operations.
Programmable: We can program sophisticated tests that bring out hidden information from the application.
Comprehensive: We can build a suite of tests that covers every feature in your application.
Reusable: We can reuse tests on different versions of an application, even if the user interfaces changes.
Better Quality Software: Because we can run more tests in less time with fewer resources
Fast: Automated Tools run tests significantly faster than human users.
Cost Reduction: As the number of resources for regression test are reduced.
There are many approaches to automate a user application, like System.Reflection class available with .net framework or Win32 API calls or we can even find many tools available to automate a windows application. In this paper we will explain how this can be accomplished using a new framework called UI Automation.
UI Automation Framework
Microsoft UI Automation is the new Accessibility framework for Microsoft Windows, available on all Operating Systems that support the Windows Presentation Foundation (WPF). UI Automation provides programmatic access to most user interface (UI) elements on the desktop. [3]
The UI automation framework is relatively new to Windows platform and successor to Windows Active Accessibility. The framework provides a unified way to discover UI controls in an application built using any of the following desktop technologies: Win32, Windows Forms or WPF. It provides access to the hierarchy of user interface elements which are visible in Windows applications. Imagine the root element of the hierarchy as being the desktop, and all the running applications are the first level nodes (children) of the root, and the same for each visible form which can be detailed to its controls, the controls to its children, and so on. Each node in this tree is called UI element.
The UI Automation library architecture uses a client-server point of view and naming conventions. From a UI test automation standpoint this means that the application under test is called the server and the test harness is considered the client-the test harness client requests UI information from the application under tests (the server). [3]
The framework helps us by giving access to these UI elements and their properties. The main features supported by this framework are:
Search support that lets us find the required user interface component.
Filtering the tree structure of elements. For example when querying the hierarchy of elements, we can get only the enabled controls.
Lets us interact with UI elements. For example, you may programmatically click a button (which is contained in a different application), from your application.
Subscribing to events. This helps us to monitor UI elements and handle external events.
Implementation
UI Automation exposes every piece of the UI to client applications as an AutomationElement object. AutomationElement objects expose common properties of the UI elements they represent. There are several properties exposed which can be used by client to get access to desired UI element.
AutomationID: Uniquely identifies an automation element from its siblings.
ControlType: Identifies the type of control represented by an automation element. Example: a window, a button etc.
NameProperty: This is a text string that identifies or explains a control. Name of a UI element.
In addition, elements expose control patterns that provide properties specific to their control types. Control patterns also expose methods that enable clients to get further information about the element and to provide input. [1] Control patterns support the methods, properties, events, and relationships needed to define a discrete piece of functionality available in a control.
Few available patterns:
InvokePattern: Used for controls that can be invoked, such as a button.
ScrollPattern: Used for controls that can scroll. For example, a control that has scroll bars that are active when there is more information than can be displayed in the viewable area of the control.
ValuePattern: Allows clients to get or set a value on controls, such as a Textbox.
As told all UI elements are structured as tree, we can get a root element (which is a desktop) and parse through the tree to get an element or we can directly get a specific element by calling the library methods. We can use the FindFirst() method to search for a specific AutomationElement which matches the criteria passed. In order to call this method, we need to pass the scope of search (instance of TreeScope enum), for example to search through the first level of children, or to search through all descendants. Besides scope parameter, we have to pass the condition that should be met in order to identify the required AutomationElement. We will pass the condition as an instance of a class that extends Condition abstract class. In this way, we can use PropertyCondition (for testing a property to have a specific value), but also available are: AndCondition, NotCondition or OrCondition classes, which are set of conditions which are to be evaluated.
public AutomationElement FindFirst(TreeScope scope, Condition condition)
Similar to FindFirst(), FindAll() lets us query the UI Automation tree using the parameters described above, but return a collection of AutomationElements that have passed the search condition.
The steps or the process to be followed in order to automate a test application is as follows [3][5]:
Add reference to UI automation dlls (UIAutomationClient.dll, UIAutomationTypes.dll).
Get reference to the main UI element (which is a root element).
Get references to desired user controls.
Automate the UI, this can be done by getting the control patterns for the controls and manipulate the methods exposed by it.
Check the state of the application and decide pass or fail
In the following we will use a windows application which is calculator available with any Windows OS to demonstrate the use of UI Automation Framework (it is assumed that the calculator application is already launched). Below is the code snippet to get a reference to Automation Element for Calculator application.
AutomationElement aeDesktop = AutomationElement.RootElement;
int numWaits = 0;
AutomationElement aeWindow = null;
do
{
aeWindow = aeDesktop.FindFirst(TreeScope.Children,
new PropertyCondition
(AutomationElement.NameProperty,
"Calculator"));
++numWaits;
Thread.Sleep(100);
}
while (aeWindow == null && numWaits < 50);
if (aeWindow == null)
{
throw new Exception("Failed to find Calculator.");
}
else
{
Console.WriteLine("Found the Calculator Window");
}
In the first line we are getting an object of the root element. AutomationElement contains a property called RootElement, which contains a reference to the corresponding UI element of the desktop, which in fact returns an AutomationElement.
The first line in the do-while loop is to get a reference to the calculator window. We are using the FindFirst() function, the first argument is the scope of the search; which instructs to find only in the immediate children of root element. The second argument to FindFirst() is a condition; we can interpret by seeing the code that the condition is, the name property of the user control should be "Calculator". We can as well use AutomationID or ControlType properties in the condition.
What we are doing in the do-while loop is, we are waiting some time in small increments to allow the user controls to load fully. We put an attempt to get the reference inside a loop with a slight delay (100 milliseconds in this case). We track the number of times my harness enters the waiting loop, and we exit if we get a non-null reference (meaning we found the element) or if it exceed a maximum number of attempts (50 in this case).
Next step is to get the control pattern for the AutomationElement object and use the methods exposed the pattern to manipulate the element, following is the code snippet:
AutomationElement aeButton = aeWindow.FindFirst(
TreeScope.Children,new PropertyCondition(
AutomationElement.AutomationIdProperty,
"131"));
InvokePattern ipClickButton1 = (InvokePattern)
aeButton.GetCurrentPattern(
InvokePattern.Pattern);
ipClickButton1.Invoke();
Instead of using NameProperty we use AutomationIdProperty; we can interpret from the code that it tells to find element whose AutomationID is '131'. '131' is the AutomationID for the button '1' in the calculator application. Once we get a reference to button we get an InvokePattern pattern available for a button. Then we are calling the Invoke() method available with InvokePattern pattern, which simulates the click on the button.
Finally we check for the application state and tell if test case passed or failed. The verification point here is, once the button '1' is clicked the TextBox in calculator application should display '1'. To do this we get the TextBox object reference and get the ValuePattern pattern, which gives the text contents of the TextBox.
AutomationElement aeTextBox = aeWindow.FindFirst(
TreeScope.Children,new PropertyCondition(
AutomationElement.ControlTypeProperty,
ControlType.Edit));
We are using the ControlType property in the condition to refer the TextBox. As only one TextBox is available we get the TextBox reference. If more Textboxes are present, we should use other properties or FindAll() method, which gives a collection of all the elements of the type Edit.
string result =
(string)aeTextBox.GetCurrentPropertyValue(
ValuePattern.ValueProperty);
if (result == "1")
{
Console.WriteLine("\nTest Case: Pass");
}
else
{
Console.WriteLine("\nTest Case: *FAIL*");
}
After getting the reference to the TextBox we get the TextBox contents and verify with expected values and tell if test case passed or failed. And finally we close the application using the WindowPattern as shown below.
Console.WriteLine("\nClosing the Calculator
application.");
WindowPattern wpCloseWin = (WindowPattern)
aeWindow.GetCurrentPattern
(WindowPattern.Pattern);
wpCloseWin.Close();
The UI Automation framework even supplies events related to the control patterns, like the InvokedEvent or the WindowOpenedEvent, as well as more general events such as focus or property changes. In automation we can use this feature in many ways, like wait for completion of some action wait for a processing window to close. We are not explaining much about the events here.
In the search condition we specify an UI element property, like the name property or automation id property or control type property. We can get the properties of user controls using varies tools available, like UISpy, UIA Verify… which enables developers and testers to view and interact with the user interface (UI) elements of an application. We can view the application's UI hierarchical structure, property values, and raised events. We can quickly find and select any UI element anywhere on the desktop and get the properties and patterns available with it. Below is the screenshot (Fig. 1) which shows how UI elements properties and available patterns are displayed. The tool used id UIA Verify.
Fig. 1 Screenshot showing the UI Elements properties
Advantages and Limitations
UI Automation framework is a pure object oriented programming model. We can use the managed code to program the automation scripts, which provides a rich advantages like error checking, type safety… over the previously used libraries. The controls types exposed by the framework is much similar to the windows form controls, hence the windows application developers can easily recognize and automate the user controls. The control patterns match how a user interacts with and views the system. The properties of automation elements and control patterns support how a user thinks of an application; they are not meant to expose every property that can be set by a developer. Compared to the commercial automation framework the UI Automation Framework is much cheaper as it is available with the .net framework 3.0. Here we have to learn only one set of API instead of many custom libraries.
However, the other commercial test automation software available in the market have few advantages over the UI Automation framework in that they are often tightly integrated with tools such as test case managers and bug-reporting software tools. These tools usually come with an IDE and record and play functionality, which offers less time spent in understanding, coding and managing the test suite. Lightweight custom UI test automation libraries have an advantage in that they are generally easier to use for quick-and-dirty test automation[2].
CONCLUSION
In this paper, we have shown how we can use the UI Automation Framework to automate a windows application. There are lot things that can be extended from the idea presented in the paper; like we can have a structured data input for execution of test cases, there can be structured logging of test results and many more which contributes to a test automation suite. It can be used in the development of automated UI testing/debugging application and so on. This can be the most successfully used automation framework, as it is a single, standard, comprehensive, consistent, and well-tested UI automation library that is freely available to software engineers.