使用 WPF UI 自动化来自动化软件






4.26/5 (11投票s)
我自动化了安装向导,

引言
在那篇文章中,我将向您展示一个有趣的魔法工具,它可以自动安装/卸载软件。实际上,我的目的是展示WPF UI自动化的强大功能。我认为UI自动化可以替代基本的应用程序测试,并自动化我们需要重复进行的任何操作。
这篇文章只是一个示例,演示了如何捕获一个窗口并在其中输入和更改数据。我以安装向导为例。
背景
我最近的开发任务是为一些需要定期部署的产品实现服务器部署自动化,这浪费了部署工程师大量的时间。此外,有时人们会犯错误,导致产品出现问题。
部署自动化主要包括构建、文件复制/粘贴、启动/停止服务、设置虚拟目录、备份数据库、修改和运行数据库脚本等等。在进行部署自动化时,我发现我需要安装和卸载MSI文件,但这些MSI文件没有静默安装模式,而是MSI文件安装向导需要输入文本框,还需要勾选复选框等。
市面上有很多工具可以录制安装步骤并按计划运行,但使用这些工具会遇到很多问题,例如错误处理、依赖特定工具在生产服务器上运行、许可问题等等。因此,我的首席架构师建议我使用WPF UI自动化来创建一个工具,该工具可以自动调用按钮、搜索文本框、在文本框中设置值、更改单选按钮、测量进度等等。我发现WPF UI自动化库是实现这一目标的一个很好的选择,并且我真的在一天内成功完成了。
步骤
通过自动化安装向导,我将展示一些自动化技术。它们如下:
步骤 1:搜索向导窗口并点击“下一步”按钮进入下一页。(该步骤将展示如何从桌面上查找窗口并调用按钮的代码。)
步骤 2:搜索文本框,更改文本,搜索单选按钮,选择单选按钮并继续。(该步骤将展示如何搜索当前窗口中是否存在 `textbox`,如果存在则在新文本框中插入文本,以及如何选择/取消选择单选按钮的代码。)
步骤 3:检查安装状态并继续(每个安装程序都应该有一个等待安装完成的阶段,通常会显示进度条,自动化脚本需要等待直到安装完成。这里我将展示等待新状态并继续的代码。)
步骤 4:关闭向导。(向导最简单的结束方式将在该步骤中展示。)
步骤 1
搜索向导窗口并点击“下一步”按钮进入下一页。
首先,我们需要搜索一个特定的窗口,自动化脚本将在该窗口中执行后续步骤。我通过窗口标题来获取窗口元素。代码如下:
AutomationElement rootElement = AutomationElement.RootElement;
if (rootElement != null)
{
Automation.Condition condition =
new PropertyCondition(AutomationElement.NameProperty,
"My Application Installer");
AutomationElement appElement =
rootElement.FindFirst(TreeScope.Children, condition);
}
获取主窗口后,我们需要点击“下一步”按钮继续。我写了一个名为的方法
Private AutomationElement GetElementByNameProperty
(AutomationElement parentElement, string nameValue)
这里参数1接受父元素,例如父窗口,参数2接受您正在搜索的元素的文本。该方法不仅可以用于按钮,还可以用于查找包含第二个参数名称的任何元素。代码如下:
private AutomationElement GetElementByNameProperty
(AutomationElement parentElement, string nameValue)
{
Automation.Condition condition =
new PropertyCondition(AutomationElement.NameProperty, nameValue);
AutomationElement element =
parentElement.FindFirst(TreeScope.Descendants, condition);
return element;
}
需要调用按钮进入下一步。
private void ClickElement(AutomationElement element)
上面的方法可以点击一个元素;如果该元素是按钮,则点击它;如果该元素是单选按钮,则选择它。将来,我将为其他控件修改该方法。代码如下:
private void ClickElement(AutomationElement element)
{
if (element != null)
{
if (element.Current.ControlType.Equals(ControlType.Button))
{
InvokePattern pattern =
element.GetCurrentPattern
(InvokePattern.Pattern) as InvokePattern;
pattern.Invoke();
Wait(2);
}
else if (element.Current.ControlType.Equals(ControlType.RadioButton))
{
SelectionItemPattern pattern =
element.GetCurrentPattern
(SelectionItemPattern.Pattern)
as SelectionItemPattern;
pattern.Select();
Wait(2);
}
}
}
第二步
搜索文本框,更改文本,搜索单选按钮,选择单选按钮并继续。
在该阶段,我将展示一个方法,该方法可以搜索当前窗口中是否存在 `textbox`,并且还可以向找到的任何文本框插入数据。
private bool SetValueInTextBox(AutomationElement rootElement, string value)
代码如下:
private bool SetValueInTextBox(AutomationElement rootElement, string value)
{
Automation.Condition textPatternAvailable =
new PropertyCondition
(AutomationElement.IsTextPatternAvailableProperty, true);
AutomationElement txtElement =
rootElement.FindFirst(TreeScope.Descendants, textPatternAvailable);
if (txtElement != null)
{
try{
Console.WriteLine("Setting value in textbox");
ValuePattern valuePattern =
txtElement.GetCurrentPattern
(ValuePattern.Pattern) as ValuePattern;
valuePattern.SetValue(value);
Wait(2);
return true;
}catch{
Console.WriteLine("Error");
return false;
}
}
else
{
return false;
}
}
在文本框中插入数据后,我们有两个单选按钮可供选择/取消选择。单选按钮的选择/取消选择方式与我在步骤一中描述的“下一步”按钮的点击方式相同。
步骤 3
检查安装状态并继续。
在我的自动化中,我需要在安装完成前等待一个窗口,这意味着我需要等待某些东西。我发现进度条是最好的控件选择和等待对象。
private void WaitUntilInstallationComplete(AutomationElement appElement)
该方法主要等待直到安装完成,这意味着进度条结束。该方法的代码如下:
private void WaitUntilInstallationComplete(AutomationElement appElement)
{
AutomationElement status = null;
Automation.Condition statusPatternAvailable = new PropertyCondition
(AutomationElement.IsRangeValuePatternAvailableProperty, true);
int numWaits = 0;
do{
Console.WriteLine(numWaits + "Waiting for close button");
status = appElement.FindFirst
(TreeScope.Descendants, statusPatternAvailable);
++numWaits;
Wait(5);
} while (status != null && numWaits < 50);
}
步骤 4
关闭向导。
最后,我们有一个关闭按钮需要调用以完成安装,这与我在步骤1中描述的“下一步”按钮相同。调用关闭按钮,然后调用向导关闭。
关注点
自动化这样的事情真的很有趣。软件测试人员可以利用这个例子来自动化Windows应用程序测试。
历史
- 版本 1:2010年2月23日
参考文献
一些博客帖子和文章帮助并启发了我使用WPF开发这样的工具。以下是一些链接。如果我忘记了某些链接,我深表歉意。