我想进入 GUI 自动化领域,以便在我自己的程序上运行测试。我想要测试的程序是用 Python 编写的,并使用 Tkinter 作为 GUI。测试代码不一定必须是Python,CPP 也可以。我做了一些研究,我已经面临一个问题。
根据我的研究,我发现“Windows 应用程序驱动程序”是测试 GUI 的免费方法。还有“WinAppDriver UI Recorder”,使用起来似乎很方便。此外,(在我的例子中)“C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86”中的“Inspect.exe”程序对于获取有关 GUI 元素的信息很有用。
假设我有一个像这样的小Python代码(仅用于测试):
from Tkinter import *
import ttk
class Test():
def __init__(self):
self.root = Tk()
self.root.geometry("250x100")
self.text = StringVar()
self.text.set("Original Text")
self.buttonA = Button(self.root, textvariable=self.text)
self.buttonA.configure(text="test")
self.buttonB = Button(self.root,
text="Click to change text",
command=self.changeText
)
self.buttonA.pack(side=LEFT)
self.buttonB.pack(side=RIGHT)
self.root.mainloop()
def changeText(self):
self.text.set("Updated Text")
app=Test()
运行代码并检查时buttonB
with Inspect.exe
我得到的结果是“”(空)。有什么方法可以将该名称更改为信息性且有用的名称,例如计算器示例中的“7”按钮的名称是“七”。然后在测试器中使用它,如下所示:
self.driver.find_element_by_name("Seven").click()
应该是这样的:
self.driver.find_element_by_name("buttonB").click()
例如我的例子。
您可以将 tkinter 小部件命名为:
self.buttonA = Button(self.root, textvariable=self.text,name = 'buttonA')
if WinAppDriver
无法找到以这种方式命名的 tkinter 小部件。您可以修改代码以模仿 UI 自动化框架的方式调用按钮(并“保留”其他 UI 小部件):
我修改了您的示例以展示如何做到这一点
from Tkinter import *
import ttk
def _widgets_by_name(parent,name,widgets):
if not parent.winfo_children():
if name == parent.winfo_name() :
widgets.append(parent)
else:
for child in parent.winfo_children():
_widgets_by_name(child,name,widgets)
def find_widget_by_name(parent,name):
''' ui automation function that can find a widget in an application/hierarchy of widgets by its name '''
widgets = []
_widgets_by_name(parent,name,widgets)
if len(widgets) == 0:
raise Exception(f'no widget named {name} found')
elif len(widgets) >1:
raise Exception(f'multiple widget named {name} found')
return (widgets[0])
class Test():
def __init__(self):
self.root = Tk()
self.root.geometry("250x100")
self.text = StringVar()
self.text.set("Original Text")
self.buttonA = Button(self.root, textvariable=self.text,name = 'button-a')
self.buttonA.configure(text="test")
self.buttonB = Button(self.root,
text="Click to change text",
command=self.changeText,
name = 'button-b'
)
self.buttonA.pack(side=LEFT)
self.buttonB.pack(side=RIGHT)
# self.root.mainloop() do not start the main loop for testing purpose
# can still be started outside of __init__ for normal operation
def changeText(self):
self.text.set("Updated Text")
app=Test()
# test the app step by step
# find one of the buttons and invoke it
find_widget_by_name(app.root,'button-b').invoke()
app.root.update() # replace the app mainloop: run the UI refresh once.
assert app.text.get() == "Updated Text"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)