Я написал небольшое приложение, используя python 3 и tkinter. Тестирование каждого виджета, даже если их не так много, кажется сложной задачей, поэтому я хотел написать пару автоматических тестов, чтобы упростить процесс. Я прочитал еще один вопрос, который казался относящимся к этой проблеме, но не соответствовал моим потребностям. Прямо сейчас я провожу тестирование очень просто - я вызываю команду для каждого виджета и вручную щелкаю по нему, чтобы проверить, работает ли он. Это действительно немного ускоряет работу, но я постоянно сталкиваюсь с некоторыми проблемами, например, я не могу автоматически закрывать всплывающие окна (например, showinfo) даже с использованием библиотек для имитации щелчков клавиатуры (а именно pynput). Есть ли эффективный подход к тестированию приложений с использованием 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()






Я мало что знаю о unittest, но я нашел обходной путь, чтобы закрыть всплывающие диалоговые окна, такие как showinfo, во время тестов. Идея состоит в том, чтобы использовать событие клавиатуры для вызова кнопки диалогового окна. Но поскольку приложение ожидает, пока пользователь закроет всплывающее диалоговое окно, нам нужно заранее запланировать событие клавиатуры с помощью after:
self.root.after(100, self.root.event_generate('<Return>'))
v.button.invoke()
Полный пример
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()
Вы действительно хотите это проверить? Разве вы не доверяете
tkinter, чтобы поступить правильно, когда вы звоните вshowinfo?