Python下編寫Windows自動化測試軟件

https://www.jianshu.com/p/be3c46c7a905html

uiautomation模塊學習筆記


前段時間,因爲我的須要,在網上查找了一些關於Windows平臺下自動化測試的資料,最後找到了一款至關不錯的Python模塊:uiautomation,直接pip install uiautomation便可方便地獲取這個模塊。在學習這個模塊的同時,記些筆記,方便本身之後查閱,也方便你們翻閱。python

0x00 概述

這個庫在Github上是開源的,地址:https://github.com/yinkaisheng/Python-UIAutomation-for-Windows
並且做者是一名中國人,仍是南京人,讓我感受十分親切。
這個庫能夠說是十分貼合實際,在Windows平臺下,絕大部分軟件都要遵循Windows的規範,也就是說窗口啊,句柄啊、控件啊這些東西,都是通用的,Windows向外提供了這些接口。先感謝一下yinkaisheng,他的工做就是進一步給這些接口作了整合,給Python的開發者提供了接口。這極大地方便了想要用Python開發自動化測試程序的人。git

0x01 做者的readme文檔

  • 這個模塊是基於Windows的UIA技術實現的,系統最低須要WindowsXP SP3,支持MFC、WinForm、WPF、Metro UI(從Windows8開始Windows系統開發的一種新的窗口)、Qt和火狐,也就是說基於.Net技術的全部Windows窗體程序都支持,而其餘的軟件,好比基於DirectUI開發的,這個模塊可能難以獲取到其中的信息。
  • 做者將這個模塊開源了,基於Apache2.0,這覺得着源代碼能夠任意複製,修改,使用以及再發布,贊!
  • 安裝方法很簡單,在已有Python和pypi環境的電腦上運行pip install uiautomation便可安裝,而且主程序automation.py也會自動複製到Python的Scripts文件夾下。
  • 同時做者也提供了C++ dll的源碼,可是在這裏就不去涉及了。能夠看出做者是名十分敬業的開發人員!
  • 能夠簡單運行一下automation.py,直接運行的效果就是3秒後遍歷當前活動窗口的全部控件。對QQ運行的效果:github


     
     

     
     

    可見效果十分明顯,窗口內的控件信息所有都顯示出來了,包括控件類型,控件的名稱,控件的位置(以像素爲單位),句柄,控件樹深度等。同時,全部信息會保存到當前目錄下的@AutomationLog.txt文件中,方便查閱。編程

  • 做者提供了一個Demo,用於控制記事本程序:
import subprocess import uiautomation as automation print(automation.GetRootControl()) subprocess.Popen('notepad.exe') notepadWindow = automation.WindowControl(searchDepth = 1, ClassName = 'Notepad') print(notepadWindow.Name) notepadWindow.SetTopmost(True) edit = notepadWindow.EditControl() edit.SetValue('Hello') edit.SendKeys('{Ctrl}{End}{Enter}World') 

GetRootControl()方法將返回根控件,也就是整個Windows可視化的桌面(這麼理解沒錯吧)
WindowControl(searchDepth=1,ClassName='Notepad')方法將建立一個WindowsControl對象,參數的做用是細化如何找到咱們想要的控件,可用的參數有searchFromControl=None,searchDepth=0xFFFFFFF,searchWaitTime=SEARCH_INTERVAL,foundIndex=1,Name,SubName,ClassName,Depth等,能夠去源碼下的Control類的初始化方法init看一下這些參數怎麼用。ide

  • 接下來做者介紹了一個小工具Inspect.exe,這個工具是微軟提供的,能夠用來探測UI的內容,這個程序自動集成在微軟的Windows SDK中,我電腦上正好安裝了Visual Studio和Windows SDK,應該能夠找到這個程序。果真在工具集中找到了這個程序:函數


     
     

     
     

    能夠看到使用效果很是好,窗口的構造一目瞭然!工具

  • 最後做者放了一些本身使用該模塊的截圖,能夠看到,功能十分強大:學習


     

     

     

     

     

0x02 簡單瞭解實現原理

