Unittest Tkinter 文件对话框 [英] Unittest Tkinter File Dialog
问题描述
有没有办法自动选择 tkFileDialog
以通过 unittest
运行它?以下是我的应用程序中 tkinter
的唯一使用:
Is there any way to automate a tkFileDialog
selection to run it through unittest
? The following is the only use of tkinter
in my application:
root = Tkinter.Tk()
types = [('Comma Separated Values', '.csv'), ('All Files', '*')]
filename = tkFileDialog.askopenfilename(parent=root,
filetypes=types)
root.destroy()
编辑:我没有提到这部分代码被困在我无法控制的类的方法调用中.
Edit: I didn't mention that this part of the code was trapped in a method call from a class outside my control.
我已经构建了一个本地应用程序,它在 localhost
上创建了一个 http 服务器,并在 Web 浏览器中使用 HTML/CSS/JS 运行其 GUI.由于浏览器限制,我无法使用内置文件对话框,因此必须通过 Python 发送此请求.我希望它在带有内置 Python 2.5 的 OSX 上运行.我对 Tcl/Tk
不是很熟悉.
I've built a local app that creates an http server on localhost
and runs its GUI with HTML/CSS/JS in a web browser. Because of browser restrictions, I can't use the built-in file dialog and so have to send this request through Python. I want this to run on a OSX with the built-in Python 2.5. I'm not very familiar with Tcl/Tk
.
如果我可以访问底层小部件,我可以像 this 那样生成点击问题.但是,查看 对话框源,它在我看来,第 48-50 行中的 Tcl
调用正在阻塞.这是一个正确的假设吗?
If I could get to the underlying widgets, I could generate the clicks like in this question. However, looking at the dialog source, it appears to me that the Tcl
call in lines 48-50 is blocking. Is this a correct assumption?
我认为可能有一种方法可以直接通过 root.tk.call
使用 Tcl
命令.由于我使用的是 Python2
,我认为底层的 Tcl
是对 tk_getOpenFile
的单个调用.我是否必须确保 Tcl
解释器是线程化的?是否有任何 Tcl/Tk
命令可以帮助我?
I thought there might be a way using Tcl
commands directly through root.tk.call
. Since I'm on Python2
, I think the underlying Tcl
is a single call to tk_getOpenFile
. Would I have to ensure the Tcl
interpreter is threaded? Is there any Tcl/Tk
command that can help me out here?
我可以使用 os.listdir
等从头开始实现文件选择(可能在与服务器来回通信的单独 HTML 页面中).这将不仅仅是一点点痛苦,但希望可以避免.
I could implement the file selection from scratch using os.listdir
etc. (Probably in a separate HTML page communicating back and forth with the server). It would be more than a little painful and hopefully avoidable.
根据下面 A. Rodas 的回答,我得出以下结论:
Based on A. Rodas's answer below, I came up with the following:
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
推荐答案
Tkinter 代码的单元测试不是一个简单的问题.例如,IDLE 没有合适的测试套件,即使它是标准库的一部分.由于您提到这将是您的应用程序中唯一使用 Tkinter 的地方,因此我建议对此代码的结果进行单元测试:filename
的值.
Unit testing of Tkinter code is not an easy issue. For instance, the IDLE does not have a proper test suite, even though it is part of the standard library. Since you mention that this is going to be the only use of Tkinter in your application, I'd suggest to make unit tests for the outcome of this code: the value of filename
.
例如,您可以对 .csv 文件进行一次测试,对不正确的文件扩展名进行另一次测试.由于 tkFileDialog
在用户关闭时返回一个空字符串,因此还要添加一个测试 where filename = ''
.
For instance, you can have a test for a .csv file, and another one for an incorrect file extension. Since tkFileDialog
returns an empty string if it is closed by the user, add also a test 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'
# ...
这篇关于Unittest Tkinter 文件对话框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!