演练:创建、编辑和维护编码的 UI 测试
在本演练中,您将创建一个简单的 Windows Presentation Foundation (WPF) 应用程序来演示如何创建、编辑和维护编码的 UI 测试。 本演练为更正由各种计时问题和控件重构中断的测试提供了解决方案。
系统必备
本演练需要:
- Visual Studio 2010 旗舰版 或 Visual Studio 2010 高级专业版。
创建一个简单的 WPF 应用程序
在**“文件”菜单上指向“新建”,然后选择“项目”**。
将显示**“新建项目”**对话框。
在**“已安装的模板”窗格中,展开“Visual C#”,然后选择“Windows”**。
在中间窗格之上,验证是否将目标框架下拉列表设置为**“.NET Framework 4”**。
在中间窗格中,选择**“WPF 应用程序”**模板。
在**“名称”**文本框中,键入 SimpleWPFApp。
选择要用于保存项目的文件夹。 在**“位置”**文本框中,键入文件夹的名称。
单击**“确定”**。
用于 Visual Studio 的 WPF 设计器将打开,并显示项目的主窗口。
如果当前未打开工具箱,请将其打开。 单击**“视图”菜单,然后单击“工具箱”**。
在**“所有 WPF 控件”部分,将一个“Button”、“CheckBox”和“ProgressBar”**控件拖动到设计图面的主窗口中。
选择 Button 控件。 在“属性”窗口中,将**“Content”属性的值由“Button”**更改为“Start”。
选择 ProgressBar 控件。 在“属性”窗口中,将**“Maximum”属性的值由“100”更改为“1000”**。
选择 Checkbox 控件。 在“属性”窗口中,清除**“IsEnabled”**属性。
双击按钮控件,以添加 Click 事件。
将在代码编辑器中显示 MainWindow.xmal.cs,并且光标位于新的 button1_Click 事件中。
在 MainWindow 类的顶部,添加一个委托。 该委托将用于进度栏。 若要添加委托,请添加以下代码:
private delegate void ProgressBarDelegate( System.Windows.DependencyProperty dp, Object value);
在 button1_Click 方法中,添加以下代码:
double progress = 0; ProgressBarDelegate updatePbDelegate = new ProgressBarDelegate(progressBar1.SetValue); do { progress ++; Dispatcher.Invoke(updatePbDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { ProgressBar.ValueProperty, progress }); progressBar1.Value = progress; } while (progressBar1.Value != progressBar1.Maximum); checkBox1.IsEnabled = true;
验证 WPF 应用程序是否正常运行
在**“调试”菜单上,选择“启动调试”或按“F5”**。
单击**“启动”**。
几秒后,进度栏应 100% 完成。 现在,已启用复选框控件。
关闭 SimpleWPFApp。
为 SimpleWPFApp 创建和运行编码的 UI 测试
在解决方案资源管理器中,右击该解决方案,单击**“添加”,然后选择“新建项目”**。
随即出现**“添加新项目”**对话框。
在**“已安装的模板”窗格中,展开“Visual C#”,然后选择“测试”**。
在中间窗格中,选择**“测试项目”**模板。
单击**“确定”**。
在解决方案资源管理器中,名为**“TestProject1”**的新测试项目将添加到解决方案中,而且 UnitTest1.cs 文件会出现在代码编辑器中。 由于本演练中不使用 UnitTest1.cs 文件,因此可将其关闭。
在解决方案资源管理器中,右击**“TestProject1”,单击“添加”,然后选择“编码的 UI 测试”**。
此时将显示**“为编码的 UI 测试生成代码”**对话框。
选择**“录制操作、编辑 UI 映射或添加断言”选项,然后单击“确定”**。
将出现“UIMap – 编码的 UI 测试生成器”。
有关此对话框中选项的更多信息,请参见如何:创建编码的 UI 测试。
查找并运行您在前面创建的 SimpleWPFApp 应用程序。 默认情况下,该应用程序将位于 C:\Users\<username>\Documents\Visual Studio 2010\Projects\SimpleWPFApp\SimpleWPFApp\bin\Debug\SimpleWPFApp.exe
创建 SimpleWPFApp 应用程序的桌面快捷方式。 右击 SimpleWPFApp.exe 并选择**“复制”。 在桌面上右击,然后选择“粘贴快捷方式”**。
提示
使用应用程序的快捷方式可以快速启动应用程序,因此便于为应用程序添加或修改编码的 UI 测试。 不必导航到该应用程序。 在本演练中,您必须再次运行该应用程序。
在“UIMap – 编码的 UI 测试生成器”中单击**“开始记录”**。 几秒后,“编码的 UI 测试生成器”将准备就绪。
使用桌面快捷方式运行 SimpleWPFApp.exe。
在 SimpleWPFApp 中,单击**“开始”**。
几秒后,进度栏应 100% 完成。 现在,已启用复选框控件。
选中 Checkbox 控件对应的框。
关闭 SimpleWPFApp 应用程序。
在“UIMap – 编码的 UI 测试生成器”中,单击**“生成代码”**。
在“方法名称”中键入 SimpleAppTest,然后单击**“添加并生成”**。 几秒后,编码的 UI 测试将出现,并且会添加到“解决方案”中。
关闭“UIMap – 编码的 UI 测试生成器”。
CodedUITest1.cs 文件将出现在代码编辑器中。
运行编码的 UI 测试
在 CodedUITest1.cs 文件中,找到**“CodedUITestMethod”方法,右击并选择“运行测试”**。
当编码的 UI 测试运行时,SimpleWPFApp 将可见。 它会执行您在前面的过程中执行的步骤。 但是,当测试试图选中 CheckBox 控件对应的复选框时,“测试结果”窗口将显示测试未通过。 原因是测试试图选中该复选框,但不知道 CheckBox 控件已被禁用,直至进度栏 100% 完成为止。 通过可用于编码的 UI 测试的各种 UITestControl.WaitForControlXXX() 方法可以更正此问题和类似问题。 下面的过程将演示如何使用 WaitForControlEnabled() 方法更正导致此测试未通过的问题。 有关更多信息,请参见播放期间让编码的 UI 测试等待特定事件。
编辑并重新运行编码的 UI 测试
在“测试结果”窗口中,右击未通过的测试,并选择**“查看测试结果详细信息”**。
将显示 CodedUITestMethod1[Results]。
在**“错误堆栈跟踪”部分,单击“TestProject1.UIMap.SimpleAppTest()”**旁边的第一个链接。
将打开 UIMap.Designer.cs 文件,并在代码中突出显示错误点:
// Select 'CheckBox' check box uICheckBoxCheckBox.Checked = this.SimpleAppTestParams.UICheckBoxCheckBoxChecked;
若要更正此问题,可以使用 WaitForControlEnabled() 方法使编码的 UI 测试等待 CheckBox 控件被启用,然后再继续此行。
警告
请不要修改 UIMap.Designer.cs 文件。 每次使用“UIMap - 编码的 UI 测试生成器”生成代码时,都会覆盖在 UIMapDesigner.cs 文件中进行的所有代码更改。 如果必须修改录制的方法,则必须将其复制到 UIMap.cs 文件并对其重命名。 UIMap.cs 文件可用于重写 UIMapDesigner.cs 文件中的方法和属性。 必须在 Coded UITest.cs 文件中删除对原始方法的引用,并将其替换为重命名的方法名称。
在 UIMapDesinger.cs 文件中,选择整个 SimpleAppTest 方法的所有代码并复制该代码。
在解决方案资源管理器中,打开 UIMap.cs 文件。
将 SimpleAppTest 方法代码粘贴到 UIMap 分部类中。
将方法由 SimpleAppTest() 重命名为 ModifiedSimpleAppTest()
将下面的 using 语句添加到文件中:
using Microsoft.VisualStudio.TestTools.UITesting.WpfControls;
在之前标识的有问题的代码行之前添加下面的 WaitForControlEnabled() 方法:
uICheckBoxCheckBox.WaitForControlEnabled(); // Select 'CheckBox' check box uICheckBoxCheckBox.Checked = this.SimpleAppTestParams.UICheckBoxCheckBoxChecked;
在 CodedUITest1.cs 文件中,查找**“CodedUITestMethod”**方法并注释掉或重命名对原始 SimpleAppTest() 方法的引用,然后将其替换为新的 ModifiedSimpleAppTest():
[TestMethod] public void CodedUITestMethod1() { // 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 //this.UIMap.SimpleAppTest(); this.UIMap.ModifiedSimpleAppTest(); }
在**“生成”菜单上,单击“生成解决方案”**。
右击**“CodedUITestMethod”方法,然后选择“运行测试”**。
此时,编码的 UI 测试已成功完成测试中的所有步骤,“测试结果”窗口中将显示**“通过”**。
在 SimpleWPFApp 中重构控件
在 MainWindow.xaml 文件中,在设计器中选择按钮控件。
在“属性”窗口顶部,选择**“Button”旁边的值“button1”**,并将其值更改为 buttonA。
在**“生成”菜单上,单击“生成解决方案”**。
在**“测试”菜单上,选择“窗口”,然后单击“测试视图”**。
在测试视图中,在**“测试名称”列下选择“CodedUITestMethod1”,再单击工具栏中的“运行选定内容”**。
由于编码的 UI 测试找不到最初在 UIMap 映射为 button1 的按钮控件,因此测试未通过。 重构会以此方式对编码的 UI 测试产生影响。
在“测试结果”窗口中,右击未通过的测试,并选择**“查看测试结果详细信息”**。
将显示 CodedUITestMethod1[Results]。
在**“错误堆栈跟踪”部分,单击“TestProject1.UIMpa.SimpleAppTest()”**旁边的第一个链接。
将打开 UIMap.Designer.cs 文件。 代码中将突出显示错误点:
// Click 'Start' button Mouse.Click(uIStartButton, new Point(27, 10));
请注意,此过程前面的代码行使用了 UiStartButton,这是重构之前的 UIMap 名称。
若要更正此问题,可使用编码的 UI 测试生成器向 UIMap 中添加重构的控件。 可以更新测试的代码以使用该代码,如下一过程所示。
映射重构的控件并编辑和重新运行编码的 UI 测试
在 CodedUITest1.cs 文件的**“CodedUITestMethod1()”方法中,右击并选择“为编码的 UI 测试生成代码”,然后单击“使用编码的 UI 测试生成器”**。
将出现“UIMap – 编码的 UI 测试生成器”。
使用您之前创建的桌面快捷方式运行您在前面创建的 SimpleWPFApp 应用程序。
在“UIMap – 编码的 UI 测试生成器”中,将十字线工具拖至 SimpleWPFApp 中的**“Start”**按钮。
“Start”按钮包围在蓝色框中,编码的 UI 测试生成器需要几秒钟来为选定控件处理数据并显示控件属性。 请注意,“AutomationUId”命名为“buttonA”。
在控件的属性中,单击左上角的箭头以展开 UI 控件图。 请注意,已选择**“UIStartButton1”**。
在工具栏中,单击**“将控件添加到 UI 控件图”**。
窗口底部的状态通过显示**“所选控件已添加到 UI 控件图中”**来验证操作。
在“UIMap – 编码的 UI 测试生成器”中,单击**“生成代码”**。
将显示“编码的 UI 测试生成器 – 生成代码”,其中包含一个注释,指示不需要任何新方法,并且只为 UI 控件图的更改生成代码。
单击**“生成”**。
关闭 SimpleWPFApp.exe。
关闭“UIMap – 编码的 UI 测试生成器”。
“UIMap – 编码的 UI 测试生成器”需要几秒钟来处理 UI 控件图更改。
在解决方案资源管理器中,打开 UIMap.Designer.cs 文件。
在 UIMap.Designer.cs 文件中,在生成的代码类 UIMainWindow 中的构造函数下,展开**“属性”**区域。 请注意,已添加 public WpfButton UIStartButton1 属性。
在 UIStartButton1 属性中,展开“搜索条件”区域。 请注意,SearchProperties 设置为 "buttonA":
public WpfButton UIStartButton1 { get { if ((this.mUIStartButton1 == null)) { this.mUIStartButton1 = new WpfButton(this); #region Search Criteria this.mUIStartButton1.SearchProperties[WpfButton.PropertyNames.AutomationId] = "buttonA"; this.mUIStartButton1.WindowTitles.Add("MainWindow"); #endregion } return this.mUIStartButton1; } }
现在,您可以修改编码的 UI 测试,以使用新映射的控件。 如前一过程所述,如果要在编码的 UI 测试中重写任何方法或属性,则必须在 UIMap.cs 文件中执行此操作。
在 UIMap.cs 文件中,添加一个构造函数,并指定 UIStartButton 属性的 SearchProperties 属性,以使用值为 "buttonA": 的 AutomationID 属性
public UIMap() { this.UIMainWindowWindow.UIStartButton.SearchProperties[WpfButton.PropertyNames.AutomationId] = "buttonA"; }
在**“生成”菜单上,单击“生成解决方案”**。
在测试视图中,在**“测试名称”列下选择“CodedUITestMethod1”,在工具栏中单击“运行选定内容”**。
此时,编码的 UI 测试已成功完成测试中的所有步骤。 在“测试结果”窗口中,您会看到状态**“通过”**。