QT4C是什么
QTA作为腾讯内部元老级的自动化测试项目,之前已经先后对QTAF、QT4A、QT4i、QT4W进行了开源。在QTA正式对外开源提供了Android端、iOS端以及Web端的自动化测试能力后,外界对于Windows端自动化测试框架的呼声越来越高。
QT4C(Quick Test for Client)作为基于QTA提供的面向Win32应用的UI测试自动化测试框架,此次开源弥补了QTA自动化测试项目在Windows端能力的不足。QT4C使用Python开发,实现了Windows端的UI自动化测试,支持多种控件类型的自动化测试,同时支持扩展自定义控件类型,目前被用于PCQQ、企业微信等产品的自动化测试中。
功能亮点
01、多种控件类型支持
QT4C现支持对Windows Native控件、UIA控件、Web控件进行自动化测试。
02、支持无障碍化自动化测试
QT4C对于Win32原生控件支持MSAA(Microsoft Active Accessibility)无障碍化测试。在QT4C中,通过使用win32com模块和comtypes模块实现IAccessible接口的包裹类,对用户提供封装好的AccessibleObject对象进行使用,用户可以通过控件的AccessibleObject属性获取并进行无障碍化的自动化测试。
03、支持控件类型扩展
QT4C具有良好的扩展性,支持用户根据实际需求对控件类型进行扩展,支持多种使用场景,用户可以针对自研控件实现测试桩注入逻辑,通过扩展新的控件类型对自研控件进行UI自动化测试。
04、支持PC端的Web自动化测试
QT4C对于Windows端的浏览器同样进行了封装,用户可以在QT4C的基础上使用QT4W进行Web自动化测试,同样支持Win32应用的内嵌Web自动化测试。目前QT4C已经对IE浏览器、Chrome浏览器进行了封装,用户可以直接在Windows上使用上述浏览器进行Web自动化测试。
设计原理
在QT4C中,Windows中所有的控件类型都可以抽象为Control供用户调用,每一种控件类型都继承自Control类。对于Windows端常见的窗口,QT4C将其抽象成了Windows类,Window也可以视作特殊的Control,它既是Control的载体,也能够调用Proxy Object中封装的方法来进行操作。
QT4C对每一种控件类型都内置了Proxy Object,用于获取应用程序的属性或者进行操作,Proxy Object底层基于注入测试桩或调用被测程序提供的API来封装获取属性或操作的接口。
使用说明
QT4C基于QPath技术和QTA UI框架,控件封装简单,结构清晰,可以同时使用多种控件类型进行定位,用户可以非常方便地利用QPath定位控件并进行自动化测试。关于QPath的语法和使用,可以参考QPath使用文档。这里以Windows自带的计算器为例,展示我们如何利用QT4C来对计算器的运算能力进行自动化测试,更多使用说明可参考QT4C使用文档。
01、使用Inspect获取控件属性
Inspect是一种Win32应用控件抓取工具,你可以使用微软提供的Inspect.exe来获取控件,关于微软的Inspect.exe的使用,可参考官方文档。
这里使用Inspect获取计算器主界面的控件,下面是Inspect的截图。
借助Inspect工具,就可以获取大部分Win32应用中控件的属性来使用QPath来对其进行封装。
02、封装控件
根据Inspect获取到的计算器主界面属性,可以写出主界面MainPanel的QPath:
"/ClassName='CalcFrame' && Text='计算器' && Visible='True'"
- 1
其次对界面中每个按键进行抓取封装,这里建议尽可能通过ClassName、ControlId等这些比较容易进行区分的属性来封装控件,例如按键1的QPath为:
"/ClassName='Button' && MaxDepth='3' && ControlId='0x83'"
- 1
这里封装几个接下来要进行自动化测试的按键以及操作逻辑作为参考:
class MainPanel(win.Window): def __init__(self, qpath=None): qp = QPath("/ClassName='CalcFrame' && Text='计算器' && Visible='True'") super(MainPanel, self).__init__(locator=qp)
self.updateLocator({ '按键1': {'type': win.Control, 'root': self, 'locator': QPath("/ClassName='Button' && MaxDepth='3' && ControlId='0x83'")}, '按键2': {'type': win.Control, 'root': self, 'locator': QPath("/ClassName='Button' && MaxDepth='3' && ControlId='0x84'")}, '加号': {'type': win.Control, 'root': self, 'locator': QPath("/ClassName='Button' && MaxDepth='3' && ControlId='0x5D'")}, '等号': {'type': win.Control, 'root': self, 'locator': QPath("/ClassName='Button' && MaxDepth='3' && ControlId='0x79'")}, '结果': {'type': win.Control, 'root': self, 'locator': QPath("/ClassName='Static' && MaxDepth='3' && ControlId='0x96'")} })
def add (self): self.wait_for_exist(5, 0.2) self.Controls['按键1'].click() self.Controls['加号'].click() self.Controls['按键2'].click() self.Controls['等号'].click()
- 1
- 2
- 3
03、进行自动化测试
在对控件进行封装之后,就可以在测试用例中使用封装好的MainPanel类来进行自动化测试,这里以简单的加法运算为例:
mainPanel = MainPanel()mainPanel.add()self.assertEqual(mainPanel.Controls['结果'].Text, '3')
- 1
04、自动化测试示例
真诚开源
我们后续会继续完善和优化功能,提升框架稳定性;同时支持远程操作Windows机器进行UI自动化测试。如果你对这个项目感兴趣,还请给这个项目一个 Star,欢迎提出你的 issue 和 PR!欢迎您和我们一起优化!