03
11

核心实验:利用UIAutomation库测试Windows应用(三)

UIAutomation是微软在MSAA的基础上,对MSAA进行封装,重新设计并实现了 UIAutomation的类库(.Net),微软根据自动化测试的需求,重新实现了一套自动化体系。

 实 验 简 介



前面已经学习的自动化测试框架,除SikuliX之外都只能对B/S架构的系统进行自动化 测试,而Windows平台下的C/S架构用SikuliX来做自动化,可靠性、可维护性比较差。


项目代码中还要夹杂着大量的图片,对于整个项目来说,庞大的数据量里90%都是图片,对于编码者和使用者都会造成困扰,那么Windows平台的自动化测试框架就有了学习和使用的价值了。


目前Windows平台下自动化工具有:Windows API, MSAA - Microsoft Active Accessibility, UIAutomation

Windows API 通过FindWindow和EnumWindows来查找到窗口句柄,然后再调用其它 API(GetWindowText,GetWindowRect, GetWindowLong…)来获取窗口属性,以此来找到想要的控件(窗口),AutoIt工具就是Windows API的技术体现。


MSAA 提供一套接口,让开发人员可以方便的给残疾人开发可以使用的软件,比如读屏程序(鼠标移动到按钮的时候,可以发出声音,辅助视力障碍的人操作电脑),从而实现微软将电脑普及到每一个家庭的梦想。


它本身设计不是为了测试,但它提供一套接口,可以通过调用接口来达到测试的目的,也是目前主流Windows平台测试的基础,通过对其再次封装实现对系统软件的调用和测试。


UIAutomation是微软在MSAA的基础上,对MSAA进行封装,重新设计并实现了 UIAutomation的类库(.Net),微软根据自动化测试的需求,重新实现了一套自动化体系。

 

 实 验 目 的 



(1).熟练应用UIAutomation完成针对Windows应用程序的自动化测试。

(2).能够在实际测试项目中综合运用Web和Windows应用自动化测试技术完成复杂的测试操作。

 

 实 验 流 程 



  • UIAutomation使用中的问题


前面以计算器为例子,UIAutomation可以轻松实现。但在实际操作中,不可能就能得到所有元素的唯一属性,很多时候是什么都没有,或者是大家都用一样的名字。这样定位就不容易实现。


以QQMusic为例,选择歌手后会出现歌曲列表。但是,通过UISpy根本找不到唯一的属性,如图。


20201103_105340_463.png

20201103_105257_111.png

从上图可以看出,第一首歌只提供一个processId的属性,但是该属性在QQmusic里几乎所有元素都一样,所以不能用来定位。该问题提供一种解决方案,拖动UIAutomation界面的Properties下拉滚动条,可以看到出现元素的坐标,那么是否可以用过坐标来定位呢?如图所示。


20201103_105353_627.png

在UIAutomation里面提供一个click(x,y,waittime)的方法。我们可以尝试坐标定位。代码如下:

import subprocess

import uiautomation

import time

#打开QQMusic

subprocess.Popen('C:\Program Files (x86)\Tencent\QQMusic\QQMusic.exe')

time.sleep(2)

#定位主界面

musicwindow = uiautomation.WindowControl(searchDepth=1, ProcessId='6092 (QQMusic)')

#定位输入框

edit = uiautomation.EditControl(searchFromControl = musicwindow, foundIndex = 1,ProcessId='7148 (QQMusic)')

#将光标定位到输入框中

edit.Click()

#输入歌手,{ENTER}是模拟键盘回车

edit.SendKeys('樊凡{ENTER}')

time.sleep(2)

#点击指定坐标

uiautomation.Click(435,330)

结果发现,并不能播放。在歌曲中有个播放按钮,需要定位播放按钮的位置,提供一个简单获取位置坐标的方法,可以通过截图整个屏幕的方式保存图片。然后使用画图的方式打开。这样就可以在左下方获取播放按钮的坐标,如图所示。


20201103_105402_178.png


修改Click()中坐标,重新运行程序,就可以实现播放。

当然,程序本身提供全部播放,也可以将代码改为点击全部播放按钮,可以通过UISpy获取元素识别特征,然后调用。代码如下:


