Microsoft UI 自动化库

发表于:2008-10-08 15:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Dr. James McCaffrey    来源:MSDN

  在大多数情况下,获得对所测试应用程序的窗体对象(作为 AutomationElement)引用的更好方法是使用类似Figure 5 中所示的代码。我就如何以很小的延迟(在本例中为 100 毫秒)在循环内部获得引用进行了尝试,在盲目请求对应用程序的引用之前无需任意时间的暂停。我跟踪我的工具进入等待循环的次数,在获得非空引用(意味着我找到了窗体对象)时,或在超过最大尝试次数(在本例中为 50)时退出。

  Figure 5 获取测试应用程序 AutomationElement

  // a better approach
  AutomationElement aeForm = null;
  int numWaits = 0;
  do
  {
  Console.WriteLine("Looking for StatCalc . . . ");
  aeForm = aeDesktop.FindFirst(TreeScope.Children,
  new PropertyCondition(
  AutomationElement.NameProperty,
  "StatCalc"));
 
  ++numWaits;
  Thread.Sleep(100);
  }

  while (aeForm == null && numWaits < 50);

  if (aeForm == null)
  throw new Exception("Failed to find StatCalc");
  else
  Console.WriteLine("Found it!");

  此外,我使用 FindFirst 方法,而不使用 FromHandle,前者能够继续搜索对 AutomationElement 的第一个可用的引用,AutomationElement 满足作为一对参数传入的特定条件。我的第一个参数 TreeScope.Children 指示 FindFirst 仅查看其上下文(在本例中为 aeDesktop)的直接子控件,而不需查看其上下文的所有后代。

  FindFirst 的第二个参数是一个条件:

  new PropertyCondition(AutomationElement.NameProperty, "StatCalc")

  可以将此代码的含义解释如下:“标题(Name 属性)的自动化元素等于 StatCalc。”不需要在条件中使用传统的字符串方法来确定控件(例如,Property == StatCalc),UI 自动化库的设计人员决定创建 PropertyCondition 类。这一方法乍看可能有些难以理解且冗繁,但是您很快就能熟悉它。

  基本上,使用完全面向对象的 PropertyCondition 类(而不使用简单的字符串)来确定控件在编写测试自动化时需要更多代码,但是它也有多个优点。PropertyCondition 往往使测试自动化代码的意图非常明确(至少在您熟悉此模式后是这样的)。因为 PropertyCondition 对象较之字符串是更强类型化的,所以使用 PropertyCondition 允许集成的开发环境(如 Visual Studio)提供设计时 IntelliSense® 自动完成帮助。它还使编译器能够执行更完善的错误检查。

  获得对所测试应用程序的主窗体对象的引用后,我获取了对所有用户控件的引用。例如,在需要获得对“Calculate”(计算)按钮控件的引用时,我可以编写如下代码:

  Console.WriteLine("Finding all user controls");
  AutomationElement aeButton = aeForm.FindFirst(TreeScope.Children,
  new PropertyCondition(AutomationElement.NameProperty, "Calculate"));

  获得用户控件的模式与获得窗体控件的模式是完全相同的。这种一致性是 UI 自动化库较之许多其他自动化库的一个优点。对于本例中这样使用大量编码类型、使用 UI 自动化的情况,通常可以使用几种不同的方法来完成任务。例如,若不使用上述代码获得对“Calculate”(计算)按钮控件的引用,我还可以编写如下代码:

  AutomationElement aeButton = aeForm.FindFirst(TreeScope.Children,
  new PropertyCondition(AutomationElement.ControlTypeProperty,
  ControlType.Button));

  我可以不使用 NameProperty,而使用 ControlTypeProperty 及 ControlType.Button 的值。可以将此代码的含义解释为:“提取在窗体上找到的第一个按钮控件。”此方法仅在此处适用,因为我的窗体对象上只有一个按钮控件。

  ControlType 类是一种重要的 Microsoft UI 自动化思路。此类非常简单,可用于确定任何控件的类型。获得对我的既没有标题也没有名称的文本框控件的引用,需要不同的技术:

  AutomationElementCollection aeAllTextBoxes =
  aeForm.FindAll(TreeScope.Children,
  new PropertyCondition(AutomationElement.ControlTypeProperty,
  ControlType.Edit));

  AutomationElement aeTextBox1 = aeAllTextBoxes[1];
  AutomationElement aeTextBox2 = aeAllTextBoxes[0];

  这里,我使用 FindAll 方法来检索所有作为我的窗体控件的直接子项的文本框控件。注意,您可能已经猜到,我使用 ControlType.Edit 来指定文本框控件,而不是类似于 ControlType.TextBox 的控件。我将我的所有文本框控件存储在 AutomationElementCollection 中,然后可以按索引访问这些控件。

  请回忆一下先前介绍的内容:textBox2 控件具有低于 textBox1 控件的隐含的索引,因此 textBox2 位于集合中的位置 [0],而 textBox1 位于集合中的位置 [1]。还可以使用其他几种方法来获得对没有标题的控件的引用,但是 FindAll 方法往往是不错的选择。

  以下是我获取对 radioButton1 控件的引用的方法:

  AutomationElement aeRadioButton1 =
  aeForm.FindFirst(TreeScope.Descendants,
  new PropertyCondition(AutomationElement.NameProperty,
  "Arithmetic Mean"));

  请注意,因为我当前的上下文是窗体对象,所以我使用 TreeScope.Descendants,而不使用 TreeScope.Children。radioButton 控件是 groupBox1 控件的子项,后者又是 Form1 控件的子项,因此 radioButton 控件是 Form1 的后代,但不是它的子项。或者,我可以首先获得对 groupBox1 控件(为 Form1 的子项)的引用,然后再获得对 radioButton1(为 groupBox1 控件的子项)的引用。

  在采用上述获得对 radioButton1 的引用的方法获得对 radioButton2(几何平均数)和 radioButton3(调和平均数)的引用后,我可以开始执行所测试的应用程序。

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号