1、文章一:
题记
本文简述如何利用appium对Windows桌面应用程序进行UI自动化测试。
UI自动化测试
所谓UI自动化测试,就是模拟一个用户,对应用程序的UI进行操作,以完成特定场景的功能性集成测试。
要对Windows桌面应用程序进行UI自动化测试,目前可选的技术主要是两种:
VS自带的CodedUI Test和Appium+WinAppDriver。
但是,微软已经宣布VS2019将是带有CodedUI Test的最后一个版本,且在面对某些复杂场景的时候有点力不从心。
而Appium作为移动应用主流的UI测试工具,已经被业界广泛采用,且相关的接口是标准化的,因此微软对其进行了扩展(即WinAppDriver),让Appium可以支持包括Universal Windows Platform (UWP), Windows Forms (WinForms), Windows Presentation Foundation (WPF), and Classic Windows (Win32)之内的Windows桌面应用。所以采用Appium来作为Windows桌面应用程序UI自动化测试的工具是最佳选择。
要完成UI自动化测试的大致步骤如下(你首先需要一台Windows 10的PC):
-
准备好待测试的Windows桌面应用程序。
-
到 https://github.com/Microsoft/WinAppDriver/releases 下载WinAppDriver的安装包,进行安装。并启用Windows 10的开发者模式。从安装目录(比如:C:\Program Files (x86)\Windows Application Driver)来启动WinAppDriver。
-
用你喜欢的测试框架创建UnitTest项目,在项目中引用Appium.WebDriver这个Nuget包。
-
编写测试用例,执行测试。
整个用例的编写也相对简单:
-
使用DesiredCapabilities来设定要测试的目标应用。
-
使用WindowsDriver来声明测试的会话。
-
通过测试会话查找对应的UI元素,对UI元素进行SendKeys(模拟填写内容)和Click(模拟点击)等操作,或者获取UI元素的相关Property和Attribute来进行验证。
-
编写测试最挑战的地方就是在于如何查找到UI元素,我们可以借用Windows SDK里面的inspect.exe这个工具来辅助我们查找。
工具的位置在C:\Program Files (x86)\Windows Kits\10\bin里面的特定版文件夹中。用法是先启动应用程序并导航到待测试的界面,启动这个工具就会获得桌面上所有窗口的UI元素层级关系,并通过焦点等方式导航到要查找的UI元素上。查看相应的信息,并采用适合的查找方式。具体的查找方式可见:https://github.com/Microsoft/WinAppDriver#supported-locators-to-find-ui-elements。
选择适合的查找方式有时候需要多尝试几种,有些UI元素只能用特定的方式来查找,比如html的input button只用FindElementByName ,而html的button就可以用FindElementByAccessibilityId 。
测试用例的编写可以参考WinAppDriver源代码自带的Sample,也可以参照我的示例:https://github.com/heavenwing/WindowsAppUITestSample。
在我的这个示例当中,目标应用采用的是Hybrid方式运行(即通过WebBrowser来嵌入html,并用C#进行行为操作),考虑到这种应用程序可能是多个函数库组装在一起,所以测试项目理应也是多个项目组合的(即功能函数库对应一个测试项目),并且其他测试项目可以复用公共的测试步骤(比如:列表页面复用登录的测试步骤)。
参考
https://www.cnblogs.com/redmoon/p/11401030.html
2、文章二:
参考:https://blog.csdn.net/The_Eyes/article/details/73432716
最近研究自动化测试,看了一下UI Automation的微软例子,表示太老了,遇到各种问题,
UI Spy 好像已经被放弃了,可以用inspect.exe来代替,win10 的路径为:“C:\Program Files (x86)\Windows Kits\8.1\bin\x64\inspect.exe”
这个用来查询automationId,
官网是以计算器例子,下面是在win10 修改后能运行版本:
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows.Automation;
namespace ConsoleApp1
{
class CalcAutomationClient
{
AutomationElement calWindow = null;//计算器窗口主窗口元素
string resultTextAutoID = "CalculatorResults";
string btn5AutoID = "num5Button";
string btn3AutoID = "num3Button";
string btn2AutoID = "num2Button";
string btnPlusAutoID = "plusButton";
string btnSubAutoId = "94";
string btnEqualAutoID = "equalButton";
static void Main(string[] args)
{
CalcAutomationClient autoClient = new CalcAutomationClient();
AutomationEventHandler eventHandler = new AutomationEventHandler(autoClient.OnWindowOpenOrClose);
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, eventHandler);
Process.Start("calc.exe");
Console.ReadLine();
}
private void OnWindowOpenOrClose(object sender, AutomationEventArgs e)
{
if (calWindow != null)
return;
if (e.EventId != WindowPattern.WindowOpenedEvent)
{
return;
}
if (sender == null)
{
Console.WriteLine("sender is null");
return;
}
Thread.Sleep(1000);//此处必须等待一下,应该是计算器的等待计算器完全加载,不然控件 找不到
AutomationElement sourceElement = null;
sourceElement = sender as AutomationElement;
Console.WriteLine(sourceElement.Current.Name);
try
{
sourceElement = sender as AutomationElement;
Console.WriteLine(sourceElement.Current.Name);
if (sourceElement.Current.Name == "计算器")
{
calWindow = sourceElement;
}
}
catch (Exception ex)
{
Console.WriteLine("ex:" + ex.Message);
return;
}
if (calWindow == null)
{
return;
}
ExcuteTest();
}
private void ExcuteTest()
{
ExcuteButtonInvoke(btn2AutoID);
ExcuteButtonInvoke(btnPlusAutoID);
ExcuteButtonInvoke(btn3AutoID);
ExcuteButtonInvoke(btnEqualAutoID);
string rs = GetCurrentResult();
Console.WriteLine(rs);
}
private void ExcuteButtonInvoke(string automationId)
{
Condition conditions = new AndCondition(
new PropertyCondition(AutomationElement.AutomationIdProperty, automationId),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
if (calWindow == null)
return;
AutomationElementCollection collection = calWindow.FindAll(TreeScope.Descendants, conditions);
if (collection == null || collection.Count == 0)
return;
AutomationElement btn = collection[0];
if (btn != null)
{
InvokePattern invokeptn = (InvokePattern)btn.GetCurrentPattern(InvokePattern.Pattern);
invokeptn.Invoke();
}
Thread.Sleep(1000);
}
private string GetCurrentResult()
{
Condition conditions = new AndCondition(
new PropertyCondition(AutomationElement.AutomationIdProperty, resultTextAutoID),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text));
AutomationElement text = calWindow.FindAll(TreeScope.Descendants, conditions)[0];
return text.Current.Name;
}
}
}
运行结果:
3、重要资源【实例】:
1)已验证可用【非常好的例子,便于理解】
C#自动化测试工具编写(借助API) :https://download.csdn.net/download/luminji/2796362
关键代码
1)自动化测试程序
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//获取被测试程序的窗口句柄
IntPtr mainWnd = FindWindow(null, "FormLogin");
List<IntPtr> listWnd = new List<IntPtr>();
//获取窗体上按钮的句柄,按钮上的文字为OK
IntPtr hwnd_button = FindWindowEx(mainWnd, new IntPtr(0), null, "OK");
//获取窗体上全部的子控件句柄
EnumChildWindows(mainWnd, new CallBack(delegate(IntPtr hwnd, int lParam)
{
listWnd.Add(hwnd);
return true;
}), 0);
foreach (IntPtr item in listWnd)
{
if (item != hwnd_button)
{
char[] UserChar = "StarStar".ToCharArray();
foreach (char ch in UserChar)
{
SendChar(item, ch, 100);
}
}
}
SendMessage(hwnd_button, WM_CLICK, mainWnd, "0");
}
public void SendChar(IntPtr hand, char ch, int SleepTime)
{
PostMessage(hand, WM_CHAR, ch, 0);
System.Threading.Thread.Sleep(SleepTime);
}
public static int WM_CHAR = 0x102;
public static int WM_CLICK = 0x00F5;
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
string lpszClass, string lpszWindow);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern int AnyPopup();
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
public static extern int EnumThreadWindows(IntPtr dwThreadId, CallBack lpfn, int lParam);
[DllImport("user32.dll")]
public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr PostMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern IntPtr SendMessageA(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowTextLength(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr GetParent(IntPtr hWnd);
public delegate bool CallBack(IntPtr hwnd, int lParam);
}
}
2)被测试程序
using System;
using System.Windows.Forms;
namespace WindowsFormsToBeTest
{
public partial class FormLogin : Form
{
public FormLogin()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show(textBox1.Text.Trim());
}
}
}
运行结果:
2)未验证
C#借助Code UI Automation实现黑盒自动化测试工具: https://download.csdn.net/download/luminji/2839416文章来源:https://www.toymoban.com/news/detail-791571.html
和上边的好像一样:文章来源地址https://www.toymoban.com/news/detail-791571.html
到了这里,关于C#【自动化测试】对Windows桌面应用程序进行UI自动化测试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!