单元测试Python GUI应用程序的推荐方法是什么?

38 python user-interface unit-testing pygtk pygobject

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

我试图找出一种设计一些单元测试的好方法,这些单元测试最好适合在两个代码库上运行.这不是一个过于复杂的程序,(它本质上是一个图书馆管理工具,想像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 
Run Code Online (Sandbox Code Playgroud)

我试图尽可能地将模型与模型分开.这些项中的每一个都在它自己的类中实现(好吧,在从列出的GTK类继承的类中).ListViews与从ListStores继承的其他类耦合.图书馆本身由不同的班级处理.尽管如此,需要测试的小部件之间存在交互.例如,如果用户在过滤器视图中选择特定项目,过滤库,然后从过滤结果中选择一个项目,则文本视图必须显示正确库条目的信息,这是因为翻译而半复杂在TreeModelFilter和原始ListStore之间等等.

所以,我想问一下,为这样的GUI应用程序编写健壮的单元测试的推荐方法是什么?我已经看到有一些这样的库,但pygtk的主要库已经多年没有更新,因此它们几乎肯定会因PyGObject内省而失败.也许我没有足够的创造力来找出使用Python unittest模块做到这一点的好方法,所以我愿意接受建议.

Jür*_*bel 6

您确定要对GUI 进行单元测试吗?您的复杂性示例涉及超过1个单元,因此是集成测试.

如果你真的想进行单元测试,那么你应该能够实例化一个为其依赖项提供模拟或存根的类,然后在GUI框架上调用方法,例如用户点击.这可能很乏味,您必须确切知道GUI框架如何将用户输入分派给您的类.

我的建议是在模型中加入更多东西.对于您给出的示例,您可以创建一个FilterManager,它抽象出单个方法后面的所有过滤器/选择/显示内容.然后单元测试它.


ana*_*cat 5

有一种很好的方法可以直接测试PyGTK函数和小部件,而无需通过接受/功能/集成测试框架,这些框架可能会被遗忘.我在这篇文章中了解到这一点,是相当自我解释的.但基本思想是将小部件视为函数/类,并且可以直接测试它们.如果你需要处理回调等等,我会在这里重现一个巧妙的技巧:

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)
Run Code Online (Sandbox Code Playgroud)

正如博客文章中提到的,这段代码是LGPL.否则,当你想到它时,只要你没有show()窗口或小部件,就可以测试它们你想要的所有东西,它们应该表现得好像它们是真实的,因为在某种程度上它们是真的.他们只是没有显示.

当然,您需要通过调用clicked()按钮来自己模拟按钮和交互式小部件上的交互.再看看Ali Afshar在PyGTK中关于单元测试的优秀帖子.