测试 tkinter 应用程序 [英] Testing tkinter application

查看:110
本文介绍了测试 tkinter 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 python 3 和 tkinter 编写了一个小应用程序.测试每个小部件,尽管它们并不多,但感觉令人生畏,所以我想编写一些自动化测试来简化过程.我读了一些其他似乎与这个问题相关的问题,但没有一个符合我的需求.现在我正在以一种非常简单的方式进行测试 - 我为每个小部件调用命令并手动单击它以查看它是否有效.它确实让事情变快了一点,但我经常遇到一些问题 - 即即使使用库来模拟键盘点击(即 pynput),我也无法自动关闭弹出窗口(如 showinfo).是否有使用 tkinter 测试应用程序的有效方法?

I wrote a small application using python 3 and tkinter. Testing every widget, even though there are not many of them feels daunting so I wanted to write a couple of automated tests to simplify the process. I read some other question that seemed relevant to this problem but none fit my needs. Right now I'm doing the testing in a very simple manner - I invoke the command for every widget and manually click through it to see if it works. It does make things a bit faster, but I constantly run into some problems - i.e. I can't automatically close popup windows (like showinfo) even with using libraries to simulate keyboard clicks (namely pynput). Is there an efficient approach for testing applications using tkinter?

这是我现在使用的代码:

Here is the code I use right now:

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 提前安排键盘事件:

I don't know much about unittest but I found a workaround to close popup dialogs like showinfo during the tests. The idea is to use keyboard event to invoke the button of the dialog. But since the app is waiting for the user to close the popup dialog, we need to schedule in advance the keyboard event using 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 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