【问题标题】:unittesting a tkinter application对 tkinter 应用程序进行单元测试
【发布时间】:2017-02-17 10:13:42
【问题描述】:

我正在尝试为我编写的 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 没有定义而崩溃(见下面的错误)。

根据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()

因此,问题是我是否应该在单元测试中以不同的方式实例化它,如果以这种方式或完全以其他方式调用,则修改应用程序以具有假根。

【问题讨论】:

标签: python python-2.7 tkinter python-unittest


【解决方案1】:

我在要测试的应用程序中发现了问题,我在主文件中声明了root = Tk()。这个rootmaster 的形式传递给App 类,但在程序中我调用了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)

【讨论】:

  • 对于未来的流浪者:readTest 类还应该包含实例的创建 (a = MassyTools.App(Tk())。否则,readData() 会在未知对象(a) 上调用。
猜你喜欢
  • 2012-03-21
  • 2011-03-25
  • 1970-01-01
  • 1970-01-01
  • 2019-01-01
  • 2014-06-03
  • 2010-09-11
  • 1970-01-01
  • 2016-04-04
相关资源
最近更新 更多