【问题标题】:Testing tkinter application测试 tkinter 应用程序
【发布时间】:2018-05-23 07:48:44
【问题描述】:

我使用 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()

【问题讨论】:

  • 你真的要测试吗?当您致电showinfo 时,您不相信tkinter 会做正确的事吗?

标签: python testing tkinter


【解决方案1】:

我对 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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-13
    • 2010-11-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多