• 使用UI Automation库用于UI自动化测试


    UI Automation也不是什么新东西了,很久以前曾经用过一次,最近又在一个测试中打算使用,于是又翻了一遍MSDN。MSDN里的介绍确实非常详细,但是对于一个刚刚接触的人来说,大而全的文档反而使得无从下手。往往一个简单的Demo比得上大段的文字说明,因此我打算用几个简单的Demo来介绍一下UI Automation到底是如何使用的。

    首先,我们还是得知道UI Automation的MSDN文档在哪。在这:

    http://msdn.microsoft.com/en-us/library/ms753107.aspx

    我们只看关键的一节:

    Using UI Automation for Automated Testing

    上面的文档能够在你遇到各种复杂情况下有资料可查,下面就开始我们的Demo,大致分为以下几个步骤。

    1. 添加引用。 需要添加UIAutomationClient.dll,UIAutomationClientSideProvider.dll,UIAutomationTypes.dll

    2. 添加相应的命名空间System.Windows.Automation。

    3. 查找你感兴趣的控件。你要单击一个按钮或是在一个文本框输入内容,你得先找到它。要找到你要的控件,你就必须提供一些的标识来定位你的控件,包括:控件类型,标题等等。看一个简单的例子,如何找到一个窗口,标题为"test"。

    var desktop = AutomationElement.RootElement; // 先找到根元素,可以认为是桌面
    var condition = new PropertyCondition(AutomationElement.NameProperty, "test"); // 定义我们的查找条件,名字是test
    var window = desktop.FindFirst(TreeScope.Children, condition); // 在桌面的子控件中查找第一个符合条件的窗体。

    UI Automation有一个配套的工具,用于查看控件的属性和事件,就是UI Spy,单个文件,绿色版,非常好用。

    上面的PropertyCondtion是单个的属性条件,如果需要设置多个条件,可以使用AndContion对象。比如,我们在上面的window窗口中其中一个按钮,标题是"ok":

    var btnCondition = new AndCondition(
                    
    new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
                    
    new PropertyCondition(AutomationElement.NameProperty, "ok"));

    我们最常用的几个属性就是AutomationID,ControlType,NameProperty了,这几个属性都可以在UI Spy里查到。

    4. 如何触发控件的事件。比如,按钮的点击事件,窗口的拖动事件等等。好是来个简单的例子,也是最最常用的例子,按钮的点击:

    var button = window.FindFirst(TreeScope.Children, btnCondition);
    var clickPattern 
    = (InvokePattern)button.GetCurrentPattern(InvokePattern.Pattern);
    clickPattern.Invoke();

    我们怎么知道一个控件有哪些Pattern呢,还是看UI Spy。在左边的树目录中右键需要查看的控件,选中“Control Patterns”就可以查看有哪些Pattern,并且可以进行测试。下面这个地址可以查看一共有哪些Control Pattern,需要用到的时候查一下就知道了:

    UI Automation Control Patterns Overview 

    总结:

    可以看出,我上面的例子一共也没多少行,就把UI Automation的基本用法介绍了一遍,这些东西也是最最常使用到的,通常的情况也都能应付过去。如果需要更加深入的内容,就得自己去详细查看MSDN的文档了。

    同时,也许你也会发现,这套库用起来比较烦琐,就是简单的查找一个控件也要花费我们不少功夫。所以,我们可以在这套库的基础上去做自己的扩展,编写出一套适合自己的UI自动化库。一个最常见的例子就是做一个安装程序的自动化,我们需要去点击上面的下一步按钮,按钮点击后会进行安装操作,这时候按钮是灰色的,安装完成后,按钮恢复可用状态,然后点击完成。因为需要等待完成按钮出现,在自动化实现过程中我们可以实现一个等待控件的通用函数:

    static AutomationElement WaitForElement(AutomationElement parent, Condition condition, int milisecondTimeout)
    {
        var waitTime 
    = 0;
        var element 
    = parent.FindFirst(TreeScope.Children, condition);

        
    while (element == null)
        {
            
    if (waitTime >= milisecondTimeout)
            {
                
    break;
            }

            Thread.Sleep(
    500);
            waitTime 
    += 500;

            element 
    = parent.FindFirst(TreeScope.Children, condition);
        }

        
    return element;
    }

    往往我们使用控件的Name属性来标识,因此,我们可以再一步封装一下:

    static AutomationElement WaitForElement(int milisecondTimeout, params string[] controlTexts)
    {
        var waitTime 
    = 0;
        AutomationElement child 
    = null;

        
    while (true)
        {
            var parent 
    = AutomationElement.RootElement;
            var founded 
    = true;
            
    foreach (var text in controlTexts)
            {
                child 
    = WaitForElement(parent, text, 10);
                
    if (child == null)
                {
                    founded 
    = false;
                    
    break;
                }
                parent 
    = child;
            }

            
    if (founded)
            {
                
    break;
            }

            
    if (waitTime >= milisecondTimeout)
            {
                child 
    = null;
                
    break;
            }

            Thread.Sleep(
    500);
            waitTime 
    += 500;
        }
        
        
    return child;
    }

     因此,我就可以这样来等待一个控件的出现:

    var btn = WaitForElement(5000"安装向导""完成");

    甚至可以把按钮的点击也封装,封装成下面的方式调用,就像在AutoIt脚本里一样简单:

    Click("安装向导""完成");

    最后,其实我想说的是,在codeplex上,有一个开源项目White,对UI Automation进行了一些易用性上的封装,非常值得我们去学习和参考,甚至直接拿来使用。下一篇我们将继续学习White测试框架,敬请关注。

    微信扫一扫交流

    作者:CoderZh
    公众号:hacker-thinking (一个程序员的思考)
    独立博客:http://blog.coderzh.com
    博客园博客将不再更新,请关注我的「微信公众号」或「独立博客」。
    作为一个程序员,思考程序的每一行代码,思考生活的每一个细节,思考人生的每一种可能。
    文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    11.判断单链表是否有环
    10.从尾到头打印单链表
    9.单链表反转
    8.合并两个有序的单链表,合并之后的链表依然有序【出现频率高】
    【前端安全】JavaScript防http劫持与XSS (转)
    javascript Date format(js日期格式化)
    微信内置浏览器浏览H5页面弹出的键盘遮盖文本框的解决办法(转)
    document.visibilityState 监听浏览器最小化
    【19道XSS题目】不服来战!(转)
    一劳永逸的搞定 FLEX 布局(转)
  • 原文地址:https://www.cnblogs.com/coderzh/p/1603109.html
Copyright © 2020-2023  润新知