2016-11-08 3 views
1

У меня есть диалог wxpython, который вызывает исключение TypeError при нажатии кнопки OK. Я хотел бы проверить возникновение исключения с unittest, но тест не работает должным образом. Результат показывает, что исключение возбуждено. Во всяком случае UnitTest уведомляет о том, что тест не пройден:unittest: метод события wxpython вызывает исключение, но assertRaises не обнаруживает его

"C:\Program Files (x86)\Python\python.exe" test.py 
Traceback (most recent call last): 
    File "test.py", line 22, in on_ok 
    raise TypeError('TypeError raised') 
TypeError: TypeError raised 
F 
====================================================================== 
FAIL: test_should_raise (__main__.CDlgTest) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "test.py", line 34, in test_should_raise 
    self._dut.m_button_ok.GetEventHandler().ProcessEvent(event) 
AssertionError: TypeError not raised 

---------------------------------------------------------------------- 
Ran 1 test in 0.005s 

FAILED (failures=1) 

Вот сокращенный пример моего кода:

import unittest 
import wx 

class CDlgBase (wx.Dialog): 
    """The UI""" 
    def __init__(self, parent): 
     wx.Dialog.__init__ (self, parent) 
     bSizerTest = wx.BoxSizer(wx.VERTICAL) 
     self.m_button_ok = wx.Button(self, wx.ID_ANY) 
     bSizerTest.Add(self.m_button_ok, 0) 
     self.SetSizer(bSizerTest) 
     # Connect Events 
     self.m_button_ok.Bind(wx.EVT_BUTTON, self.on_ok) 
    def on_ok(self, event): 
     event.Skip() 

class CDlg(CDlgBase) : 
    """The dialog""" 
    def __init__(self, parent): 
     super(CDlg, self).__init__(parent) 
    def on_ok(self, event): 
     # The exception should be verified in the test `test_should_raise()`. 
     raise TypeError('TypeError raised') 

class CDlgTest(unittest.TestCase) : 
    """The test class""" 
    def setUp(self): 
     self._dut = CDlg(None) 
    def test_should_raise(self): 
     """The test to verify raising the TypeError exception in the event 
     method `on_ok()`. this is the test method wich works not as expected.""" 
     event = wx.CommandEvent(wx.EVT_BUTTON.evtType[0]) 
     event.SetEventObject(self._dut.m_button_ok) 
     with self.assertRaises(TypeError) : 
      """Simulate an "OK" click. `on_ok()` will be executed 
      and raises the TypeError exception.""" 
      self._dut.m_button_ok.GetEventHandler().ProcessEvent(event) 

if __name__ == '__main__': 
    app = wx.App() 
    tests = [ unittest.TestLoader().loadTestsFromTestCase(CDlgTest) ] 
    unittest.TextTestRunner(verbosity=2, failfast=True).run(unittest.TestSuite(tests)) 

Может кто-нибудь, пожалуйста, помогите мне узнать, что я сделал не так?

+0

Я сам интересуюсь этим решением. Насколько я понимаю, исключение выражается в другом потоке и ломается каркасом wx, возможно, его след сбрасывается в 'stdout'. –

+0

С другого форума python я получил следующий ответ: Это общая проблема при тестировании графического интерфейса. Исключения, вызванные обработчиками событий, не должны влиять на полную программу. Это причина, когда планировщик ловит их и не передает их в вашу тестовую процедуру. Обработчики событий должны быть не более тонких слоев, которые необходимо тестировать отдельно без графического интерфейса. – Humbalan

ответ

2

См: https://wiki.wxpython.org/CppAndPythonSandwich

Исключения не передаются в стек вызовов, хотя слои C++. Когда элемент управления возвращается к C++ из Python, тогда он проверяет, не было ли исключение Python, если оно было потом, затем оно печатает, а затем очищает ошибку.

Один из способов борьбы с этим в модульных тестах - уловить исключение в обработчике событий и установить флаг. Затем в тестовом коде вы можете проверить, установлен ли этот флаг или нет.

+0

Я пробовал ваш совет, и это работает для меня. Большое спасибо. Во всяком случае, я думаю о переделке моих валидаторов на работу без исключений. – Humbalan