编码的 UI 测试剖析

在测试项目中创建编码的 UI 测试时,将向解决方案添加多个文件。 在本主题中,我们将使用编码的 UI 测试示例来浏览这些文件。

编码的 UI 测试的内容

创建编码的 UI 测试时,**“编码的 UI 测试生成器”**会创建一个被测试用户界面的映射以及所有测试的测试方法、参数和断言。 它还会为每个测试创建一个类文件。

文件

内容

可编辑?

UIMap.Designer.cs

声明部分

UIMap 类(分部类,自动生成)

方法

属性

UIMap.cs

UIMap 类(分部类)

CodedUITest1.cs

CodedUITest1 类

方法

属性

UIMap.uitest

测试用的 UI 的 XML 映射。

UIMap.Designer.cs

此文件包含创建测试时由**“编码的 UI 测试生成器”**自动创建的代码。 每当测试更改时都会重新创建此文件,因此不能在此文件中添加或修改代码。

声明部分

本部分包括以下 Windows UI 声明。

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Input;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
using MouseButtons = System.Windows.Forms.MouseButtons;

Microsoft.VisualStudio.TestTools.UITesting.WinControls 命名空间用于 Windows 用户界面 (UI)。 对于网页 UI,该命名空间为 Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;对于 Windows Presentation Foundation UI,该命名空间为 Microsoft.VisualStudio.TestTools.UITesting.WpfControls

UIMap 类

该文件的下一部分是 UIMap 类。

[GeneratedCode("Coded UITest Builder", "10.0.21221.0")]
public partial class UIMap

类代码以应用于该类的 GeneratedCodeAttribute 开头,该类声明为分部类。 您将注意到,该特性也适用于此文件中的每个类。 可以包含此类的更多代码的另一个文件是 UIMap.cs,稍后将对其进行讨论。

生成的 UIMap 类包含记录测试时指定的每个方法的代码。

public void LaunchCalculator()
public void AddItems()
public void VerifyTotal()
public void CleanUp()

UIMap 类的这一部分还包括这些方法所需的每个属性的生成代码。

public virtual LaunchCalculatorParams LaunchCalculatorParams
public virtual AddItemsParams AddItemsParams
public virtual VerifyTotalExpectedValues VerifyTotalExpectedValues
public virtual CalculateItemsParams CalculateItemsParams
public virtual VerifyMathAppTotalExpectedValues 
    VerifyMathAppTotalExpectedValues
public UIStartMenuWindow UIStartMenuWindow
public UIRunWindow UIRunWindow
public UICalculatorWindow UICalculatorWindow
public UIStartWindow UIStartWindow
public UIMathApplicationWindow UIMathApplicationWindow

UIMap 方法

每个方法都有一个与 AddItems() 方法类似的结构。 在代码下面对此进行了详细说明,为了清楚起见,增加了换行符。

/// <summary>
/// AddItems - Use 'AddItemsParams' to pass parameters into this method.
/// </summary>
public void AddItems()
{
    #region Variable Declarations
    WinControl uICalculatorDialog = 
        this.UICalculatorWindow.UICalculatorDialog;
    WinEdit uIItemEdit = 
        this.UICalculatorWindow.UIItemWindow.UIItemEdit;
    #endregion

    // Type '{NumPad7}' in 'Calculator' Dialog
    Keyboard.SendKeys(uICalculatorDialog, 
        this.AddItemsParams.UICalculatorDialogSendKeys, 
        ModifierKeys.None);

    // Type '{Add}{NumPad2}{Enter}' in 'Unknown Name' text box
    Keyboard.SendKeys(uIItemEdit, 
        this.AddItemsParams.UIItemEditSendKeys, 
        ModifierKeys.None);
}

每个方法定义的摘要注释都指出将哪个类用于该方法的参数值。 在本例中,该类为 AddItemsParams 类,稍后将在 UIMap.cs 文件中定义该类,它也是由 AddItemsParams 属性返回的值类型。

在方法代码的顶部是一个 Variable Declarations 区域,它为方法将使用的 UI 对象定义局部变量。

在此方法中,UIItemWindow 和 UIItemEdit 都是可使用 UICalculatorWindow 类访问的属性,后面的 UIMap.cs 文件中定义了该类。

下面是可使用 AddItemsParams 对象的属性从键盘向计算器应用程序发送文本的行。

VerifyTotal() 方法具有非常相似的结构,包括下面的断言代码。

// Verify that 'Unknown Name' text box's property 'Text' equals '9. '
Assert.AreEqual(
    this.VerifyTotalExpectedValues.UIItemEditText, 
    uIItemEdit.Text);

由于 Windows 计算器应用程序的开发人员没有为文本框提供公开可用的名称,因此该控件名称列为未知。 当实际值不等于预期值时,Assert.AreEqual 方法将失败,从而导致测试未通过。 另请注意,预期值包括一个小数点和后面的一个空格。 如果不得不修改此特定测试的功能,则必须允许使用该小数点和空格。

UIMap 属性

每个属性的代码在整个类中都非常标准。 用于 AddItemsParams 属性的下列代码可在 AddItems() 方法中使用。

public virtual AddItemsParams AddItemsParams
{
    get
    {
        if ((this.mAddItemsParams == null))
        {
            this.mAddItemsParams = new AddItemsParams();
        }
        return this.mAddItemsParams;
    }
}

请注意,属性在返回值之前使用名为 mAddItemsParams 的私有局部变量保存该值。 它为对象返回的属性名称和类名称相同。 该类在后面的 UIMap.cs 文件中定义。

