Sur*_*ouf 2 python testing tkinter
我使用 python 3 和 tkinter 编写了一个小应用程序。测试每个小部件,尽管它们并不多,但感觉令人生畏,所以我想编写一些自动化测试来简化过程。我读了一些其他似乎与这个问题相关的问题,但没有一个符合我的需求。现在我正在以一种非常简单的方式进行测试 - 我为每个小部件调用命令并手动单击它以查看它是否有效。它确实让事情变快了一点,但我经常遇到一些问题 - 即即使使用库来模拟键盘点击(即 pynput),我也无法自动关闭弹出窗口(如 showinfo)。是否有使用 tkinter 测试应用程序的有效方法?
这是我现在使用的代码:
import tkinter as tkinter
import unittest
from mygui import MyGUI
class TKinterTestCase(unittest.TestCase):
def setUp(self):
self.root = tkinter.Tk()
def tearDown(self):
if self.root:
self.root.destroy()
def test_enter(self):
v = MyGUI(self.root)
v.info_button.invoke()
v.close_button.invoke()
v.btnOut.invoke()
if __name__ == "__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)
我对 unittest 了解不多,但我找到了一种解决方法,可以在测试期间关闭 showinfo 等弹出对话框。这个想法是使用键盘事件来调用对话框的按钮。但是由于应用程序正在等待用户关闭弹出对话框,我们需要使用after以下方法提前安排键盘事件:
self.root.after(100, self.root.event_generate('<Return>'))
v.button.invoke()
Run Code Online (Sandbox Code Playgroud)
完整示例
import tkinter
from tkinter import messagebox
import unittest
class MyGUI(tkinter.Frame):
def __init__(self, master, **kw):
tkinter.Frame.__init__(self, master, **kw)
self.info_button = tkinter.Button(self, command=self.info_cmd, text='Info')
self.info_button.pack()
self.quit_button = tkinter.Button(self, command=self.quit_cmd, text='Quit')
self.quit_button.pack()
def info_cmd(self):
messagebox.showinfo('Info', master=self)
def quit_cmd(self):
confirm = messagebox.askokcancel('Quit?', master=self)
if confirm:
self.destroy()
class TKinterTestCase(unittest.TestCase):
def setUp(self):
self.root = tkinter.Tk()
self.root.bind('<Key>', lambda e: print(self.root, e.keysym))
def tearDown(self):
if self.root:
self.root.destroy()
def test_enter(self):
v = MyGUI(self.root)
v.pack()
self.root.update_idletasks()
# info
v.after(100, lambda: self.root.event_generate('<Return>'))
v.info_button.invoke()
# quit
def cancel():
self.root.event_generate('<Tab>')
self.root.event_generate('<Return>')
v.after(100, cancel)
v.quit_button.invoke()
self.assertTrue(v.winfo_ismapped())
v.after(100, lambda: self.root.event_generate('<Return>'))
v.quit_button.invoke()
with self.assertRaises(tkinter.TclError):
v.winfo_ismapped()
if __name__ == "__main__":
unittest.main()
Run Code Online (Sandbox Code Playgroud)