做者在readme文檔中外鏈了一篇博文,簡單介紹了實現原理,爲了能更好地掌握這個庫的使用,這篇原理我也簡單的學習一下。(原文連接測試

在最先的Windows開發中是沒有自動化測試的概念的。1997年微軟在操做系統中集成了MASS(Microsoft Active Accessibility)組件,可是微軟開發MASS組件的初衷並非爲了自動化測試,而是提供了一套接口,讓開發者們能夠方便的開發殘疾人士輔助軟件,好比讀屏軟件等。伴隨着自動化測試的應用愈來愈普遍,微軟正視了自動化測試的需求,在MASS的基礎上,對其從新封裝設計並實現了UIAutomation的類庫(.NET)。從Win7系統開始的後續Windows操做系統都整合了Windows Automation API的全部功能。做者在閱讀了MSDN上的《UI Automation Client Programmer's Guide》和CodeMagazine上的《Creating UI Automation Client Applications》兩篇文章後,用Python和C++對UIAutomation作了一層簡單的封裝,方便了想要用Python開發自動化測試應用而對.Net平臺又不太熟悉的人,好比我。

0x03 API學習摘要

以前也已經提到,這個模塊是做者對UIA用C++和Python簡單的作了一層封裝,只要能理解面向對象編程,學習難度也不是很大。正好,我在做者的CSDN博客裏面找到了做者使用此模塊的實例(原文連接),就以此爲學習的入口,代碼以下:

#!python3 # -*- coding: utf-8 -*- """ 本腳本能夠獲取QQ2017(v8.9.4)羣全部成員詳細資料,請根據提示作對應的操做 做者:yinkaisheng@foxmail.com """ import time import uiautomation as automation def GetPersonDetail(): detailWindow = automation.WindowControl(searchDepth= 1, ClassName = 'TXGuiFoundation', SubName = '的資料') details = '' for control, depth in automation.WalkControl(detailWindow): if isinstance(control, automation.EditControl): details += control.Name + control.CurrentValue() + '\n' details += '\n' * 2 detailWindow.Click(-10, 10) return details def main(): automation.Logger.WriteLine('請把鼠標放在QQ羣聊天窗口中的一個成員上面,3秒後獲取\n') time.sleep(3) listItem = automation.ControlFromCursor() if listItem.ControlType != automation.ControlType.ListItemControl: automation.Logger.WriteLine('沒有放在羣成員上面,程序退出!') return consoleWindow = automation.GetConsoleWindow() if consoleWindow: consoleWindow.SetActive() qqWindow = listItem.GetTopWindow() list = listItem.GetParentControl() allListItems = list.GetChildren() for listItem in allListItems: automation.Logger.WriteLine(listItem.Name) answer = input('是否獲取詳細信息?按y和Enter繼續\n') if answer.lower() == 'y': automation.Logger.WriteLine('\n3秒後開始獲取QQ羣成員詳細資料,您能夠一直按住F10鍵暫停腳本') time.sleep(3) qqWindow.SetActive() #確保羣裏第一個成員可見在最上面 left, top, right, bottom = list.BoundingRectangle while allListItems[0].BoundingRectangle[1] < top: automation.Win32API.MouseClick(right - 5, top + 20) for listItem in allListItems: if listItem.ControlType == automation.ControlType.ListItemControl: if automation.Win32API.IsKeyPressed(automation.Keys.VK_F10): if consoleWindow: consoleWindow.SetActive() input('\n您暫停了腳本,按Enter繼續\n') qqWindow.SetActive() listItem.RightClick() menu = automation.MenuControl(searchDepth= 1, ClassName = 'TXGuiFoundation') menuItems = menu.GetChildren() for menuItem in menuItems: if menuItem.Name == '查看資料': menuItem.Click() break automation.Logger.WriteLine(listItem.Name, automation.ConsoleColor.Green) automation.Logger.WriteLine(GetPersonDetail()) listItem.Click() automation.SendKeys('{Down}') if __name__ == '__main__': main() input('press Enter to exit') 

我用的環境是Pycharm2017.2社區版和Python3.6,這個模塊的內容主要集中在uiautomation.py文件中,學習方法就是去這個文件裏看相關的代碼。先簡單看一下這個代碼,看看裏面有哪些看不懂的,看不懂的地方就是要學習的地方。

首先是automation.WindowControl,這看起來是個對象,可是還不知道這個對象有哪些方法和屬性,下面的WalkControl和EditControl應該也是對象,從命名上看可能直接表明了窗體中的不一樣控件。control.CurrentValue應該是屬性,下面的detailWindow.Click()應該是模擬鼠標點擊的方法。再看main()函數,Logger.WriteLine()方法應該是跟日誌有關,ControlFromCursor()多是從鼠標獲取控件的方法......

這樣看一遍大概就知道應該去源碼裏面找哪些定義了,咱們利用PyCharm的跳轉定義功能能夠很容易地找到定義這些類和方法的代碼,都在uiautomation.py這個文件中。源碼就不貼了,經過跳轉功能能夠很容易地理解其中的方法與類之間的邏輯關係。這個文件中主要定義了「控件」這個類,就是兩千多行處的Class Control(.............):這一大段代碼,裏面包含了全部對控件的方法和基本的屬性。方法有獲取控件名稱啊,內容啊等,屬性有位置啊,是否Active啊這些。而後由Control類派生出各個子類,表明具體的各類控件,好比WindowControl類表示窗口,EditControl類表示輸入框,ButtonControl類表明按鈕等等,幾乎涵蓋全部Win窗體程序的全部控件。而且做者在不少類下面作了詳細的註釋,閱讀起來應該沒有什麼困難。理解的難點應該是這裏面有大量關於WinForm開發的知識,須要一點基礎。

那麼當咱們將這些方法與類的定義搞清楚以後,咱們就能讀懂這個實例的功能了。經過組合運用各個空間的屬性和方法,實現從QQ羣窗口中得到QQ羣的信息。包括羣號、羣成員信息、聊天記錄等信息,並保存到文本文件。

0x04 後記

  • 果真多看,多寫纔是提高實力的根本途徑,教材看一百遍不如本身摸索一遍!
  • Life is short,use Python!
做者:8f7aac77586a 連接:https://www.jianshu.com/p/be3c46c7a905 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索