Каков рекомендуемый способ тестирования приложений Python GUI? - PullRequest
38 голосов
/ 26 августа 2011

В настоящее время я достаточно глуп, чтобы попытаться сохранить две параллельные базы кода для настольного приложения Python, одно с использованием самоанализа PyGObject для GTK 3, а другое с использованием PyGTK для 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 

Я пытался максимально отделить виды от моделей. Каждый из этих элементов реализован в своем собственном классе (ну, в классах, которые наследуются от перечисленных классов GTK). ListViews связаны с другими классами, которые наследуются от ListStores. Сама библиотека обрабатывается другим классом. Тем не менее, есть взаимодействия между виджетами, которые необходимо протестировать. Например, если пользователь выбирает конкретный элемент в представлении фильтра, фильтрует библиотеку, а затем выбирает элемент из отфильтрованных результатов, в текстовом представлении должна отображаться информация для правильной записи библиотеки, которая является полусложной из-за перевода разрывы между TreeModelFilter и оригинальным ListStore и т. д. и т. д.

Итак, я спрашиваю, каков рекомендуемый способ написания надежных модульных тестов для такого приложения с графическим интерфейсом? Я видел, что для этого есть несколько библиотек, но основные для pygtk не обновлялись годами, поэтому они почти наверняка потерпят неудачу с самоанализом PyGObject. Возможно, я недостаточно изобретателен, чтобы найти хороший способ сделать это с помощью модуля Python unittest, поэтому я открыт для предложений.

Ответы [ 4 ]

6 голосов
/ 01 сентября 2011

Вы уверены, что хотите устройство проверить графический интерфейс? Ваш пример сложности включает более 1 единицы и, следовательно, является интеграционным тестом.

Если вы действительно хотите выполнить модульное тестирование, вы должны иметь возможность создавать отдельный класс, предоставляющий макеты или заглушки для его зависимостей, а затем вызывать методы для него, как, например, для среды GUI. пользовательский клик. Это может быть утомительно, и вы должны точно знать, как платформа GUI отправляет пользовательский ввод вашим классам.

Мой совет - помещать еще больше вещей в модели. Для вашего данного примера вы можете создать FilterManager, который абстрагирует весь фильтр / выбор / отображение материала за одним методом. Затем выполните его модульное тестирование.

5 голосов
/ 18 января 2013

Существует отличный способ напрямую протестировать функции и виджеты 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)

Как упоминается в сообщении в блоге, этот код называется LGPL.В противном случае, когда вы думаете об этом, пока вы не show() окон или виджетов, вы можете проверить их все, что вы хотите, и они должны вести себя так, как будто они реальны, потому что, в некотором смысле, они есть.Они просто не отображаются.

Конечно, вам нужно смоделировать взаимодействие с кнопками и интерактивными виджетами, например, вызвав clicked() для кнопки.Смотрите снова Отличный пост Али Афшара о модульном тестировании в PyGTK .

2 голосов
/ 26 февраля 2012

Придерживаясь темы, в которой Юрген был прав: я не заинтересован в модульном тестировании, но на самом деле заинтересован в интеграционном тестировании, я также нашел эту платформу на freedesktop.org: http://ldtp.freedesktop.org/wiki/

Позволяет автоматизировать различные тесты для приложений с графическим интерфейсом с поддержкой специальных возможностей (включая GTK, Qt, Swing и т. Д.).

0 голосов
/ 05 мая 2014

Вы можете использовать кадровый буфер X11:

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

Обязательно не вводите gtk.main(), так как это будет ожидать ввода с клавиатуры или мыши. Вы можете использовать этот шаблон, чтобы gtk обрабатывал все события:

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

AFAIK, вы не можете видеть свое приложение, но вы можете проверить свои обратные вызовы.

...