Unittest Tkinter文件对话框

时间:2013-06-14 17:34:47

标签: python unit-testing user-interface tkinter

问题

有没有办法让tkFileDialog选项自动运行unittest?以下是我的应用程序中tkinter的唯一用途:

root = Tkinter.Tk()
types = [('Comma Separated Values', '.csv'), ('All Files', '*')]
filename = tkFileDialog.askopenfilename(parent=root,
                                        filetypes=types)
root.destroy()

编辑:我没有提到代码的这一部分被困在我控制之外的类的方法调用中。

<小时/>

背景

我已经构建了一个本地应用程序,它在localhost上创建一个http服务器,并在Web浏览器中使用HTML / CSS / JS运行其GUI。由于浏览器的限制,我无法使用内置文件对话框,因此必须通过Python发送此请求。我想让它在内置Python 2.5的OSX上运行。我对Tcl/Tk不是很熟悉。

尝试#1

如果我可以访问底层小部件,我可以生成this question中的点击次数。但是,查看dialog source,在我看来第48-50行中的Tcl调用正在阻止。这是正确的假设吗?

尝试#2

我认为有可能通过Tcl直接使用root.tk.call命令。由于我在Python2,我认为基础Tcl是对tk_getOpenFile的单次调用。我是否必须确保Tcl解释器具有线程?是否有任何Tcl/Tk命令可以帮助我在这里?

尝试#3

我可以使用os.listdir等从头开始实现文件选择。(可能在与服务器来回通信的单独HTML页面中)。这会有点痛苦,希望可以避免。

<小时/>

解决方案

根据A. Rodas的回答,我想出了以下内容:

import tkFileDialog
old_dialog = tkFileDialog.askopenfilename
try:
    tkFileDialog.askopenfilename = lambda *args, **kw: filename

    # First test dialog cancelled
    filename = ''
    method_that_calls_tk()
    # run some assertions

    # Next test a valid file name with valid contents
    filename = self.VALID_FILENAME
    method_that_calls_tk()
    # run some assertions

    # Now test a valid file name with invalid contents
    filename = self.INVALID_CONTENTS_FILENAME
    method_that_calls_tk()
    # run some assertions

    # Now test an invalid file name
    filename = self.INVALID_FILENAME
    method_that_calls_tk()
    # run some assertions
finally:
    tkFileDialog.askopenfilename = old_dialog

2 个答案:

答案 0 :(得分:3)

Tkinter代码的单元测试不是一个简单的问题。例如,IDLE没有适当的测试套件,即使它是标准库的一部分。既然你提到这将是你的应用程序中唯一使用Tkinter的东西,我建议对这段代码的结果进行单元测试:filename的值。

例如,您可以测试.csv文件,另一个文件扩展名不正确。由于tkFileDialog返回空字符串(如果用户已关闭),因此请在filename = ''处添加测试。

import unittest

class TestFileDialog(unittest.TestCase):

    def test_dialog_closed(self):
        filename = ''
        # ...

    def test_incorrect_extension(self):
        filename = '/path/to/another/filetype'
        # ...

    def test_csv_extension(self):
        filename = '/path/to/correct/file.csv'
        # ...

答案 1 :(得分:1)

您可以仅将呼叫打补丁至tkinter: 修补tk.Tk(),因为大多数配置项会因为没有显示而出错。 还要修补文件对话框,以便您可以模拟返回值,并以期望的方式调用它。

@patch('your_module.tk.Tk')
def test_your_stuff(self, Tk)

    with @patch('your_module.tkFileDialog.askopenfilename') as file_dialog:
        expected = 'expected return value'
        assert expected = your_function_calling_file_dialog()

        file_dialog.assert_called_once_with(whatever, you, expect, it, to, be, called, with)