WindowsGUI自动化测试项目实战+辛酸过程+经验分享
做测试的同事,应该都有相同的技术储备,那就是自动化测试。然而一直从事APIwebUI等方面的自动化测试,突然一天领导说让搞WindowsGUI自动化;说实话,当时还是很抵触的:一是 这方面的资源不多;二是 很多像样(我认为的)的工具是付费的;三是 自己没做过,但是又不得不去尝试;四是 因为业务的特殊性,涉及到了建模或者模型之类的东西不好做自动化。但没办公,只能自己上了。我们自己的建模软件,如图:其
WindowsGUI自动化测试项目实战+辛酸过程+经验分享
一、前言
⚜ 起因
- 做测试的同事,应该都有相同的技术储备,那就是自动化测试。然而一直从事
API
、webUI
等方面的自动化测试,突然一天领导说让搞WindowsGUI
自动化; - 说实话,当时还是很抵触的:
一是 这方面的资源不多;
二是 很多像样(我认为的)的工具是付费的;
三是 自己没做过,但是又不得不去尝试;
四是 因为业务的特殊性,涉及到了建模或者模型之类的东西不好做自动化。
- 但没办公,只能自己上了。
⚜ 项目要求
- 平台:
Windows
11(64位)系统; - 主要要求:
⚜ 完成:WindowsGUI
自动化测试框架预言和搭建;
⚜ 满足:模型或建模自动化的操作;
⚜ 达到:和WebUI
类似的框架组织(如Unittest+Python+Selenium+BeautifulReport
);
⚜ 特质:可以帮助测试人员提升编程技能,而非傻瓜式的操作某个工具;
⚜ 时间:一个星期。(想说句:我太难了~,因为当时确实是不会啊。)
⚜ 预研过程
⚜⚜ 框架选型
-
用例组织框架(
Unittest
):
⭕ 按照领导的要求,必须是和WebUI
类似,那好吧,我继续用Unittest
;
⭕ 这里为啥没用Pytest
,主要是当时对其还不是很熟悉,在一星期内要加上熟悉Pytest
,那真的是时间太紧张了。 -
编程语言(
Python
):
✔ 为啥选择它,因为当时团队成员基本都是用Python
做自动化测试的;
✔ 其实这个还与后边的界面控件识别有关系,因为界面识别框架UIaotumation
有作者对其进行了二次封装,感觉是不错的选择。 -
WindowsGUI
界面识别框架(UIaotumation
):
💦 为啥选择这个呢?详见后边的表格:
💦 当然也有其他很多工具,但是无非就是这几类:识别控件、坐标操作、图像识别;
💦 经过对比,按照Leader的要求,还是要选择按照识别控件的方式进行,因为其他两个类型对业务不太适合,比如坐标操作,我们的控件变化可能会很大,用这个就很麻烦了;
💦 最终我们看到了一个作者使用UIaotumation
来做Windows桌面端自动化测试,而没有选择一些工具,感觉受益匪浅。
工具 | 简介 |
---|---|
pywinauto | 主要使用到 Application 类,用于应用程序管理(打开与关闭应用等)、窗口管理(最小化、最大化、关闭窗口) |
Pywin32 | 包含 win32gui、win32api、win32con 3个子模块,用于窗口管理(定位窗口、显示和关闭窗口、获取窗口位置等) |
pyautogui | 屏幕控制(截屏等)、鼠标控制(移动鼠标、单击、双击、右击、拖拽等)、键盘控制(编辑、按键等) |
- 测试报告的选择,仍然使用
BeautifulReport
,简单美观使用。
⚜⚜ 关于UIaotumation框架
UIAutomation实现的自动化支持微软提供的各种界面开发框架,如Win32, MFC, Windows Forms, WPF, Metro App, IE;
另外Qt, Firefox, Chrome实现了UI Automation Provider,也支持UIAutomation;
作者用Python和C++对UIAutomation做了一层封装,方便我自己的使用,可以快速开发自动化脚本;
UIAutomation支持平台包括Windows XP(SP3),Windows Vista, Windows 7, Windows 8、8.1、10;
- 功能说明:
🏆#常用操作:
1、WindowContrl(searchDepth,ClassName,SubName) # 查找窗口中的程序,如果有中文则需用Unicode;可用window.Exists(maxSearchSeconds)来判断此窗口是否存在;
2、EditControl(searchFromControl) # 查找编辑位置,找到后可用DoubleClick()来改变电脑的focus;edit.SetValue(“string”)输入值;
3、Win32API.SendKeys(“string”) # 如果已在编辑位置,则可用此方法来输入值,{Ctrl}为ctrl键,其他类似;{@ 8}格式可输入8个@,对于数字也可实现此功能,但对于字母不能…;
4、MenuItemControl(searchFromControl,Name) # 查找菜单按钮;
5、ComboBoxControl(searchFromControl,AutomationI) # 查找下拉框,然后在此基础上用Select(“name”)方法来选择需要的选项;
6、BottonControl(searchFromControl,Name,SubName) # 查找按钮;
7、automation.FindControl(firefoxWindow, lambda c:(isinstance(c, automation.EditControl) or isinstance(c, automation.ComboBoxControl)) and c.Name == 'Enter your search term') # 按条件搜索handle
🏆#句柄常用操作
Click() # 点击;
RighClik() # 右键点击;
SendKeys() # 发送字符;
SetValue() # 传值,一般对EditControl用;
🏆# windows程序常用操作
subprocess.Popen(‘Name’) # 用进程打开程序;
window.Close() # 关闭窗口;
window.SetActive() # 使用;
window.SetTopMost() # 设置为顶层
window.ShowWindow(uiautomation.ShowWindow.Maximize) # 窗口最大化
window.CaptureToImage(‘Notepad.png’) # 截图
uiautomation.Win32API.PressKey(uiautomation.Keys.VK_CONTROL) # 按住Ctrl键
uiautomation.Win32API.ReleaseKey(uiautomation.Keys.VK_CONTROL) # 释放Ctrl键
automation.GetConsoleWindow() # return console window that runs python,打开控制台
automation.Logger.ColorfulWriteLine(’\nI will open <Color=Green>Notepad and <Color=Yellow>automate it. Please wait for a while.’) # 控制台传值(彩色字体),普通传值用WriteLine;
automation.ShowDesktop() # 显示桌面;
🏆# 句柄的抓取
# 直接运行automation模块枚举窗口时,支持下列参数(从doc窗口运行automation.py程序 )
-t intValue 延迟枚举时间,单位秒
-r 从树的根部枚举,如果不指定,从当前窗口枚举
-d intValue 枚举控件树的的深度,如果不指定,枚举整个树
-f 从焦点控件枚举,如果不指定,从当前窗口枚举
-c 从光标下的控件枚举,如果不指定,从当前窗口枚举
-a 获取光标下控件及其所有父控件
-n 显示控件的完整Name, 如果不指定,只显示前30个字符
-m 显示控件更多属性,默认只显示控件的四个属性
⚜ 预研成果
- 框架:
UIAutomation+Python+Unittest+Beautifulreport
; - 示例代码:
# -*- coding:utf-8 -*-
import unittest
import logging
import time
import uiautomation
import os
# @unittest.skip("跳过")
class TestFaultTree(unittest.TestCase):
def setUp(self) -> None:
# 初始化
os.system("calc") # 打开计算器
time.sleep(2)
self.calc = uiautomation.WindowControl(Name="计算器")
self.calc_list = ["二", "加", "八", "等于"]
self.result = "10"
def tearDown(self) -> None:
time.sleep(1)
self.calc.ButtonControl(Name="关闭 计算器").Click()
def test_toolbar(self):
time.sleep(1)
for i in range(0, len(self.calc_list)):
self.calc.ButtonControl(Name=self.calc_list[i]).Click()
time.sleep(0.5)
calc_result = self.calc.TextControl(foundIndex=3).Name
print("计算器运行结果为:", calc_result)
print("预期结果为:", self.result)
self.assertIn(self.result, calc_result)
if __name__ == "__main__":
unittest.main()
- 运行效果:
二、项目介绍
💓 测试对象
- 我们自己的建模软件,如图:
- 其实简单点说就是模拟用户的真实操作,和
WebUI
是一样的效果。
💓 技术栈
技术 | 版本及说明 |
---|---|
Python | V3.x(本文为3.7)===编程语言支撑 |
UIAutomation | 控件的识别、定位及操作 |
BeautifulReport | 生成Html测试报告 |
Logging | Python自带===生成log日志 |
Unittest | Python自带===自动化测试框架 |
Smtplib | Python自带===邮件服务 |
Python自带===邮件服务 | |
os | Python自带===系统模块 |
PyCharm | Community 2020.2汉化版 |
操作系统 | Windows10旗舰版64位 |
其它 | 后续补充 |
💓 项目框架说明
三、项目展示
🤣 界面实现效果
- 这里简单录制下自动化执行的效果;
- 真实场景要比这个复杂的多;
- 这里就不过多介绍了。
🤣 测试报告效果
🤣 用例执行失败效果
🤣 日志效果
🤣 使用场景说明
四、项目经验分享
✨ 技术迁移
- 其实最终做完了才发现,只是自己知道的太晚了;
- 框架逻辑和其他自动化是一样的,万变不离其中;
- 只需要把其他框架的核心工具如
Appium
、Selenium
、Reques
等换成UIaotumation
即可;
那这里我觉得就是平常工作中要多总结、多思考,技术这东西有很多事可以进行迁移的,听不一样非要从0开始。
✨ 语言基础的重要性
- 作为自动化测试的同事,编程语言是必须要掌握的;
- 但是语言的基础最为要命;
- 过程中发现一些简单的操作,其实是自身对编程语言本身的基础掌握不牢靠。
夯实基础,才能走的很深、更远。
✨ 多写、多练
- 因为平常写的少,看的多,结果实战起来,才发现根本是无从下手;
- 可以找一些其他的项目进行摸索,多写几遍就熟悉了。
光看不写,等于0.1,为啥是0.1,不是1,因为只保存了点印象,哈哈。
✨ 分享总结最重要
- 遇到问了赶紧记下来;
- 遇到花费很长时间才解决的“坑”,一定要记下来;
- 记录地方最好是下次能以下找到的,CSDN就不错,你说呢(我是不是做了个宣传),哈哈。
更多推荐
所有评论(0)