PyUnit/UnittestDialog.py

branch
Py2 comp.
changeset 3057
10516539f238
parent 2791
a9577f248f04
parent 2992
dbdf27746da5
child 3058
0a02c433f52d
equal deleted inserted replaced
3056:9986ec0e559a 3057:10516539f238
14 import time 14 import time
15 import re 15 import re
16 import os 16 import os
17 17
18 from PyQt4.QtCore import pyqtSignal, QEvent, Qt, pyqtSlot 18 from PyQt4.QtCore import pyqtSignal, QEvent, Qt, pyqtSlot
19 from PyQt4.QtGui import QWidget, QColor, QDialog, QApplication, QDialogButtonBox, \ 19 from PyQt4.QtGui import QWidget, QColor, QDialog, QApplication, \
20 QListWidgetItem 20 QDialogButtonBox, QListWidgetItem
21 21
22 from E5Gui.E5Application import e5App 22 from E5Gui.E5Application import e5App
23 from E5Gui.E5Completers import E5FileCompleter 23 from E5Gui.E5Completers import E5FileCompleter
24 from E5Gui import E5MessageBox, E5FileDialog 24 from E5Gui import E5MessageBox, E5FileDialog
25 from E5Gui.E5MainWindow import E5MainWindow 25 from E5Gui.E5MainWindow import E5MainWindow
34 34
35 class UnittestDialog(QWidget, Ui_UnittestDialog): 35 class UnittestDialog(QWidget, Ui_UnittestDialog):
36 """ 36 """
37 Class implementing the UI to the pyunit package. 37 Class implementing the UI to the pyunit package.
38 38
39 @signal unittestFile(str, int, int) emitted to show the source of a unittest file 39 @signal unittestFile(str, int, int) emitted to show the source of a
40 unittest file
40 @signal unittestStopped() emitted after a unit test was run 41 @signal unittestStopped() emitted after a unit test was run
41 """ 42 """
42 unittestFile = pyqtSignal(str, int, int) 43 unittestFile = pyqtSignal(str, int, int)
43 unittestStopped = pyqtSignal() 44 unittestStopped = pyqtSignal()
44 45
45 def __init__(self, prog=None, dbs=None, ui=None, fromEric=False, parent=None, 46 def __init__(self, prog=None, dbs=None, ui=None, fromEric=False,
46 name=None): 47 parent=None, name=None):
47 """ 48 """
48 Constructor 49 Constructor
49 50
50 @param prog filename of the program to open 51 @param prog filename of the program to open
51 @param dbs reference to the debug server object. It is an indication 52 @param dbs reference to the debug server object. It is an indication
61 self.setObjectName(name) 62 self.setObjectName(name)
62 self.setupUi(self) 63 self.setupUi(self)
63 64
64 self.startButton = self.buttonBox.addButton( 65 self.startButton = self.buttonBox.addButton(
65 self.trUtf8("Start"), QDialogButtonBox.ActionRole) 66 self.trUtf8("Start"), QDialogButtonBox.ActionRole)
66 self.startButton.setToolTip(self.trUtf8("Start the selected testsuite")) 67 self.startButton.setToolTip(self.trUtf8(
68 "Start the selected testsuite"))
67 self.startButton.setWhatsThis(self.trUtf8( 69 self.startButton.setWhatsThis(self.trUtf8(
68 """<b>Start Test</b>""" 70 """<b>Start Test</b>"""
69 """<p>This button starts the selected testsuite.</p>""")) 71 """<p>This button starts the selected testsuite.</p>"""))
70 self.startFailedButton = self.buttonBox.addButton( 72 self.startFailedButton = self.buttonBox.addButton(
71 self.trUtf8("Rerun Failed"), QDialogButtonBox.ActionRole) 73 self.trUtf8("Rerun Failed"), QDialogButtonBox.ActionRole)
72 self.startFailedButton.setToolTip( 74 self.startFailedButton.setToolTip(
73 self.trUtf8("Reruns failed tests of the selected testsuite")) 75 self.trUtf8("Reruns failed tests of the selected testsuite"))
74 self.startFailedButton.setWhatsThis(self.trUtf8( 76 self.startFailedButton.setWhatsThis(self.trUtf8(
75 """<b>Rerun Failed</b>""" 77 """<b>Rerun Failed</b>"""
76 """<p>This button reruns all failed tests of the selected testsuite.</p>""")) 78 """<p>This button reruns all failed tests of the selected"""
79 """ testsuite.</p>"""))
77 self.stopButton = self.buttonBox.addButton( 80 self.stopButton = self.buttonBox.addButton(
78 self.trUtf8("Stop"), QDialogButtonBox.ActionRole) 81 self.trUtf8("Stop"), QDialogButtonBox.ActionRole)
79 self.stopButton.setToolTip(self.trUtf8("Stop the running unittest")) 82 self.stopButton.setToolTip(self.trUtf8("Stop the running unittest"))
80 self.stopButton.setWhatsThis(self.trUtf8( 83 self.stopButton.setWhatsThis(self.trUtf8(
81 """<b>Stop Test</b>""" 84 """<b>Stop Test</b>"""
86 89
87 self.dbs = dbs 90 self.dbs = dbs
88 self.__fromEric = fromEric 91 self.__fromEric = fromEric
89 92
90 self.setWindowFlags( 93 self.setWindowFlags(
91 self.windowFlags() | Qt.WindowFlags(Qt.WindowContextHelpButtonHint)) 94 self.windowFlags() | Qt.WindowFlags(
95 Qt.WindowContextHelpButtonHint))
92 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) 96 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
93 self.setWindowTitle(self.trUtf8("Unittest")) 97 self.setWindowTitle(self.trUtf8("Unittest"))
94 if dbs: 98 if dbs:
95 self.ui = ui 99 self.ui = ui
96 else: 100 else:
124 self.dbs.utStopTest.connect(self.testFinished) 128 self.dbs.utStopTest.connect(self.testFinished)
125 self.dbs.utTestFailed.connect(self.testFailed) 129 self.dbs.utTestFailed.connect(self.testFailed)
126 self.dbs.utTestErrored.connect(self.testErrored) 130 self.dbs.utTestErrored.connect(self.testErrored)
127 self.dbs.utTestSkipped.connect(self.testSkipped) 131 self.dbs.utTestSkipped.connect(self.testSkipped)
128 self.dbs.utTestFailedExpected.connect(self.testFailedExpected) 132 self.dbs.utTestFailedExpected.connect(self.testFailedExpected)
129 self.dbs.utTestSucceededUnexpected.connect(self.testSucceededUnexpected) 133 self.dbs.utTestSucceededUnexpected.connect(
134 self.testSucceededUnexpected)
130 135
131 def keyPressEvent(self, evt): 136 def keyPressEvent(self, evt):
132 """ 137 """
133 Protected slot to handle key press events. 138 Protected slot to handle key press events.
134 139
145 """ 150 """
146 self.progressLed.setColor(QColor(color)) 151 self.progressLed.setColor(QColor(color))
147 152
148 def insertProg(self, prog): 153 def insertProg(self, prog):
149 """ 154 """
150 Public slot to insert the filename prog into the testsuiteComboBox object. 155 Public slot to insert the filename prog into the testsuiteComboBox
156 object.
151 157
152 @param prog filename to be inserted (string) 158 @param prog filename to be inserted (string)
153 """ 159 """
154 # prepend the selected file to the testsuite combobox 160 # prepend the selected file to the testsuite combobox
155 if prog is None: 161 if prog is None:
294 failed, 300 failed,
295 self.coverageCheckBox.isChecked(), mainScript, 301 self.coverageCheckBox.isChecked(), mainScript,
296 self.coverageEraseCheckBox.isChecked(), clientType=clientType) 302 self.coverageEraseCheckBox.isChecked(), clientType=clientType)
297 else: 303 else:
298 # we are running as an application or in local mode 304 # we are running as an application or in local mode
299 sys.path = [os.path.dirname(os.path.abspath(prog))] + self.savedSysPath 305 sys.path = [os.path.dirname(os.path.abspath(prog))] + \
306 self.savedSysPath
300 307
301 # clean up list of imported modules to force a reimport upon running the test 308 # clean up list of imported modules to force a reimport upon
309 # running the test
302 if self.savedModulelist: 310 if self.savedModulelist:
303 for modname in list(sys.modules.keys()): 311 for modname in list(sys.modules.keys()):
304 if modname not in self.savedModulelist: 312 if modname not in self.savedModulelist:
305 # delete it 313 # delete it
306 del(sys.modules[modname]) 314 del(sys.modules[modname])
316 module) 324 module)
317 else: 325 else:
318 test = unittest.defaultTestLoader.loadTestsFromName( 326 test = unittest.defaultTestLoader.loadTestsFromName(
319 testFunctionName, module) 327 testFunctionName, module)
320 except AttributeError: 328 except AttributeError:
321 test = unittest.defaultTestLoader.loadTestsFromModule(module) 329 test = unittest.defaultTestLoader.loadTestsFromModule(
330 module)
322 except: 331 except:
323 exc_type, exc_value, exc_tb = sys.exc_info() 332 exc_type, exc_value, exc_tb = sys.exc_info()
324 E5MessageBox.critical(self, 333 E5MessageBox.critical(self,
325 self.trUtf8("Unittest"), 334 self.trUtf8("Unittest"),
326 self.trUtf8("<p>Unable to run test <b>{0}</b>.<br>{1}<br>{2}</p>") 335 self.trUtf8(
327 .format(self.testName, str(exc_type), str(exc_value))) 336 "<p>Unable to run test <b>{0}</b>.<br>"
337 "{1}<br>{2}</p>")
338 .format(self.testName, str(exc_type),
339 str(exc_value)))
328 return 340 return
329 341
330 # now set up the coverage stuff 342 # now set up the coverage stuff
331 if self.coverageCheckBox.isChecked(): 343 if self.coverageCheckBox.isChecked():
332 if self.dbs: 344 if self.dbs:
341 else: 353 else:
342 mainScript = os.path.abspath(prog) 354 mainScript = os.path.abspath(prog)
343 355
344 from DebugClients.Python3.coverage import coverage 356 from DebugClients.Python3.coverage import coverage
345 cover = coverage( 357 cover = coverage(
346 data_file="{0}.coverage".format(os.path.splitext(mainScript)[0])) 358 data_file="{0}.coverage".format(
359 os.path.splitext(mainScript)[0]))
347 cover.use_cache(True) 360 cover.use_cache(True)
348 if self.coverageEraseCheckBox.isChecked(): 361 if self.coverageEraseCheckBox.isChecked():
349 cover.erase() 362 cover.erase()
350 else: 363 else:
351 cover = None 364 cover = None
375 @param exc_value value of exception occured during preparation (string) 388 @param exc_value value of exception occured during preparation (string)
376 """ 389 """
377 if nrTests == 0: 390 if nrTests == 0:
378 E5MessageBox.critical(self, 391 E5MessageBox.critical(self,
379 self.trUtf8("Unittest"), 392 self.trUtf8("Unittest"),
380 self.trUtf8("<p>Unable to run test <b>{0}</b>.<br>{1}<br>{2}</p>") 393 self.trUtf8(
394 "<p>Unable to run test <b>{0}</b>.<br>{1}<br>{2}</p>")
381 .format(self.testName, exc_type, exc_value)) 395 .format(self.testName, exc_type, exc_value))
382 return 396 return
383 397
384 self.totalTests = nrTests 398 self.totalTests = nrTests
385 self.__setRunningMode() 399 self.__setRunningMode()
397 411
398 def on_errorsListWidget_currentTextChanged(self, text): 412 def on_errorsListWidget_currentTextChanged(self, text):
399 """ 413 """
400 Private slot to handle the highlighted signal. 414 Private slot to handle the highlighted signal.
401 415
402 @param txt current text (string) 416 @param text current text (string)
403 """ 417 """
404 if text: 418 if text:
405 for pattern in self.rxPatterns: 419 for pattern in self.rxPatterns:
406 text = re.sub(pattern, "", text) 420 text = re.sub(pattern, "", text)
407 itm = self.testsListWidget.findItems(text, Qt.MatchFlags(Qt.MatchExactly))[0] 421 itm = self.testsListWidget.findItems(
422 text, Qt.MatchFlags(Qt.MatchExactly))[0]
408 self.testsListWidget.setCurrentItem(itm) 423 self.testsListWidget.setCurrentItem(itm)
409 self.testsListWidget.scrollToItem(itm) 424 self.testsListWidget.scrollToItem(itm)
410 425
411 def __setRunningMode(self): 426 def __setRunningMode(self):
412 """ 427 """
427 self.progressCounterRunCount.setText(str(self.runCount)) 442 self.progressCounterRunCount.setText(str(self.runCount))
428 self.progressCounterRemCount.setText(str(self.remainingCount)) 443 self.progressCounterRemCount.setText(str(self.remainingCount))
429 self.progressCounterFailureCount.setText(str(self.failCount)) 444 self.progressCounterFailureCount.setText(str(self.failCount))
430 self.progressCounterErrorCount.setText(str(self.errorCount)) 445 self.progressCounterErrorCount.setText(str(self.errorCount))
431 self.progressCounterSkippedCount.setText(str(self.skippedCount)) 446 self.progressCounterSkippedCount.setText(str(self.skippedCount))
432 self.progressCounterExpectedFailureCount.setText(str(self.expectedFailureCount)) 447 self.progressCounterExpectedFailureCount.setText(
448 str(self.expectedFailureCount))
433 self.progressCounterUnexpectedSuccessCount.setText( 449 self.progressCounterUnexpectedSuccessCount.setText(
434 str(self.unexpectedSuccessCount)) 450 str(self.unexpectedSuccessCount))
435 self.errorsListWidget.clear() 451 self.errorsListWidget.clear()
436 self.testsListWidget.clear() 452 self.testsListWidget.clear()
437 self.progressProgressBar.setRange(0, self.totalTests) 453 self.progressProgressBar.setRange(0, self.totalTests)
524 @param test name of the test (string) 540 @param test name of the test (string)
525 @param exc string representation of the exception (string) 541 @param exc string representation of the exception (string)
526 @param id id of the test (string) 542 @param id id of the test (string)
527 """ 543 """
528 self.expectedFailureCount += 1 544 self.expectedFailureCount += 1
529 self.progressCounterExpectedFailureCount.setText(str(self.expectedFailureCount)) 545 self.progressCounterExpectedFailureCount.setText(
546 str(self.expectedFailureCount))
530 itm = QListWidgetItem(self.trUtf8(" Expected Failure")) 547 itm = QListWidgetItem(self.trUtf8(" Expected Failure"))
531 itm.setForeground(Qt.blue) 548 itm.setForeground(Qt.blue)
532 self.testsListWidget.insertItem(1, itm) 549 self.testsListWidget.insertItem(1, itm)
533 550
534 def testSucceededUnexpected(self, test, id): 551 def testSucceededUnexpected(self, test, id):
629 646
630 # get the error info 647 # get the error info
631 tracebackLines = self.dlg.traceback.toPlainText().splitlines() 648 tracebackLines = self.dlg.traceback.toPlainText().splitlines()
632 # find the last entry matching the pattern 649 # find the last entry matching the pattern
633 for index in range(len(tracebackLines) - 1, -1, -1): 650 for index in range(len(tracebackLines) - 1, -1, -1):
634 fmatch = re.search(r'File "(.*?)", line (\d*?),.*', tracebackLines[index]) 651 fmatch = re.search(r'File "(.*?)", line (\d*?),.*',
652 tracebackLines[index])
635 if fmatch: 653 if fmatch:
636 break 654 break
637 if fmatch: 655 if fmatch:
638 fn, ln = fmatch.group(1, 2) 656 fn, ln = fmatch.group(1, 2)
639 self.unittestFile.emit(fn, int(ln), 1) 657 self.unittestFile.emit(fn, int(ln), 1)
749 self.cw.installEventFilter(self) 767 self.cw.installEventFilter(self)
750 size = self.cw.size() 768 size = self.cw.size()
751 self.setCentralWidget(self.cw) 769 self.setCentralWidget(self.cw)
752 self.resize(size) 770 self.resize(size)
753 771
754 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) 772 self.setStyle(Preferences.getUI("Style"),
773 Preferences.getUI("StyleSheet"))
755 774
756 def eventFilter(self, obj, event): 775 def eventFilter(self, obj, event):
757 """ 776 """
758 Public method to filter events. 777 Public method to filter events.
759 778

eric ide

mercurial