WindowsAutomation Reference 2.0
This is the documentation for the Windows Automation 2.0 plugin.
It provides facilities to automate tests incorporating applications with a GUI based on Windows Presentation Foundation (WPF), WinForms, and the old Win32 API.
Inhaltsverzeichnis
Features[Bearbeiten]
- Automated GUI testing of WPF, WinForms, and Win32 applications.
- Contains an expecco block library and tools which help to model tests and inspect the GUI of the application.
- Parallel remote test-execution on multiple systems.
- Performs tests against already built executables. No source code changes / recompilation of the application is required.
- Access to GUI components using XPath locators.
- Access objects of the application live at execution time.
- Full access to keyboard and mouse of the target system.
- Lots of additional features such as screen capturing, taking screenshots, highlighting GUI elements, mouse tracking, ...
Installation and Connection[Bearbeiten]
The WindowsAutomation testing plugin uses the expecoo ".NET-Bridge" which consists of two parts: A plugin for expecco, and a server executable using the .NET framework running on the remote computer to connect to.
Requirements[Bearbeiten]
On the machine running the system under test:
- .NET Framework 4.6.2 [1] or higher.
- One of the following operation systems:
- - Windows 7 SP1
- - Windows 8
- - Windows 8.1
- - Windows 10
- - Windows Server 2008 R2 SP1
- - Windows Server 2012
- - Windows Server 2012 R2
- - Windows Server 2016
- - Windows Server, version 1709
Plugin Components[Bearbeiten]
The plugin consists of the following parts:
- The GUI Browser, used to interactively explore your application.
- The Windows Automation Library, which provides blocks that you can use in your test cases.
- The .NET-Bridge server, which provides an interface between the application under test and your tests running in expecco.
Installing and Configuring the Plugin in Expecco[Bearbeiten]
The plugin is usually installed automatically by the installer; either included in the main expecco installation or provided as a separate installable add-on package. Its files are stored in the "plugin" subfolder of the expecco installation folder. You can also copy those files manually to that folder, if required. Expecco detects the plugin automatically during startup. You might need to restart your expecco session.
Preparing a local system for test execution[Bearbeiten]
If you want to automate an application running on the same host as expecco, there is no need to set up anything! Everything should work out of the box.
TODO: Is that still true with the gui browser? TODO: Pictures for the connection process
Preparing a remote system for test exeuction[Bearbeiten]
The remote system will have to run the ".Net-Bridge server" which in turn connects to expecco. You just need to copy "DotNetBridgeServer.exe" to the computer your system under test is running on. No further installation is needed.
To start the bridge, navigate to the executable in a shell and start it with the following arguments:
Arguments | Required | Description |
---|---|---|
-s | Yes | Tells the executable to run in server mode (as opposed to client mode). |
-k | Yes | Tells the client to keep the connection open after aconnection has been terminated saving you the hassle to restart it every time a test finishes. |
-a <ip/hostname> | Yes | The IP-Address of the PC your application is running on. |
-p <int> | No | The port the server should listen on (default is 34318). |
Settings[Bearbeiten]
TODO: What settings does the plugin have?
GUI Browser[Bearbeiten]
The GUI browser allows you to explore a running application. You can browse the application, inspect element properties and execute actions. For a more detailed description on how to use and what to do with the GUI browser also see Expecco GUI Tests Extension Reference.
Library[Bearbeiten]
This article gives a short overview over the design philosophy of the library. You can find more detailed documentation and examples attached to the blocks itself.
Connecting to an Application[Bearbeiten]
To automate an application, you first have to connect to it. You can do this with the blocks from the Connecting group.
You can connect to an application by its executable name, or by its process id. If you use the executable name, expecco will attach to the main process of the specified executable. Be careful as this is not necessarily the process drawing the GUI! Use the process id if an application spawns more than one process and you need to make sure you connect to the GUI process and not some background process. All connection blocks also require you to specify a name by which the connection should be known in future. This is needed for when you automate multiple applications at the same time and need to change connection contexts during test execution. Please note that the application to connect to has to be started before the corresponding connection block is executed. You can change in context of which connection a block is executed with the Set Active Connection block. This allows you, for example, to automate and compare the state of applications running on multiple systems in one test case.
Establishing a Local Connection[Bearbeiten]
If you want to automate an application running on the same host as expecco, there is no need to set up anything! Just use the Create Local Connection with the mentioned above parameters.
Establishing a Remote Connection[Bearbeiten]
Make sure that the DotNet Bridge server is started as explained in #Preparing a remote system for test exeuction When the bridge is running, you can connect to it with the Create Remote Connection block using the hostname and IP-Address you specified when you started the bridge.
Closing a Connection[Bearbeiten]
Remember to always close a connection when it is no longer needed, as it otherwise needlessly consumes resources. One simple way to do this is to setup your connections in the Before Execution part of the test suite and put the Close All Connections block in the After exeuction part.
Accessing Gui Elements[Bearbeiten]
All Windows applications are built as a tree of GUI elements . Some elements act as container of other element - their children. Tables, for example, are containers for their cell elements which themselves might contain text labels. At the root of the tree are one or more windows . When you connect to an application, you get access to all windows at the tree's root. To manipulate any of the system under test's GUI element, you first have to gain access to it. The group GUI Element Access provides blocks that help you to gain access to the elements. There are 12 blocks in total, divided between Access By XPath , Access By Property, and Existence Test. For each category, blocks with the same interface exist. The only difference is the method of retrival.
- Get GUI Element
- returns a single GUI Element matching the search condition. If multiple match the condition, an arbitrary element matching the condition is returned.
- If you want to make sure that there is only one element matching, set ensureExclusive to true. You can also enforce this globally by setting the environment variable ensureExclusive in your environment.
- If ensureExclusive is set and more than one element is found, the block will fail and notify you of the ambiguity. This is disabled by default as checking for uniqueness is a very costly operation.
- You can also specify a timeout after which the search is aborted. This is useful if you know an element should be there soon but might currently be loading.
- Get GUI Elements
- returns all GUI Element matching the search condition. Timeout and cacheXPath are also applicable.
Both of these blocks are also available in the Relative To Anchor
Constructing XPaths
XPath is the query language this plugin uses for selecting GUI elements in the application's element tree.
You can find the XPath of an element with the expecco GUI browser or with separate applications like UISpy or FlaUInspect.
An XPath for the scroll button on the
vertical scrollbar in the german Windows Notepad application looks like this:
/Window[@Name='Unbenannt - Editor']/Document[@Name='Text-Editor']/ScrollBar[@Name='Vertikale Bildlaufleiste']/Button[@Name='Bildlauf nach unten']
For each level in the GUI tree, a new Location Step containing the child elements Control Type has to be added.
You do not have to use any predicates, the following XPath is valid as well:
/Window/Document/ScrollBar/Button
but might lead to issues as there might be multiple GUI Elements matching this path.
You can select by three predicates that can be mixed and matched in the same query:
-
Name: the name the application developer has given an element. Be careful as this name might change
during programm execution (See for example Notepad's window name which always begins with the name of the currently opened file.
/Window[@Name='Unbenannt - Editor']
-
AutomationId: An ID the application developer has given an element. It is meant to be unique between siblings but that is not enforced.
Many developers infact leave the ID empty or reuse it, making it useless. You should nontheless use this ID wherever applicable as it is static
and meant for this exact purpose.
/Window/Document[@AutomationId='15']
-
List Index: If there are multiple siblings with the same Control Type, you can select one of them by (1-based) list index.
/Window[1]/Document[1]
/Window[1]/Document[last()]
XPath also supports wildcards. You can:
-
replace one tree level with a "*" wildcard:
/Window/Document[@AutomationId='15']/*/Button[1]
/*/*/*/Button[1]
-
replace a control type with a "*" wildcard:
/Window/*[@AutomationId='15']
-
replace an arbitrary amount of tree levels with a "//" wildcard:
//Button
/Window//Button[1]
Especially the last option is useful as it makes your tests more readable as the reader can easily focus on the relevant parts of the xpath.
But be careful. Using wildcards comes at a steep performance cost. If your tests run unacceptably slow, first try to remove wildcards where they are not needed.
Accessing by Property
XPath resultion in action blocks
</section> <section>
Manipulating Gui Elements
</section> <section>
Checking the State of Gui Elements
</section>
</html>