news 2026/6/24 2:23:47

第七:PC端自动化测试实战教程-pywinauto等待方法大集合

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第七:PC端自动化测试实战教程-pywinauto等待方法大集合

一.简介

1.在上一篇中在start()后,加入适当的等待时间(如time.sleep()),让应用程序有足够的时间初始化窗口和UI元素1.1.之前在做web和app的ui自动化过程中,常用到等待机制,那PC端自动化有这个方法吗?1.2.答案是肯定的,python这么强大,肯定是有方法的
2.PC端自动化是如何等待的
2.1.应用程序行为通常不稳定,脚本需要等待,直到出现新窗口或关闭/隐藏现有窗口2.2.pywinauto可以隐式地(默认超时)灵活地等待对话框初始化,或者明确地使用专用方法/函数来帮助您使代码更容易和更可靠

二.等待机制

1.分为三个大类(仅是自己的观点):窗口/元素等待、应用程序等待和全局等待时间Timings
2.窗口/元素等待
2.1.Pywinauto是用于自动化Windows GUI应用程序的模块,提供了两种等待函数:wait()和wait_not()
2.1.1.wait():等待窗口达到指定状态2.1.2.wait_not():等待窗口不处于某种状态
2.2.wait()
2.2.1.wait()函数用于等待指定窗口达到指定状态,例如“最大化”或“最小化”状态2.2.2.可以通过设置超时时间和重试间隔来控制等待的时间和频率
2.2.3.wait()的源码
defwait(self,wait_for,timeout=None,retry_interval=None):""" Wait for the window to be in a particular state/states. :param wait_for: The state to wait for the window to be in. It can be any of the following states, also you may combine the states by space key. * 'exists' means that the window is a valid handle * 'visible' means that the window is not hidden * 'enabled' means that the window is not disabled * 'ready' means that the window is visible and enabled * 'active' means that the window is active :param timeout: Raise an :func:`pywinauto.timings.TimeoutError` if the window is not in the appropriate state after this number of seconds. Default: :py:attr:`pywinauto.timings.Timings.window_find_timeout`. :param retry_interval: How long to sleep between each retry. Default: :py:attr:`pywinauto.timings.Timings.window_find_retry`. An example to wait until the dialog exists, is ready, enabled and visible: :: self.Dlg.wait("exists enabled visible ready") .. seealso:: :func:`WindowSpecification.wait_not()` :func:`pywinauto.timings.TimeoutError` """check_method_names,timeout,retry_interval=self.__parse_wait_args(wait_for,timeout,retry_interval)wait_until(timeout,retry_interval,lambda:self.__check_all_conditions(check_method_names,retry_interval))# Return the wrapped controlreturnself.wrapper_object()
2.2.4.参数说明
2.2.4.1.wait_for可选参数
2.2.4.1.1.‘exists’:表示窗口存在,是一个有效的句柄2.2.4.1.2.‘visible’:表示窗口可见(不隐藏)2.2.4.1.3.‘enabled’:表示窗口未被禁用2.2.4.1.4.‘ready’:表示窗口可见且已启用2.2.4.1.5.‘active’:表示窗口处于活动状态
2.2.4.2.timeout:表示超时时间2.2.4.3.retry_interval:表示重试间隔
2.3.wait_not()
2.3.1.其实和上面都是一样的,一种等待处于某种状态,一种等待不处于某种状态2.3.2.wait_not()函数则用于等待指定窗口不处于某种状态,例如“关闭”状态2.3.3.它的使用方式与wait()函数类似,但参数和返回值有所不同
2.3.4.wait_not()的源码
defwait_not(self,wait_for_not,timeout=None,retry_interval=None):""" Wait for the window to not be in a particular state/states. :param wait_for_not: The state to wait for the window to not be in. It can be any of the following states, also you may combine the states by space key. * 'exists' means that the window is a valid handle * 'visible' means that the window is not hidden * 'enabled' means that the window is not disabled * 'ready' means that the window is visible and enabled * 'active' means that the window is active :param timeout: Raise an :func:`pywinauto.timings.TimeoutError` if the window is sill in the state after this number of seconds. Default: :py:attr:`pywinauto.timings.Timings.window_find_timeout`. :param retry_interval: How long to sleep between each retry. Default: :py:attr:`pywinauto.timings.Timings.window_find_retry`. An example to wait until the dialog is not ready, enabled or visible: :: self.Dlg.wait_not("enabled visible ready") .. seealso:: :func:`WindowSpecification.wait()` :func:`pywinauto.timings.TimeoutError` """check_method_names,timeout,retry_interval=\ self.__parse_wait_args(wait_for_not,timeout,retry_interval)wait_until(timeout,retry_interval,lambda:notself.__check_all_conditions(check_method_names,retry_interval))# None return value, since we are waiting for a `negative` state of the control.# Expect that you will have nothing to do with the window closed, disabled, etc.
2.3.5.参数说明
2.3.5.1.wait_not可选参数
2.3.5.1.1.‘exists’:表示窗口存在,是一个有效的句柄2.3.5.1.2.‘visible’:表示窗口可见(不隐藏)2.3.5.1.3.‘enabled’:表示窗口未被禁用2.3.5.1.4.‘ready’:表示窗口可见且已启用2.3.5.1.5.‘active’:表示窗口处于活动状态
2.3.5.2.timeout:表示超时时间2.3.5.3.retry_interval:表示重试间隔