edit.SendKeys('樊凡{ENTER}')

time.sleep(2)

musicwindow.ButtonControl(Name='播放全部').Click()


当然,坐标定位不是最好的解决问题的方式,想要解决上面这种问题,可以尝试多级父子节点关系的查找定位,但这种方式肯定会非常复杂!


  • UIAutomation代码实例


下述代码演示了如何利用UIAutomation库完成对Windows 10自带的计算器和记事本的自动化操作。并用过程中还使用了PyUserInput库。需要下载安装pyHook和pyUserInput库即可。


import uiautomation, time, subprocess, os

from pykeyboard import PyKeyboard

 

class PyUIAuto():

 

    def calc_test(self):

        # 或者直接使用Python运行一个计算器

        # 启动之前先运行一条命令强制关闭所有计算器

        os.system("taskkill /f /IM Calculator.exe")

 

        # os.system("start /b calc.exe")

        subprocess.Popen("calc.exe")

 

        # 首先找到应用程序的顶层窗口

        calc_window = uiautomation.WindowControl(searchDepth=1, Name="计算器", ClassName="ApplicationFrameWindow")

 

        # 运行之前,如果程序已经启动,则将其放置于窗口上方

        calc_window.SetFocus()

        calc_window.SetTopmost(isTopmost=True)

 

        # 找到对应的该应用程序的对象进行操作

        button_3 = calc_window.ButtonControl(AutomationId="num3Button")

        button_3.Click()

        calc_window.ButtonControl(Name="加").Click()

        calc_window.ButtonControl(AutomationId="num5Button").Click()

        calc_window.ButtonControl(Name="等于").Click()

 

        # 得到实际运算结果并进行断言

        result = calc_window.TextControl(AutomationId="CalculatorResults").Name

        if result.split(" ")[1] == "8":

            print("测试成功.")

        else:

            print("测试失败.")

 

        os.system("taskkill /f /IM Calculator.exe")

 

        # 执行其他应用程序

        # os.system(r'"C:\Program Files\internet explorer\iexplore.exe" http://www.woniuxy.com')

 

 

    def notepad_test(self):

        os.system("start /b C:/Windows/notepad.exe")

        time.sleep(2)

        notepad = uiautomation.WindowControl(searchDepth=1, ClassName="Notepad")

        document = notepad.EditControl(AutomationId="15", Name="文本编辑器")

        document.SendKeys("这是一个文本编辑工具")  # 或使用SetValue

        notepad.MenuItemControl(Name="文件(F)").Click()

        # 按三次下箭头,再一次回车,打开文件保存对话框

        uiautomation.SendKey(uiautomation.Keys.VK_DOWN)

        uiautomation.SendKey(uiautomation.Keys.VK_DOWN)

        uiautomation.SendKey(uiautomation.Keys.VK_DOWN)

        uiautomation.SendKey(uiautomation.Keys.VK_ENTER)

 

        # 组合按键

        # uiautomation.Win32API.PressKey()

        # uiautomation.Win32API.ReleaseKey()

 

        uiautomation.SendKeys("D:\\uiauto_test4.txt")

        time.sleep(2)

        notepad.ButtonControl(Name="保存(S)").Click()

        time.sleep(2)

        notepad.ButtonControl(Name="关闭").Click()

 

        # os.system("taskkill /f /IM notepad.exe")

 

if __name__ == '__main__':

    # PyUIAuto().notepad_test()

    time.sleep(2)

    uiautomation.MoveTo(500, 600)

    pos = uiautomation.Win32API.GetCursorPos()

    print(pos)


总之,UIAutomation是一个功能非常强大的专门用于Windows操作系统的测试库,除了测试Windows应用程序外,也可以作为Web系统GUI自动化测试的辅助。


 思 考 练 习 

(1)完成上述代码实现并理解其作用。

(2)利用UIAutomation测试任意程序。


下周分享:核心实验:Android SDK配置与应用





为了答谢大家对蜗牛学院的支持,蜗牛学院将会定期对大家免费发放干货,敬请关注蜗牛学院的官方微信。

20190320_095757_834.jpg



版权所有,转载本站文章请注明出处:蜗牛学苑, https://www.woniuxy.cn/article/549