发布新日志

  • Microsoft UI 自动化库

    2008-10-07 18:14:15

    以使用多种技术测试 Windows® 应用程序的用户界面。例如,可以使用 System.Reflection 类来测试 Microsoft® .NET Framework 应用程序,也可以使用非托管 C++C# 或者 Visual Basic® 通过 P/Invoke 机制调用 Win32® API 函数(例如 FindWindow)来测试 .NET 和本机应用程序。

    在 本月的专栏中,我将为您介绍如何使用新的 Microsoft UI 自动化库(包含在 .NET Framework 3.0 中,是 Windows Presentation Foundation (WPF) 的一部分)开始进行 UI 测试自动化。您可以将其看作是 Microsoft Active Accessibility (MSAA) 库的后继产品,后者最初设计用于可访问性功能,但同时发现它对 UI 自动化很有用也很适合。另一方面,UI 自动化库从一开始就是为可访问性和 UI 测试自动化任务而专门设计的。您可以使用 UI 自动化库来测试运行支持 .NET Framework 3.0 的操作系统(例如 Windows XPWindows Vista®Windows Server® 2003 Windows Server 2008)的主机上的 Win32 应用程序、.NET Windows 窗体应用程序和 WPF 应用程序。

    言 归正传,我认为 UI 自动化库的开发是迄今为止测试自动化领域中最重大的一项进步,并将迅速成为 Windows 应用程序 UI 测试自动化方面最常用的技术。与其他用于 UI 自动化的可选方法相比,UI 自动化库功能更强大、往往更易于使用并且更加一致。就像 .NET Framework 改变了软件应用程序开发一样,我认为 UI 自动化库极有可能会彻底改变 UI 测试自动化。

    向您阐述我的观点的一个好方法是通过屏幕快照。 1 显示的是我将要测试的一个简单的 Windows 应用程序。该应用程序被称为 StatCalc,它可以计算一组整数的算术平均数、几何平均数或调和平均数。算术平均数只是简单的平均。例如,30 英寸和 60 英寸的算术平均数是 45 英寸。几何平均数用于比例。例如,30:1 60:1 的几何平均数是 42.4264:1。调和平均数用于比率。例如,在超过某一固定距离时 30 英里/小时和 60 英里/小时的平均数为 40 英里/小时。

    图 1 UI 测试自动化中的示例应用程序
    1 UI 测试自动化中的示例应用程序 (单击该图像获得较小视图)

    图 1 UI 测试自动化中的示例应用程序
    1 UI 测试自动化中的示例应用程序 (单击该图像获得较大视图)

     1 中所示的 UI 测试自动化是一个控制台应用程序,它可以启动所测试的应用程序,使用 UI 自动化库获取对应用程序中的应用程序控件和用户控件的引用,模拟用户输入 30 60,以及模拟单击“Calculate”(计算)按钮控件。然后测试自动化通过检查结果 TextBox 控件是否为预期值来查看应用程序的最终状态,并在随后输出通过失败结果。我在测试自动化关闭所测试的应用程序之前捕获屏幕快照。

    在 本专栏的其余部分中,我将简要介绍所测试的 StatCalc Windows 应用程序,并将说明如何启动所测试的应用程序;如何使用 UI 自动化库获得对应用程序控件和用户控件的引用;以及如何模拟用户操作和查看应用程序状态。我还将为您介绍如何扩展和修改此处介绍的测试系统以满足您的自身需求。我相信您会发现能够使用此新的 UI 自动化库对您的测试工具集是一个很好的补充。


    了解 StatCalc

    让我们简要了解一下所测试的应用程序,从而使您了解测试自动化的目标。您还将了解为什么说在编写 UI 测试自动化时能够访问应用程序源代码很有用,而又不是绝对必要的。

    StatCalc 应用程序是一个简单的基于 Windows 的窗体。我使用 C# 为应用程序编写代码,不过 UI 自动化库也可以与 Win32 应用程序和 WPF 应用程序配合工作。为了简单起见,我接受 Visual Studio® 的默认控件名称,包括 Form1label1textBox1groupBox1radioButton1radioButton2radioButton3 button1 textBox2。我使用 MenuStrip 控件(在 .NET Framework 2.0 及更高版本中提供),而非早期的 MainMenu 控件,增加了顶层菜单项:“File”(文件)和“Help”(帮助)StatCalc 应用程序的功能包含在 button1_Click 方法中,如图 2 所示。

    用 户单击“Calculate”(计算)按钮时,控制权转至 button1_Click 方法,该方法将 textBox1 中的值提取为单字符串。然后使用 String.Split 方法将每个值解析为字符串数组。接着,单击处理程序将字符串数组转换为整型数组。Button1_Click 逻辑将根据选择的单选按钮控件构造分支,以 double 类型计算相应的平均数,然后将结果的格式设置为四个小数位的字符串形式,显示在 textbox2 控件中。

    在计算几何平均数时,应用程序将调用名为 NthRoot 的本地 helper 方法,定义如下:

    private static double NthRoot(double x, int n) {
      return Math.Exp( Math.Log(x) / (double)n );
    }

    在此未执行任何常规错误检查,以确保应用程序代码尽可能的小并且易于理解。

    作 为经验之谈,在使用 UI 自动化库编写测试自动化时,不需要访问所测试系统的源代码。大多数情况下,可以通过控件的标题(例如 Calculate)而不是通过控件的内部 Name 属性(例如 button1)访问控件。但是,某些控件(例如,文本框控件)没有标题。

    若要使用 UI 自动化访问没有标题的控件,必需知道它们隐含的索引顺序。这一顺序是初始化窗体时控件加载到主窗体控件(或父控件)中的顺序。隐含的索引顺序不一定要与设计时将控件添加到窗体对象中的顺序一样,而且它与选项卡索引顺序也不一样。

    通过查看应用程序源代码可以很容易地确定没有标题的控件的隐含索引顺序。例如,如果我检查 StatCalc 应用程序的 Form1.Designer.cs 文件并展开 Windows 窗体设计器生成的代码区,可以看到以下代码:

    this.Controls.Add(this.button1);
    this.Controls.Add(this.groupBox1);
    this.Controls.Add(this.label1);
    this.Controls.Add(this.textBox2);
    this.Controls.Add(this.textBox1);
    this.Controls.Add(this.menuStrip1);

    这意味着 button1 具有隐含的索引 0groupBox1 具有索引 1,等等。请注意,textBox2 控件隐含的索引小于 textBox1 控件(即使在设计 StatCalc 应用程序时,将 textBox1 先于 textBox2 放到窗体对象上也是如此)。此外,控件 radioButton1radioButton2 radioButton3 groupBox1 控件的子控件,而不是 Form1 的子控件。稍后您将看到,在使用 UI 自动化库编写测试自动化时,控件树的深度级别是很重要的。

    因此,如果可以访问所测试的应用程序的源代码, 就可以轻松地确定控件隐含的索引顺序。但不能访问源代码时的情况如何呢?确定控件隐含的索引顺序的一种方法是使用 Visual Studio 附带的 Spy++ 工具。启动 Spy++ 后,可按 Ctrl+F5 然后将 GUI Finder 工具拖动到任何控件/窗口上获取关于该控件/窗口的详细信息。 3 显示了使用 Spy++ 指向 textBox1 控件时的结果。在背景中,您可以看到 textBox1 句柄为 00080820。在前景中,textBox1 后面的下一个控件标题为 menuStrip1,而 textBox1 前面的一个控件没有标题,这个控件是 textBox2

    图 3 使用 Spy++ 查找隐含的索引顺序
    3 使用 Spy++ 查找隐含的索引顺序 (单击该图像获得较小视图)

    图 3 使用 Spy++ 查找隐含的索引顺序
    3 使用 Spy++ 查找隐含的索引顺序 (单击该图像获得较大视图)

    这样一来,即使您不能访问所测试的应用程序的源代码,也能通过使用 Spy++ 检查每个控件来最终推断所有应用程序控件的隐含的索引顺序。

    现 在,即便是通过 StatCalc 用户界面手动测试像它这样微小的应用程序也会是令人乏味、容易出错、耗时且效率低下。您必须输入一些输入数据,单击“Calculate”(计算)按钮控 件,直观地验证结果值,并手动将“pass/fail”(通过/失败)结果记录到电子表格或数据库中。一个更好的方法是,使用 UI 自动化库模拟用户执行应用程序,然后确定应用程序是否正确响应。通过自动化枯燥的测试案例,您可以将更多时间用于更有趣且更有用的手动测试案例,在这些测试案例中您的经验和直觉将发挥很大作用。

    Back to top


    UI
    测试自动化代码

    图 4 显示了我的测试工具的整体结构。启动 Visual Studio 后,我创建了一个新的 Console Application 程序。我决定使用 C#,但是如果您需要,应能很容易地将我的测试自动化代码转换为 Visual Basic 或其他任何 .NET 兼容的语言。接下来,我将项目引用添加到 UIAutomationClient.dll UIAutomationTypes.dll 库中。这些库是 .NET Framework 3.0 的一部分,通常位于 %PROGRAMFILES%\Reference Assemblies\Microsoft\Framework\v3.0 目录中。

    UI 自动化库体系结构使用客户端 - 服务器视点和命名约定。从 UI 测试自动化的角度来看,这意味着所测试的应用程序被称为服务器,测试工具被视为客户端 - 测试工具客户端向所测试的应用程序(服务器)请求 UI 信息。UIAutomationClient.dll 库实际上就是 UI 自动化客户端使用的测试自动化库。另外,UIAutomationTypes.dll 库包含 UIAutomationClient.dll 和其他 UI 自动化服务器库使用的各种类型的定义。

    UIAutomationClient.dll UIAutomationTypes.dll 库外,您还将看到 UIAutomationClientSideProvider.dll UIAutomationProvider.dll 库。UIAutomationClientSideProvider.dll 库包含一组与构建时不支持自动化的控件配合使用的代码,这些控件可能包括旧式控件和自定义的 .NET 控件。由于我的应用程序全部使用标准控件(均设计为支持 UI 自动化),因此我不需要此库。UIAutomationProvider.dll 库是一组接口定义,可供创建自定义 UI 控件和希望控件能被 UI 自动化库访问的开发人员使用。

    添加 我的项目引用后,System.Windows.Automation 命名空间将对我的测试工具程序可见,并且我可以向该命名空间中添加 using 语句。为了方便起见,我添加了指向 System.Diagnostics 命名空间的 using 语句(以便能够方便地使用 Process 类),和指向 System.Threading 命名空间的 using 语句(以便能够方便地使用 Thread.Sleep 方法)。像往常使用任何测试自动化时一样,我将我的工具与顶层 try/catch 块封装在一起来处理任何致命错误。众所皆知,测试自动化软件机敏睿智,而异常是常事而非例外。

    我的测试自动化代码首先启动所测试的应用程序:

    Console.WriteLine("\nBegin WPF UIAutomation test run\n");
    Console.WriteLine("Launching StatCalc application");
    Process p =
        Process.Start("..\\..\\..\\StatCalc\\bin\\Debug\\StatCalc.exe");

    请注意,我捕获了所测试的应用程序的进程信息。接下来,我获取对主机的桌面窗口的引用作为 AutomationElement

    AutomationElement aeDesktop = AutomationElement.RootElement;

    大多数对使用 UI 自动化库进行测试自动化有用的对象都是 AutomationElement 类型。在此我能使用 AutomationElement 的静态 RootElement 属性获得对顶层可视元素(桌面)的引用。在执行 UI 测试自动化时,将主机上的每个可视实体(控件、窗口等)视为根元素作为桌面窗口的层次树结构的一部分是非常有用的。这是针对各种 UI 自动化的通用原则,包括使用 UI 自动化库的自动化。

    接下来,我需要获得对主窗体对象的引用,该对象实际上就是 StatCalc 应用程序。以下说明了实现上述操作的一种简单方法:

    // navie approach
    Thread.Sleep(5000);
    AutomationElement aeForm =
        AutomationElement.FromHandle(p.MainWindowHandle);
    if (aeForm == null)
        Console.WriteLine(
            "Could not find the StatCalc Form");

    暂停几秒钟以便给我的所测试的应用程序留出启动时间,然后使用 FromHandle 方法获得对该应用程序的引用。请记住,我在启动所测试的应用程序时保存了该应用程序的进程信息。

    尽 管这一方法很奏效,但是它还存在两点小问题。首先,在尝试访问窗体对象之前没有好的方法可用于推测等待时间的长短。因此,必须进行保守估计,设置一个很长 的延迟时间,这将大大减慢测试自动化的速度,在运行数百或数千个测试案例时尤其如此。其次,此方法假定测试工具启动所测试的应用程序(允许您保存有关应用程序的进程信息)。但是,在某些测试情况下,您要测试的应用程序已在运行,因此您将不能立即访问所测试的应用程序的进程信息(虽然您能够以编程方式获得这 些信息)。

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

    此外,我使用 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.ChildrenradioButton 控件是 groupBox1 控件的子项,后者又是 Form1 控件的子项,因此 radioButton 控件是 Form1 的后代,但不是它的子项。或者,我可以首先获得对 groupBox1 控件(为 Form1 的子项)的引用,然后再获得对 radioButton1(为 groupBox1 控件的子项)的引用。

    在采用上述获得对 radioButton1 的引用的方法获得对 radioButton2(几何平均数)和 radioButton3(调和平均数)的引用后,我可以开始执行所测试的应用程序。以下是我模拟用户向 textBox1 控件中键入一些输入数据的方法:

    Console.WriteLine("\nSetting input to '30 60'");
    ValuePattern vpTextBox1 =
      (ValuePattern)aeTextBox1.GetCurrentPattern(ValuePattern.Pattern);
    vpTextBox1.SetValue("30 60");

    SetValue 方法可能不会让人感到吃惊,但是请注意我不能通过 aeTextBox1 对象直接访问 SetVaue。因此,我改用中介 ValuePattern 对象。AutomationPattern 对象(如 ValuePattern)的概念对于刚接触 UI 自动化库的工程师来说可能是概念理解上最大的障碍。您可以将模式对象视为用于公开控件功能的一种抽象方法,此方法与控件的类型或外观无关。换句话说,可以使用特定的 AutomationPattern 实例(如 ValuePattern)来启用特定的控件功能。

    考 虑到控件的 ControlType 公开了控件的类型,控件的 Pattern 公开了控件的作用,我对控件做了进一步简化。此处需要特别注意的是控件可以支持多种模式。以下是我使用 AutomationPattern 选择 radioButton2 控件的方法:

    Console.WriteLine("Selecting 'Geometric Mean' ");
    SelectionItemPattern ipSelectRadioButton2 =
      (SelectionItemPattern)aeRadioButton2.GetCurrentPattern(
        SelectionItemPattern.Pattern );
    ipSelectRadioButton2.Select();

    这一次我使用 SelectionItemPattern 来启用选择。GetCurrentPattern 方法的名称经常会令 UI 自动化库初学者困惑。从测试自动化角度来看,此方法将设置(而不是获取)指定的 AutomationPattern。而从客户端 - 服务器的角度来看,自动化客户端代码将从所测试的应用程序的服务器代码中提取特定的属性。以下我用于模拟单击“Calculate”(计算)按钮控件的代 码应该能够有助于阐明上述内容:

      Console.WriteLine("Clicking on Calculate button");
      InvokePattern ipClickButton1 =
        (InvokePattern)aeButton.GetCurrentPattern(
        InvokePattern.Pattern);
      ipClickButton1.Invoke();
      Thread.Sleep(1500);

    这里,我使用 InvokePattern 来启用按钮单击,然后使用 Invoke 方法执行单击。请注意,我暂停 1.5 秒以留出我的应用程序响应的时间。我还可以进入延迟循环,使用我将在稍后简要介绍的方法定期进行检查以查看结果 textBox2 字段是否为空。有 18 AutomationPattern 类型,我已在图 6 中列出了这些类型。了解 AutomationPattern 类是了解如何使用 Microsoft UI 自动化库执行所测试的应用程序的关键。

    此 时,在我的测试自动化代码中,我启动了所测试的应用程序,在输入 (textBox1) 控件中输入了“30 60”,选择了“Geometric Mean”(几何平均数)(radioButton2) 控件,并且单击“Calculate”(计算)(button1) 控件。现在,我检查 textBox2 控件以查看是否得到了预期值:

    Console.WriteLine("\nChecking textBox2 for '42.4264'");
    TextPattern tpTextBox2 =
      (TextPattern)aeTextBox2.GetCurrentPattern(TextPattern.Pattern);
    string result = tpTextBox2.DocumentRange.GetText(-1);

    我再次使用 AutomationPattern(这次选择 TextPattern)以准备调用 GetText 方法。请注意,我通过 DocumentRange 属性间接调用 GetText,这一调用将返回一个封装有主文本“document”的文本段 - 在本例中为一个文本框。GetText 的参数旨在指明我未对返回字符串的长度设定最大限制。

    读取 textBox2 控件的内容的另一种方法是使用 GetCurrentPropertyValue 方法,如下所示:

    string result =
      (string)aeTextBox2.GetCurrentPropertyValue(
        ValuePattern.ValueProperty);

    在设置了 AutomationElement 控件的某个属性时,GetCurrentPropertyValue 方法将返回该控件的当前属性;而在未设置上下文控件的属性时,GetCurrentPropertyValue 方法将返回该控件的默认属性的值。在本例中,我未设置 textBox2 控件的属性,因此带有参数 ValueProperty GetCurrentPropertyValue 将返回 tetxtBox2 控件的默认属性(即 Text 属性)的值。使用 GetCurrentProperty 在编码时可节省时间,但是由于控件的当前属性在运行时可能会更改,因此具有风险。

    得到计算结果之后,我对照预期值进行检查以确定我的测试方案的结果是通过还是失败:

    if (result == "42.4264") {
      Console.WriteLine("Found it");
      Console.WriteLine("\nTest scenario: Pass");
    }
    else {
      Console.WriteLine("Did not find it");
      Console.WriteLine("\nTest scenario: *FAIL*");
    }

    现在,我能够关闭所测试的应用程序:

    Console.WriteLine("\nClosing application in 5 seconds");
    Thread.Sleep(5000);
    WindowPattern wpCloseForm =
      (WindowPattern)aeForm.GetCurrentPattern(WindowPattern.Pattern);
    wpCloseForm.Close();

    我使用 WindowPattern 类的 Close 方法,这是针对 UI 自动化库的主题法。

    通过另一种方法也可以关闭所测试应用程序,您可以操作以下代码开头的“File”(文件)|“Exit”(退出)菜单项:

    AutomationElement aeMenu =
      aeForm.FindFirst(TreeScope.Children,
        new PropertyCondition(AutomationElement.ControlTypeProperty,
          ControlType.Menu));

    但是,ControlType.Menu 类型是 .NET Framework 1.1 MainMenu 控件,不能与较新的 MenuStrip 控件配合使用。因为我的所测试应用程序使用 MenuStrip,所以我无法使用 ControlType.Menu 类型。这是一个罕见的异常;UI 自动化库支持绝大多数用户控件,还通过 UIAutomationProvider.dll 库中包含的功能提供了对自定义控件的自动化支持。至此我的测试自动化即将完成,我可以记录我的测试案例结果并启动另一个测试方案。

    Back to top


    扩展测试工具

    本 月的专栏中提供的代码将为您开始使用 UI 自动化库创建自己的测试自动化奠定坚实的基础。正如您已了解的,此库的涵盖面非常广泛,而且其纯面向对象的编程模型与您用过的其他库可能有些不同。但是,我相信您很快就能学会如何使用它编写功能强大的 UI 测试自动化。值得关注的三个关键概念是:使用 ControlType 类确定 UI 控件的类型,使用 AutomationPattern 类确定 UI 控件的功能,以及使用 PropertyCondition 类指定特定的 UI 控件。

    可以使用多种方法来扩展我介绍的这一介绍性测试自动化工具中的观点。一种显而易见的扩展便是 对工具进行参数化。无需对输入和预期值进行硬编码,可以在命令行中将这些信息传递给测试工具。但更好的做法是,将测试案例数据存储创建为文本文件、数据库表或 XML 文件,在每个测试案例中重复使用,分析出测试案例数据并将这些数据传递到测试工具中。我在 2005 8 月的专栏中详细介绍了此类设计模式,请参阅 msdn.microsoft.com/msdnmag/issues/05/08/TestRun

    我在此专栏中介绍的代码不执行结果日志记录,但是在大多数情况下,您都会希望将测试案例结果记录到数据存储中,而不只是希望通过失败消息输出到命令外壳程序。

    我坚信 UI 自动化库将迅速成为最广泛使用的 UI 测试自动化框架。除了可供软件工程师免费使用的单一、标准、全面、一致且经过严格测试的 UI 自动化库之外,不需要其他任何东西。这已经使拥有公共论坛、博客、示例代码等的社区更加完善。

    这 并不是说我认定 UI 自动化库将完全取代其他可选方法(如,商业 UI 测试自动化框架和自定义的 UI 自动化框架)。但是,UI 自动化库与这些可选方法相比有许多明显的优点。与商业 UI 测试自动化框架相比,UI 自动化库附带了 .NET Framework 3.0(它是事实上的标准),成本更低。

    与由一位或两位软件工程师编写的自定义 UI 测试自动化库相比,UI 自动化库包含更多功能,您只需了解 API 集合,而不用了解每个自定义自动化库的新 API。但是,商业 UI 测试自动化框架的优势在于它们往往与多种工具(例如,测试案例管理器和错误报告软件工具)紧密集成。而轻型自定义 UI 测试自动化库的优势在于它们通常能够更轻松用作应急测试自动化,并且适用于特殊测试情形。然而,随着 .NET Framework 3.0 的出现并因被 Windows Vista 采用而更加普及,您有望看到 UI 自动化库的使用将快速增长。

我的存档

数据统计

  • 访问量: 2222
  • 日志数: 2
  • 建立时间: 2008-10-07
  • 更新时间: 2008-10-07

RSS订阅

Open Toolbar