三.应用程序等待

1.应用程序等待只是针对应用程序的2.注意:此方法仅适用于整个应用程序进程,不适用于窗口/元素
3.CPU使用率
3.1.wait_cpu_usage_lower()
3.1.1.wait_cpu_usage_lower(),等待该进程的cup的使用率低于某个阀值
3.1.2.wait_cpu_usage_lower()的源码
defwait_cpu_usage_lower(self,threshold=2.5,timeout=None,usage_interval=None):"""Wait until process CPU usage percentage is less than the specified threshold"""ifusage_intervalisNone:usage_interval=Timings.cpu_usage_intervaliftimeoutisNone:timeout=Timings.cpu_usage_wait_timeout start_time=timings.timestamp()whileself.cpu_usage(usage_interval)>threshold:iftimings.timestamp()-start_time>timeout:raiseRuntimeError('Waiting CPU load <= {}% timed out!'.format(threshold))returnself
3.1.3.参数说明
3.1.3.1.threshold:表示该进程cup占用率3.1.3.2.timeout:表示超时时间3.1.3.3.retry_interval:表示重试间隔
4.进程
4.1.wait_for_process_exit()
4.1.1.wait_for_process_exit(),等待进程退出,直到超时
4.1.2.wait_for_process_exit()的源码
defwait_for_process_exit(self,timeout=None,retry_interval=None):""" Waits for process to exit until timeout reaches Raises TimeoutError exception if timeout was reached """iftimeoutisNone:timeout=Timings.app_exit_timeoutifretry_intervalisNone:retry_interval=Timings.app_exit_retry wait_until(timeout,retry_interval,self.is_process_running,value=False)
4.1.3.参数说明
4.1.3.1.timeout:表示超时时间4.1.3.2.retry_interval:表示重试间隔

四.timings

1.pywinauto 查找窗口和控件时会有超时时间与轮询机制,可以通过timings 模块设置全局等待时间
2.timings模块
2.1.timings 模块有三个模式可以设置
2.1.1.timings.Timings.fast():快速模式2.1.2.timings.Timings.defaults():默认模式2.1.3.timings.Timings.slow():慢速模式
2.2.以下是可以调整的各个时序设置
window_find_timeout(default5)window_find_retry(default.09)app_start_timeout(default10)app_start_retry(default.90)app_connect_timeout(default5.)app_connect_retry(default.1)cpu_usage_interval(default.5)cpu_usage_wait_timeout(default20)exists_timeout(default.5)exists_retry(default.3)after_click_wait(default.09)after_clickinput_wait(default.09)after_menu_wait(default.1)after_sendkeys_key_wait(default.01)after_button_click_wait(default0)before_closeclick_wait(default.1)closeclick_retry(default.05)closeclick_dialog_close_wait(default2)after_closeclick_wait(default.2)after_windowclose_timeout(default2)after_windowclose_retry(default.5)after_setfocus_wait(default.06)setfocus_timeout(default2)setfocus_retry(default.1)after_setcursorpos_wait(default.01)sendmessagetimeout_timeout(default.01)after_tabselect_wait(default.05)after_listviewselect_wait(default.01)after_listviewcheck_wait default(.001)listviewitemcontrol_timeout default(1.5)after_treeviewselect_wait default(.1)after_toobarpressbutton_wait default(.01)after_updownchange_wait default(.1)after_movewindow_wait default(0)after_buttoncheck_wait default(0)after_comboboxselect_wait default(.001)after_listboxselect_wait default(0)after_listboxfocuschange_wait default(0)after_editsetedittext_wait default(0)after_editselect_wait default(.02)drag_n_drop_move_mouse_wait default(.1)before_drag_wait default(.2)before_drop_wait default(.1)after_drag_n_drop_wait default(.1)scroll_step_wait default(.1)
3.设置模式
3.1.想让操作更快一点,可以设置快速模式3.2.想让操作更慢一点,可以设置慢速模式3.3.设置方法还是比较简单的,导入模块后,一行代码即可搞定
3.4.快速模式:快速模式的设置方式
frompywinauto.applicationimportApplicationfrom pywinauto.timingsimportTimings Timings.fast()
3.5.慢速模式:慢速模式的设置方式
frompywinauto.applicationimportApplicationfrom pywinauto.timingsimportTimings Timings.slow()

五.趁热打铁

