单元测试tkinter应用程序

时间:2017-02-17 10:13:42

标签: python python-2.7 tkinter python-unittest

我正在尝试为我编写的Tkinter应用程序实现单元测试(同时了解它们)。为此,我设法围绕应用程序的基本结构创建了一个非常简约的单元测试,如下所示(将一个Tkinter实例作为master传递):

classTest.py

#! /usr/bin/env python
from Tkinter import *

class App():
    def __init__(self,master):
        self.text = "foo"
        self.printy()

    def printy(self):
        print self.text
        return "test"

# Call the main app
if __name__ == "__main__":
    root = Tk()
    app = App(root)
    root.mainloop()

test.py

#! /usr/bin/env python
from Tkinter import *
import unittest
import classTest

class testTest(unittest.TestCase):
    def test(self):
        a = classTest.App(Tk())
        self.assertEqual(a.printy(),"test")

if __name__ == "__main__":
    unittest.main()

此测试返回它成功运行,但它确实打印foo两次。但是,当我尝试在我的整个应用程序上运行相同的概念时,它会在我班级的__init__上崩溃。

unitTest.py

#! /usr/bin/env python
import unittest
from Tkinter import *
import MassyTools

class readTest(unittest.TestCase):
    def test(self):
        a = MassyTools.App(Tk())
        self.assertEqual(a.readData("./tests/calibrated_IBD cohort sample H6-run 1_0_E24_1.xy")[0][0],1299.11)

if __name__ == "__main__":
    unittest.main()

运行此测试会因未定义root而崩溃(参见下面的错误)。

enter image description here

我一直在嘲弄这个blogpost,但我还没有真正掌握这个概念。下面是MassyTools.py文件的子集,包括有问题的self.toolbar行:

class App():

    def __init__(self, master):
        # The Canvas
        self.canvas = FigureCanvasTkAgg(self.fig, master=master)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, root)
        self.canvas.get_tk_widget().pack(fill=BOTH, expand=YES)
        self.canvas.draw()

因此,问题是我是否应该在unittest中以不同方式对其进行实例化,如果以这种方式调用或完全不同的话,修改应用程序以获得伪root。

1 个答案:

答案 0 :(得分:0)

我在应用程序中发现了我想要测试的问题,我在main中声明了root = Tk()。此root已作为App传递给master班级,但在该计划中,我调用了root,应该转到master。以下更改删除了最初的崩溃,我还调用了atexit,无需关闭应用程序(按this回答)。

修订申请:

class App():

    def __init__(self, master):

        # The Canvas
        self.canvas = FigureCanvasTkAgg(self.fig, master=master)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, master)
        self.canvas.get_tk_widget().pack(fill=BOTH, expand=YES)
        self.canvas.draw()

# Call the main app
if __name__ == "__main__":
    root = Tk()
    app = App(root)
    root.mainloop()

我调整了我的unittest.py代码,如下所示,现在我在物理关闭应用程序后完成了OK:

#! /usr/bin/env python
import unittest
from Tkinter import *
import MassyTools
import atexit

class readTest(unittest.TestCase):
    def test(self):
        self.assertEqual(a.readData("./tests/calibrated_IBD cohort sample H6-run 1_0_E24_1.xy")[0][0],1299.11)

if __name__ == "__main__":
    # Set up Tk(), instantiate the application and close it right away.
    root = Tk()
    a = MassyTools.App(root)
    atexit.register(root.mainloop)
    root.destroy()

    # Start the actual tests
    unittest.main(verbosity=2)