有没有办法让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
不是很熟悉。
如果我可以访问底层小部件,我可以生成this question中的点击次数。但是,查看dialog source,在我看来第48-50行中的Tcl
调用正在阻止。这是正确的假设吗?
我认为有可能通过Tcl
直接使用root.tk.call
命令。由于我在Python2
,我认为基础Tcl
是对tk_getOpenFile
的单次调用。我是否必须确保Tcl
解释器具有线程?是否有任何Tcl/Tk
命令可以帮助我在这里?
我可以使用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
答案 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)