Unittest Tkinter文件对话框

Fel*_*ipe 5 python user-interface unit-testing tkinter

有什么方法可以自动执行tkFileDialog选择unittest吗?以下是tkinter我的应用程序中的唯一用法:

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

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


背景

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

尝试#1

如果我可以使用基础小部件,则可以生成此问题中的点击。但是,从对话框源看,在我看来,第Tcl48-50行的呼叫正在阻塞。这是正确的假设吗?

尝试#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
Run Code Online (Sandbox Code Playgroud)

A. *_*das 4

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

例如,您可以对 .csv 文件进行测试,并针对不正确的文件扩展名进行另一次测试。由于tkFileDialog如果用户关闭它会返回一个空字符串,因此还添加一个测试 where 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'
        # ...
Run Code Online (Sandbox Code Playgroud)