1.测试场景
1.1.测试场景:启动电脑的notepadd++编辑器这款软件,然后输入内容:x京x哥,最后点击notepadd++编辑器左上角的【文件(F)->另存为(A)...】,然后等待另存为的窗口出现即可!
2.代码设计
frompywinautoimportApplication# 通过窗口打开app=Application('uia').start("D:/software/Notepad/Notepad++/notepad++.exe")app=Application('uia').connect(class_name="Notepad++")# win = app['窗口的标题']win=app['新文件1 - Notepad++']#输入内容:北京-宏哥win.type_keys("北京-宏哥")win.child_window(title="应用程序",auto_id="MenuBar",control_type="MenuBar")# 文件-另存为win.menu_select('文件(F) -> 另存为(A)...')# 等待另存为窗口出现win.child_window(title="另存为",control_type="Window").wait('ready',timeout=5)
3.运行代码,右键Run'Test',就可以看到控制台输出

4.运行代码后电脑端的动作(启动记事本)

六.总结

1.基础窗口状态等待方法‌
1.1.wait()方法‌支持等待窗口达到特定状态
1.1.1.'exists':窗口句柄有效1.1.2.'visible':窗口未隐藏1.1.3.'enabled':窗口未被禁用1.1.4.'ready':窗口可见且已启用1.1.5.'active':窗口处于活动状态
1.2.参数说明
1.2.1.timeout:超时时间(默认由全局配置决定)1.2.2.retry_interval:重试间隔(默认由全局配置决定)‌
2.高级场景等待方法‌
2.1.wait_cpu_usage_lower()‌:适用于多线程应用中延迟初始化的场景,通过监控进程的CPU使用率判断任务是否完成(如后台计算未结束前保持等待)‌
2.2.wait_until_passes()‌:持续执行指定操作直至成功或超时,特别适用于动态加载的控件或异步操作后的状态检测‌
3.全局等待时间配置
3.1.通过 timings 模块设置默认超时和轮询间隔
3.1.1.Timings.Defaults.timeout:全局超时时间(默认30秒)3.1.2.Timings.Defaults.retry_interval:全局重试间隔(默认0.5秒)
4.使用建议‌
4.1.优先使用内置等待机制‌(如 wait()和 wait_until_passes()),避免依赖 time.sleep(),以提高代码稳定性和执行效率‌4.2.对于复杂界面,结合 print_control_identifiers()输出控件信息以辅助定位目标元素‌
5.注:以上方法需根据具体场景选择,合理设置超时参数可避免因界面响应延迟导致的自动化失败
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/24 2:22:08

github克隆项目加速

例如我要克隆 https://github.com/comfyanonymous/ComfyUI.git直接克隆有点慢&#xff0c;可以在前面加 https://gitclone.com &#xff0c;如下git clone https://gitclone.com/github.com/comfyanonymous/ComfyUI.git

作者头像 李华
网站建设 2026/6/24 2:21:21

别再无脑 Vibe Coding 了,AI 写出来的 App 可能正在裸奔

过去一年,Vibe Coding 几乎成了 AI 编程圈最性感的词。 你不用会写代码,只要对 AI 说:“帮我做一个记账 App”“帮我做一个客户管理系统”“帮我做一个打卡小程序”,AI 就能一路生成页面、数据库、接口,甚至告诉你怎么部署上线。 这件事当然很酷。它把软件开发的门槛打下…

作者头像 李华
网站建设 2026/6/24 2:15:15

NSK PFT3205-5 滚珠丝杠技术解析

型号 PFT3205-5 属于 NSK 的管循环式滚珠丝杠系列。与您之前查询的轻预紧双列品&#xff08;PFT3205-3&#xff0c;有效圈数 1.5 圈 2 列&#xff0c;刚度 296 N/m&#xff09;相比&#xff0c;该型号将内部受力回路进一步加长升级为 “2.5 圈 2 列” 的大跨度双列构造。 | 编…

作者头像 李华
网站建设 2026/6/24 2:10:20

小程序商城做的比较好的品牌有哪些?要看是否适合当前经营节奏

小程序商城和普通展示页不太一样&#xff0c;它不是搭完就结束&#xff0c;而是会持续牵涉商品管理、订单处理、活动配置、页面调整、会员运营和复购节奏。前期看起来只是选一个搭建品牌&#xff0c;后面真正比出来的&#xff0c;往往是长期经营里的顺手程度。同样是做商城&…

作者头像 李华
网站建设 2026/6/24 2:08:06

DDoS防护选型实测:从带宽、计费、防御速度,看懂怎么选最值

关键要点2026 全球 DDoS 单次攻击峰值突破 8.31Tbps&#xff08;NETSCOUT《Threat Intelligence Report 2026》&#xff09;国内云抗 DDoS 市面主流方案半数以上仍按清洗带宽超额阶梯计费&#xff0c;"防得住付不起"成 2026 选型首要痛点2026 短时脉冲式攻击占比从 2…

作者头像 李华