什么是unit testingPython GUI应用程序的推荐方式?

我目前很愚蠢的尝试维护Python桌面应用程序的两个并行代码库,一个是使用PyGObject内省的GTK 3,一个是使用PyGTK的GTK 2.我主要工作在PyGObject分支,然后将端口转换到PyGTK分支。 由于这些实现之间的所有细微差别,我常常会忽略一些事情,并导致我错过和意外释放的破坏,只会被用户抓住。

我试图找出一个好方法来devise一些unit testing,最好是适合在两个代码库上运行。 这不是一个过于复杂的程序,(它本质上是一个图书馆pipe理工具,像iTunes一样):

- Main Window |- Toolbar with some buttons (add/edit/remove items, configure the program) | |- VPaned |--- Top HPaned |------ ListView (listing values by which a library of items can be filtered) |------ ListView (listing the contents of the library |--- Bottom HPaned |------ Image (displaying cover art for the currently selected item in the library) |------ TextView (displaying formatted text describing the currently selected item) - Edit dialog - Configuration dialog - About dialog 

我试图尽可能地从模型中分离视图。 这些项目中的每一个都是在自己的类中实现的(也就是从GTK类inheritance的类中)。 ListViews与从ListStoresinheritance的其他类相结合。 图书馆本身由不同的class级来处理。 但是,这些小部件之间需要进行互动。 例如,如果用户在filter视图中select特定项目,过滤库,然后从过滤结果中select一个项目,则文本视图必须显示正确的库项目的信息,由于翻译,这是半复杂的TreeModelFilter和原始ListStore之间的等等

那么,我问,为这样一个GUI应用程序编写健壮的unit testing的推荐方法是什么? 我已经看到,有一些这样的库,但主要的pygtk多年来没有更新,所以他们几乎肯定会因PyGObject内省而失败。 也许我没有足够的创造力去找出一个使用Python的unittest模块来完成这个工作的好方法,所以我愿意提供build议。

你确定要单元testingGUI吗? 你的复杂例子涉及多于一个单元,因此是一个集成testing。

如果你真的想unit testing,你应该能够实例化一个类提供模拟或存根的依赖关系,然后调用它的方法就像GUI框架将例如用户点击。 这可能很乏味,你必须确切地知道GUI框架如何将用户input分派给你的类。

我的build议是把更多的东西放在模型中。 对于你给定的例子,你可以创build一个FilterManager,抽象所有的filter/select/显示的东西在一个单一的方法后面。 然后unit testing它。

有一个很好的方法可以直接testingPyGTK函数和小部件,而不需要通过接受/function/集成testing框架,这些框架被遗忘。 我在这篇文章中了解到这一点, 这是相当自我解释。 但基本的想法是,你把你的小部件作为函数/类,你可以直接testing它们。 如果你需要处理callback等,我会在这里重现一个巧妙的技巧:

 import time import gtk # Stolen from Kiwi def refresh_gui(delay=0): while gtk.events_pending(): gtk.main_iteration_do(block=False) time.sleep(delay) 

正如在博客文章中提到的,这个代码是LGPL。 否则,只要不show()窗口或小部件,就可以testing所有你想要的东西,而且它们应该performance得像是真实的,因为从某种意义上说,它们是。 他们只是没有显示。

当然,您需要通过调用clicked()上的clicked()来模拟button和交互式小部件上的交互。 再次看到Ali Afshar在PyGTK中关于unit testing的优秀post 。

为了坚持Jürgen正确的主题,我对单元testing并不感兴趣,但对集成testing真的感兴趣,我也从freedesktop.org发现了这个框架: http : //ldtp.freedesktop.org/wiki/

它允许为启用辅助function的GUI应用程序(包括GTK,Qt,Swing等)自动执行各种testing。

您可以使用X11帧缓冲区:

 Xvfb :119 -screen 0 1024x768x16 & export DISPLAY=:119 ... run your tests 

请确保不要inputgtk.main() ,因为这将等待鼠标或键盘input。 你可以使用这个模式让gtk处理所有的事件:

 def refresh_gui(): while gtk.events_pending(): gtk.main_iteration_do(block=False) 

AFAIK你看不到你的应用程序,但你可以testing你的callback。