Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
UI Automation/White/CodedUI.
common problems & tricks
Summary: The page describes some of the problems in QA Automation that occur
when using UIAutomation (CodedUI, White) to automated desktop applications
and methods for their solution on the example of the project developed with
DevExpress library.
At the beginning was UI Automation
Using Automation UI
Using White framework.
Using Visual Studio 2010 Coded UI.
o Working with White
Some tricks to automate unsupported controls.
o UI Automation properties
o Using patterns, on SelectionPatternIdentifiers example
o DevExpress.Xpf.Core.ClearAutomationEventsHelper.IsEnabled
property
o When simple way ends
Use LegacyIAccessible
Using COM-wrapper
Use Win32 API
Call Invoke()
Use BoundingRectangle
Data caching
Summary: The page describes some of the problems in QA Automation that occur
when using UIAutomation (CodedUI, White) to automated desktop applications
and methods for their solution on the example of the project developed with
DevExpress library.
Using Automation UI
- free;
Drawback:
- the framework works well standard UI controls, but to support custom and
complex controls its necessary to make additional implementations;
Based on the UI Automation this framework has convenient access to the controls
and their properties. He has the same features as UI Automation. The framework
can be used to test the Win32, WPF, WinForm, SWT and Silverlight applications.
White framework allows you to write tests simpler and more readable.
You can use a ready BDDfy framework (read here), which allows to easily
implement BDD testing with White.
Profits:
- frequently recurring test steps can easily be re-used. Its up to you how fine-
grained you want to record your test steps. Calling a step (consisting of one or
more actions) is just a matter of a single function call;
- features fuzzy matching of UI elements. This seems to make the tests more
robust when updating the user interface;
- you can test many different kinds of user interfaces, not just the web.
Shortcomings:
- test steps are stored in an XML file (called UIMap) which in turn compiles to
C# code. The files is big and clunky and there currently is no editor or
documentation for it. So if you want to make some changes, things can get
complicated unless you want to re-record an entire test step.
- creating very simple assertions (such as look for the string foo on this web
page) is a bit clumsy and requires too many mouse clicks. An IE accelerator
would be great!
Based on the above choice was made in favor of the White framework, since it is
free and makes writing tests easier and makes them look intuitive.
It is easy to start working with the White for people who has not did. Even it does
not have such a good guide to use as MSDN, but for beginning White has enough
resources here http://teststack.azurewebsites.net/white/index.html.
To find the required control by AutomatedId property its enough to execute Get
method parameterized of control type, and as a function parameter to specify the
desired AutomatedId. For example, for Edit field with AutomatedId = "txtCity":
To find the controls in the application, as well as getting its properties are useful
Inspectors like as Inspect (download - Inspect.exe) supplied with MS win8 SDK,
or ACorns.Hawkeye (https://hawkeye.codeplex.com/). Moreover, Hawkeye shows
the actual type of the object, as well as an object implementation library.
It was noted that White is a wrapper of UI Automation, and thus it implements the
same basic controls. However, the application under test uses set of custom
controls implemented by e.g. DevExpress library. Some troubles in processing
such controls and their solutions were found out.
UI Automation properties
The first trouble is that White does not process custom DateEdit field. The
framework does not treat it neither like any DateTimePicker, nor Edit. As the
DataGrid contains MaskBox field, to get the control values you can get the value
of control through UI Automation properties:
return ((ValuePattern)valuePattern).Current.Value;
AutomationElement dateEdit
= element.FindFirst(TreeScope.Children, new
PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
dateEdit.SetFocus();
System.Windows.Forms.SendKeys.SendWait(dateString);
The next problem is the processing RadioGroup - getting the value of the selected
item. Applying White isSelected property for element RadioButton, always return
False value.
string selectedElement =
GetSelectedElementName( _element.AutomationElement);
return selectedElement.ToLower().Equals(_element.Name.ToLower());
return selectedElements[0].Current.Name;
DevExpress.Xpf.Core.ClearAutomationEventsHelper.IsEnabled = false
However, this may reduce the performance of the application (more info here).
White is not so quite good for processing Tables. Especially when tables using a
complex structure as a set of data in the collapsing combined group, nested tables,
any controls instead of text in cells.
After reading variety of websites and forums, solutions for the processing of
custom controls were found out.
To get cell values use UI Automation. To identify the type of line (collapsing
group element / data line) read the value LegacyIAccessible.State. To do this, you
should use IUIAutomationLegacyIAccessiblePattern, which provides the interface
ILegacyIAccessibleProvider. However, LegacyIAccessible pattern is not available
for control based on UI Automation, because it is not implemented neither UI
Automation nor White
if ((
bool) child.GetCurrentPropertyValue(AutomationElementIdentifiers.IsLegacyIAccessiblePatternAvailableProperty))
{ var pattern = ((LegacyIAccessiblePattern) child.GetCurrentPattern(LegacyIAccessiblePattern.Pattern));
var state = pattern.GetIAccessible().accState;
Using COM-wrapper
In addition, you can use Win32 API to send window messages and thus get
control properties or invoke events.
[System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint =
"SendMessage", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder
lParam);
private static extern IntPtr SendMessage(int hWnd, int Msg, int wparam, int lparam);
Furthermore you can call Invoke() method to get control properties. This method
implements InvokePattern, which provides support operation and invoking
unambiguous action of controls that do not maintain state by activation.
Use BoundingRectangle
Worst case to use BoundingRectangle property to get control layout. Then use
mouse clicks via SendInput expanding/collapsing/ the table.
Data caching
For processing controls which consist volume data (lists, tables, trees), as well as
getting properties and control patterns in one operation it is necessary to use data
caching. It allows improving performance and, in some cases, avoiding prolonged
searching or exceeding time-out interval through the frequent accessing to
elements. It may lead to test failures.