属性返回的每个类在结构上都相似。 下面是 AddItemsParams 类。

/// <summary>
/// Parameters to be passed into 'AddItems'
/// </summary>
[GeneratedCode("Coded UITest Builder", "10.0.21221.0")]
public class AddItemsParams
{
    #region Fields
    /// <summary>
    /// Type '{NumPad7}' in 'Calculator' Dialog
    /// </summary>
    public string UICalculatorDialogSendKeys = "{NumPad7}";

    /// <summary>
    /// Type '{Add}{NumPad2}{Enter}' in 'Unknown Name' text box
    /// </summary>
    public string UIItemEditSendKeys = "{Add}{NumPad2}{Enter}";
    #endregion
}

与 UIMap.cs 文件中的所有类一样,此类也以 GeneratedCodeAttribute 开头。 在此小型类中有一个 Fields 区域,它定义了用作 Keyboard.SendKeys 方法的参数的字符串,该方法在前面讨论过的 UIMap.AddItems() 方法中使用。 您可以编写代码,以便在调用使用这些参数的方法之前替换这些字符串字段中的值。

UIMap.cs

默认情况下,此文件包含一个没有任何方法或属性的分部 UIMap 类。

UIMap 类

可以在此处创建自定义代码以扩展 UIMap 类的功能。 每次修改测试时,**“编码的 UI 测试生成器”**不会重新生成您在此文件中创建的代码。

UIMap 的所有部分都可以使用 UIMap 类的任何其他部分中的方法和属性。

CodedUITest1.cs

此文件由**“编码的 UI 测试生成器”**生成,但不会在每次修改测试时都重新创建,因此您可以修改此文件中的代码。 该文件的名称基于您创建测试时为测试指定的名称生成。

CodedUITest1 类

默认情况下,此文件只包含一个类的定义。

[CodedUITest]
public class CodedUITest1

T:Microsoft.VisualStudio.TestTools.UITesting.CodedUITestAttribute 会自动应用于该类,从而允许测试框架将其识别为测试扩展。 另请注意,该类不是分部类。 所有类代码都包含在此文件中。

CodedUITest1 属性

此类包含两个位于文件底部的默认属性。 不能修改这些属性。

/// <summary>
/// Gets or sets the test context which provides
/// information about and functionality for the current test run.
///</summary>
public TestContext TestContext
public UIMap UIMap

CodedUITest1 方法

默认情况下,此类只包含一个方法。

public void CodedUITestMethod1()

此方法将调用您在记录测试时指定的每个 UIMap 方法,有关 UIMap 类的部分对此进行了介绍。

如果取消注释,则标题为 Additional test attributes 的区域会包含两个可选方法。

// Use TestInitialize to run code before running each test 
[TestInitialize()]
public void MyTestInitialize()
{
    // To generate code for this test, select "Generate Code for Coded 
    // UI Test" from the shortcut menu and select one of the menu items.
    // For more information on generated code, see 
    // https://go.microsoft.com/fwlink/?LinkId=179463

    // You could move this line from the CodedUITestMethod1() method
    this.UIMap.LaunchCalculator();
}

// Use TestCleanup to run code after each test has run
[TestCleanup()]
public void MyTestCleanup()
{
    // To generate code for this test, select "Generate Code for Coded 
    // UI Test" from the shortcut menu and select one of the menu items.
    // For more information on generated code, see 
    // https://go.microsoft.com/fwlink/?LinkId=179463

    // You could move this line from the CodedUITestMethod1() method
    this.UIMap.CloseCalculator();
}

MyTestInitialize() 方法应用了 TestInitializeAttribute,它指示测试框架在任何其他测试方法之前调用此方法。 同样,MyTestCleanup() 方法应用了 TestCleanupAttribute,它指示测试框架在调用其他所有测试方法之后调用此方法。 这些方法的使用是可选的。 对于此测试,可从 MyTestInitialize() 来调用 UIMap.LaunchCalculator() 方法,并且可从 MyTestCleanup() 而不是 CodedUITest1Method1() 来调用 UIMap.CloseCalculator() 方法。

如果使用 CodedUITestAttribute 向此类添加更多方法,则测试框架将在测试过程中调用每个方法。

UIMap.uitest

这是一个 XML 文件,它表示编码的 UI 测试记录及其各个部分的结构。 其中包括操作和类,以及这些类的方法和属性。 UIMap.Designer.cs 文件包含由编码的 UI 测试生成器生成的用于重现测试结构的代码,并提供到测试框架的连接。

UIMap.uitest 文件不能直接编辑。 但是,可以使用编码的 UI 测试生成器来修改测试,此操作会自动修改 UIMap.uitest 文件和 UIMap.Designer.cs 文件。

请参见

任务

如何:创建编码的 UI 测试

如何:使用编码的 UI 测试生成器添加 UI 控件和验证代码

参考

UIMap

Microsoft.VisualStudio.TestTools.UITesting.WinControls

Microsoft.VisualStudio.TestTools.UITesting.HtmlControls

Microsoft.VisualStudio.TestTools.UITesting.WpfControls

GeneratedCodeAttribute

Assert.AreEqual

Keyboard.SendKeys

CodedUITestAttribute

TestInitializeAttribute

TestCleanupAttribute

概念

编码的 UI 测试的最佳做法

支持编码的 UI 测试和操作录制的配置和平台

其他资源

使用多个 UI 映射测试大型应用程序