2014-03-28 51 views
2

我得到了一個任務來爲devassistant編寫一些單元測試(一個幫助程序可以幫助您設置開發環境)。它是用Python編寫的,提供了用pygobject3實現的圖形用戶界面。已經有單元測試,使用pytest。 我寫了一些基本的測試,它的工作是這樣的:使用pygobject3測試GUI應用程序pytest

  • 創建主窗口(如應用程序是由人正常執行),但不叫Gt​​k.main() - 使主窗口榮獲」 T顯示了
  • 模擬與GUI交互(點擊按鈕,UN /武術的思考複選框等),或直接,如果按預期的東西調用它們的回調
  • 檢查(調用斷言)

實際的問題是,當gui測試通過並且之後有更多測試時gui測試,在進行下面的測試時,一個空白窗口(只有一個標題)出現並且pytest凍結(空窗口沒有反應並且不能關閉),所以我必須殺死它。如果我將gui測試「移動」到最後一個位置,它們將正常工作。

重現步驟:

  • 克隆我的倉庫https://github.com/jkoncick/devassistant - 實際提交加入測試是https://github.com/jkoncick/devassistant/commit/e4296fcf7e1393a1140f3205304e54b9e8c62375
  • (安裝所有需要的Python包 - 他們是在需求文件)
  • 招test_gui .py文件到父目錄中 - 這樣gui測試不會被最後執行,但是在它們之後有一些測試
  • in devassistant/gui/main_window.py刪除第81行與「self.main_win.hide()」
  • 用「./setup.py test」運行測試
  • 做完gui測試後(它們應該通過),一個空的窗口顯示出來,pytest凍結。如果你不刪除行「self.main_win.hide()」,窗口將不會顯示,但pytest無論如何凍結

我真的很無奈。把gui測試移到最後工作,但這是一個解決方法,我不能認爲它會在任何地方工作。我無法設法「關閉」或「銷燬」主窗口,以防止它出現並中斷測試。 我嘗試了這些,但沒有工作:

app.main_win.destroy() app.main_win.emit('delete-event', None) Gtk.main_quit()

你請有任何想法如何解決呢?

回答

1

你總是需要運行一個Gtk主循環來讓小部件正常工作。如果你這樣做,你可以從信號回調/事件中退出主循環Gtk.main_quit()。如果你不這樣做,你最終會得到一個凍結的窗口,因爲你沒有一個mainloop來處理繪製小部件的內容。


似乎工作,如果你上次運行它,是由./setup.py test引起的終止,因此採取全過程的事實 - 包括GTK窗口 - 下來。

2

那麼,我終於解決了這個問題。而且它在Gtk中實際上不是問題。我對這是由於Gtk_main()沒有正確退出或main_window沒有正確銷燬造成的偏見以及等待事件(如前面的回答中所述)而產生偏見,但這不是真正的問題,現在它可以正常工作。

問題出在run_window.py> RunLoggingHandler> emit()> Gdk.threads_enter()< - 它在這裏凍結。 logger.py中的'logger'變量是全局變量,並且在RunLoggingHandler中添加了RunLoggingHandler(run_window.py中的「logger.addHandler(self.tlh)」)時,它保留在此處,並且在以下測試中調用emit()時,它卡在這裏。通過測試後清除記錄處理程序固定它:

from devassistant.logger import logger

def teardown_method(self, method): logger.handlers = []