自动化启用插件 - 将无法访问的元素暴露给 UI 自动化框架






4.68/5 (7投票s)
一个可重用的插件框架,可将无法访问的元素暴露给 UI 自动化框架。对于 .NET 2.0 WinForm 容器控件来说是必备的。
引言
Microsoft UI Automation 是 Microsoft Windows 的新型辅助功能框架,可在所有支持 Windows Presentation Foundation (WPF) 的操作系统上使用。UI Automation 可以程序化方式访问桌面上的大多数用户界面 (UI) 元素。
除了演示此框架用于控制应用程序的用法外,本文还展示了如何创建一个插件,该插件可以配置为在代码更改最少的情况下跨所有控件重用。

背景
商业 Windows 应用程序中的用户界面元素使用自定义用户控件创建,原因如下:
- 在整个产品和产品套件中提供统一的外观和感觉
- 通过采用软件重用,加快应用程序开发速度
这些应用程序在发布到市场之前必须经过广泛的测试才能通过质量验收标准。除了手动测试之外,还采用自动化测试来在各种测试场景中运行应用程序。自动化测试的优点在于,它可以连续运行数天而不会中断,从而测试系统功能和稳定性——这是仅凭手动测试难以实现的。
问题
市场上的自动化测试框架(用于测试基于用户界面的应用程序)依赖于用于创建 UI 的 Windows 控件的可访问性。但是,如果用户界面是通过绘制的 UI 元素(而非窗口控件)创建的,则可能无法获得相同的默认可访问性。在这种情况下,自动化框架将无法默认访问这些元素。为了能够通过自动化测试框架访问这些元素,封装绘制的 UI 元素的父控件需要实现一些规定的接口(由 Microsoft .NET UI Automation
框架指定)。由于这种可访问性不是默认提供的,并且控件的作者必须专门提供实现,因此涉及大量的额外开销。结果是,要么可访问性未实现,要么花费精力来实现这种可访问性。前者意味着系统某些区域的可测试性受到损害。后者意味着开发人员必须额外计划学习和实现其 UI 元素的自动化启用器功能。
本文目标
本文面向软件开发人员和测试人员。
本文的目的是使控件开发人员能够以以下方式集成自动化可访问性:
- 快速,轻松(在工作量和时间方面)
- 能够以最少的技术问题进行集成
- 能够以最少的自动化框架知识进行集成
- 不对控件的设计和开发方式施加限制
- 可用于控件的重用
Using the Code
我们以 Microsoft .NET UI Automation(Microsoft Windows 的辅助功能框架)的运行时环境为例进行讨论。UI Automation 使屏幕阅读器等辅助技术产品能够向最终用户提供有关 UI 的信息,并通过标准输入以外的方式来操作 UI。UI Automation 还允许自动化测试脚本与 UI 交互,以实现应用程序的 UI 驱动测试。所有需要可访问的 UI 元素都必须实现特定的接口。在自动化测试期间,测试脚本运行的测试引擎将通过这些标准接口以编程方式访问这些接口。
本文提出设计一个自动化启用器插件库,该库的引用可以插入到需要启用自动化的目标控件中。拟议的自动化启用器插件库将代表 UI 元素实现规定的接口。自动化启用器插件库将在框架中提供单独的类,通过实现所需的 UI Automation 框架接口来提供对控件及其子 UI 元素的访问。
每个用户控件都有一个单独的 XML 配置文件,用于告知插件框架控件及其子 UI 元素根据其行为所需的接口。自动化启用器插件将仅将这些行为暴露给自动化测试框架。
插件库将使用控件及其子 UI 元素的 API 来暴露行为。由于每个控件中定义的 API 可能不同,因此 XML 配置文件还将包含控件及其子 UI 元素的 API 映射详细信息。此 API 映射详细信息将包含针对控件中可调用插件的 API 的条目。例如,如果控件/对象通过字段 'Bounds
' 定义了其 Size
,而插件通过字段 'BoundingRectangle
' 读取 Size
,则 XML 映射文件将别名这两个条目,以便插件框架在内部使用 'Bounds
' 字段来获取对象的 Size
。
在自动化测试过程中,一旦自动化启用器插件获取了用户控件的引用,它将读取相应的 XML 配置文件,并为该用户控件向自动化测试框架提供指定的行为。
下面显示了插件框架与用户控件和自动化测试框架交互的示意图
在本例中,我创建了一个自定义控件,其中包含一个 user control
和一些类 objects
作为其子 UI 元素。因此,用于构建用户控件的两个主要类是——MeasurementControl
和 MeasurementItem
。MeasurementControl
类派生自 UserControl
,并充当宿主/父级以在其内部显示 UI 元素。MeasurementItem
类用于表示每个 UI 元素。
在 Microsoft UI Automation Framework 中,AutomationElement
类表示 UI Automation 树中的 UI Automation 元素,并包含 UI Automation 客户端应用程序用作标识符的值。
当 MeasurementControl
类实例传递给插件框架时,插件会代表这些类实现 IRawElementProviderSimple
接口;该接口用于识别 AutomationElement
(通常只有控件被标识为 AutomationElement
)。MeasurementControl
派生自 UserControl
,因此会自动被识别为 AutomationElement
,但 MeasurementItem
实例默认无法被识别为 AutomationElement
。
由于 MeasurementControl
类充当根节点,而 MeasurementItem
类表示控件内的每个 UI 元素,因此插件内部为 MeasurementControl
类实现了 IRawElementProviderFragmentRoot
接口,为 MeasurementItem
类实现了 IRawElementProviderFragment
接口。如果我们的控件表现为容器控件(包含子 UI 元素),则需要这两个接口。这些接口使每个 MeasurementItem
也成为一个独立的 AutomationElement
,以便它在视觉上和程序上都显得清晰。
在插件框架中,ControlProvider
类负责公开 MeasurementControl
类,ObjectProvider
类负责公开 MeasurementItem
类。IValueProvider
和 IExpandCollapseProvider
是实现特定行为所需的 UI Automation 接口。这些接口根据 XML 配置文件实现在 ControlProvider
和 ObjectProvider
类上。下面是一个典型的 XML 配置文件
<?xml version="1.0" encoding="utf-8" ?>
<ApiMapping>
<Control>
<ClassName>MeasurementControl</ClassName>
<HelpTextProperty>This is MeasurementControl user control</HelpTextProperty>
<!-- API mapping.-->
<Name>Label</Name>
<BoundingRectangle>Bounds</BoundingRectangle>
<Items>Children</Items>
<!-- Automation Framework Interface related.-->
<IValueProvider available="false">
<IsReadOnly>true</IsReadOnly>
<SetValue>Label</SetValue>
<Value>Label</Value>
</IValueProvider>
</Control>
<Object>
<!-- Similar entries for UI element class will be here.-->
</Object>
</ApiMapping>
有关更多详细信息,请参阅附件中的源文件或 MSDN 上的 UI Automation 教程。
免责声明
目前此插件框架实现的功能非常有限。当前,它仅支持 IExpandCollapseProvider
和 IValueProvider
接口。我将逐步更新和增强其功能。
此作品已由 SIEMENS 代表我申请了专利,因此在使用此代码(部分/全部)用于您的产品之前,请仔细阅读其在线专利披露。
关注点
- 无需在用户控件类上实现任何接口。这还简化了开发人员的生活,可以轻松地为现有用户控件集成所需的功能。
- 由于将为每种类型的用户控件提供特定的 XML 配置,因此自动化启用器插件框架可以重用,以将系统中的所有类型的用户控件暴露给自动化测试框架。
- 由于只需要对用户控件类进行最少的代码更改,因此产品稳定性的风险也较小。更改仅在传递引用给自动化启用器插件时需要,并且这些更改仅在自动化测试期间调用,而不是在正常执行期间调用。
- 使用反射来访问用户控件类的 API。
历史
- 2010/12/28 - 更新了屏幕截图
- 2010/12/27 - 初始帖子