eric7/Unittest/UnittestWidget.py

branch
unittest
changeset 9064
339bb8c8007d
parent 9063
f1d7dd7ae471
child 9065
39405e6eba20
equal deleted inserted replaced
9063:f1d7dd7ae471 9064:339bb8c8007d
98 98
99 self.__startButton.setToolTip(self.tr( 99 self.__startButton.setToolTip(self.tr(
100 "Start the selected testsuite")) 100 "Start the selected testsuite"))
101 self.__startButton.setWhatsThis(self.tr( 101 self.__startButton.setWhatsThis(self.tr(
102 """<b>Start Test</b>""" 102 """<b>Start Test</b>"""
103 """<p>This button starts the selected testsuite.</p>""")) 103 """<p>This button starts the test run.</p>"""))
104 104
105 # TODO: implement "Rerun Failed" 105 self.__startFailedButton = self.buttonBox.addButton(
106 ## self.__startFailedButton = self.buttonBox.addButton( 106 self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole)
107 ## self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole) 107 self.__startFailedButton.setToolTip(
108 ## self.__startFailedButton.setToolTip( 108 self.tr("Reruns failed tests of the selected testsuite"))
109 ## self.tr("Reruns failed tests of the selected testsuite")) 109 self.__startFailedButton.setWhatsThis(self.tr(
110 ## self.__startFailedButton.setWhatsThis(self.tr( 110 """<b>Rerun Failed</b>"""
111 ## """<b>Rerun Failed</b>""" 111 """<p>This button reruns all failed tests of the most recent"""
112 ## """<p>This button reruns all failed tests of the selected""" 112 """ test run.</p>"""))
113 ## """ testsuite.</p>""")) 113
114 ##
115 self.__stopButton = self.buttonBox.addButton( 114 self.__stopButton = self.buttonBox.addButton(
116 self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole) 115 self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole)
117 self.__stopButton.setToolTip(self.tr("Stop the running unittest")) 116 self.__stopButton.setToolTip(self.tr("Stop the running unittest"))
118 self.__stopButton.setWhatsThis(self.tr( 117 self.__stopButton.setWhatsThis(self.tr(
119 """<b>Stop Test</b>""" 118 """<b>Stop Test</b>"""
120 """<p>This button stops a running unittest.</p>""")) 119 """<p>This button stops a running test.</p>"""))
121
122 self.__stopButton.setEnabled(False)
123 self.__startButton.setDefault(True)
124 self.__startButton.setEnabled(False)
125 ## self.__startFailedButton.setEnabled(False)
126 120
127 self.setWindowFlags( 121 self.setWindowFlags(
128 self.windowFlags() | 122 self.windowFlags() |
129 Qt.WindowType.WindowContextHelpButtonHint 123 Qt.WindowType.WindowContextHelpButtonHint
130 ) 124 )
146 self.__discoverHistory = [] 140 self.__discoverHistory = []
147 self.__fileHistory = [] 141 self.__fileHistory = []
148 self.__testNameHistory = [] 142 self.__testNameHistory = []
149 self.__recentFramework = "" 143 self.__recentFramework = ""
150 self.__recentEnvironment = "" 144 self.__recentEnvironment = ""
151 145 self.__failedTests = []
152 self.__failedTests = set()
153 146
154 self.__editors = [] 147 self.__editors = []
155 self.__testExecutor = None 148 self.__testExecutor = None
156 149
157 # connect some signals 150 # connect some signals
158 self.frameworkComboBox.currentIndexChanged.connect( 151 self.frameworkComboBox.currentIndexChanged.connect(
159 self.__updateButtonBoxButtons) 152 self.__resetResults)
160 self.discoverCheckBox.toggled.connect( 153 self.discoverCheckBox.toggled.connect(
161 self.__updateButtonBoxButtons) 154 self.__resetResults)
162 self.discoveryPicker.editTextChanged.connect( 155 self.discoveryPicker.editTextChanged.connect(
163 self.__updateButtonBoxButtons) 156 self.__resetResults)
164 self.testsuitePicker.editTextChanged.connect( 157 self.testsuitePicker.editTextChanged.connect(
165 self.__updateButtonBoxButtons) 158 self.__resetResults)
159 self.testComboBox.editTextChanged.connect(
160 self.__resetResults)
166 161
167 self.__frameworkRegistry = UTFrameworkRegistry() 162 self.__frameworkRegistry = UTFrameworkRegistry()
168 for framework in Frameworks: 163 for framework in Frameworks:
169 self.__frameworkRegistry.register(framework) 164 self.__frameworkRegistry.register(framework)
170 165
233 self.frameworkComboBox.model().item(index).setEnabled( 228 self.frameworkComboBox.model().item(index).setEnabled(
234 isInstalled) 229 isInstalled)
235 230
236 self.frameworkComboBox.setCurrentText(self.__recentFramework) 231 self.frameworkComboBox.setCurrentText(self.__recentFramework)
237 232
233 def getResultsModel(self):
234 """
235 Public method to get a reference to the model containing the test
236 result data.
237
238 @return reference to the test results model
239 @rtype TestResultsModel
240 """
241 return self.__resultsModel
242
243 def getFailedTests(self):
244 """
245 Public method to get the list of failed tests (if any).
246
247 @return list of IDs of failed tests
248 @rtype list of str
249 """
250 return self.__failedTests[:]
251
238 @pyqtSlot(str) 252 @pyqtSlot(str)
239 def __insertHistory(self, widget, history, item): 253 def __insertHistory(self, widget, history, item):
240 """ 254 """
241 Private slot to insert an item into a history object. 255 Private slot to insert an item into a history object.
242 256
368 self.testComboBox.clear() 382 self.testComboBox.clear()
369 383
370 # sync histories 384 # sync histories
371 self.__saveRecent() 385 self.__saveRecent()
372 386
387 @pyqtSlot()
388 def __resetResults(self):
389 """
390 Private slot to reset the test results tab and data.
391 """
392 self.__totalCount = 0
393 self.__runCount = 0
394
395 self.progressCounterRunCount.setText("0")
396 self.progressCounterRemCount.setText("0")
397 self.progressProgressBar.setMaximum(100)
398 self.progressProgressBar.setValue(0)
399
400 self.statusLabel.clear()
401
402 self.__resultsModel.clear()
403 self.__updateButtonBoxButtons()
404
405 @pyqtSlot()
373 def __updateButtonBoxButtons(self): 406 def __updateButtonBoxButtons(self):
374 """ 407 """
375 Private method to update the state of the buttons of the button box. 408 Private slot to update the state of the buttons of the button box.
376 """ 409 """
377 failedAvailable = bool(self.__failedTests) 410 failedAvailable = bool(self.__resultsModel.getFailedTests())
378 411
379 # Start button 412 # Start button
380 if self.__mode in ( 413 if self.__mode in (
381 UnittestWidgetModes.IDLE, UnittestWidgetModes.STOPPED 414 UnittestWidgetModes.IDLE, UnittestWidgetModes.STOPPED
382 ): 415 ):
396 else: 429 else:
397 self.__startButton.setEnabled(False) 430 self.__startButton.setEnabled(False)
398 self.__startButton.setDefault(False) 431 self.__startButton.setDefault(False)
399 432
400 # Start Failed button 433 # Start Failed button
401 # TODO: not implemented yet (Start Failed button) 434 self.__startFailedButton.setEnabled(
435 self.__mode == UnittestWidgetModes.STOPPED and
436 failedAvailable
437 )
438 self.__startFailedButton.setDefault(
439 self.__mode == UnittestWidgetModes.STOPPED and
440 failedAvailable
441 )
402 442
403 # Stop button 443 # Stop button
404 self.__stopButton.setEnabled( 444 self.__stopButton.setEnabled(
405 self.__mode == UnittestWidgetModes.RUNNING) 445 self.__mode == UnittestWidgetModes.RUNNING)
406 self.__stopButton.setDefault( 446 self.__stopButton.setDefault(
411 QDialogButtonBox.StandardButton.Close 451 QDialogButtonBox.StandardButton.Close
412 ).setEnabled(self.__mode in ( 452 ).setEnabled(self.__mode in (
413 UnittestWidgetModes.IDLE, UnittestWidgetModes.STOPPED 453 UnittestWidgetModes.IDLE, UnittestWidgetModes.STOPPED
414 )) 454 ))
415 455
456 @pyqtSlot()
416 def __updateProgress(self): 457 def __updateProgress(self):
417 """ 458 """
418 Private method update the progress indicators. 459 Private slot update the progress indicators.
419 """ 460 """
420 self.progressCounterRunCount.setText( 461 self.progressCounterRunCount.setText(
421 str(self.__runCount)) 462 str(self.__runCount))
422 self.progressCounterRemCount.setText( 463 self.progressCounterRemCount.setText(
423 str(self.__totalCount - self.__runCount)) 464 str(self.__totalCount - self.__runCount))
424 self.progressProgressBar.setMaximum(self.__totalCount) 465 self.progressProgressBar.setMaximum(self.__totalCount)
425 self.progressProgressBar.setValue(self.__runCount) 466 self.progressProgressBar.setValue(self.__runCount)
426 467
468 @pyqtSlot()
427 def __setIdleMode(self): 469 def __setIdleMode(self):
428 """ 470 """
429 Private method to switch the widget to idle mode. 471 Private slot to switch the widget to idle mode.
430 """ 472 """
431 self.__mode = UnittestWidgetModes.IDLE 473 self.__mode = UnittestWidgetModes.IDLE
432 self.__updateButtonBoxButtons() 474 self.__updateButtonBoxButtons()
475 self.progressGroupBox.hide()
433 self.tabWidget.setCurrentIndex(0) 476 self.tabWidget.setCurrentIndex(0)
434 477
478 @pyqtSlot()
435 def __setRunningMode(self): 479 def __setRunningMode(self):
436 """ 480 """
437 Private method to switch the widget to running mode. 481 Private slot to switch the widget to running mode.
438 """ 482 """
439 self.__mode = UnittestWidgetModes.RUNNING 483 self.__mode = UnittestWidgetModes.RUNNING
440 484
441 self.__totalCount = 0 485 self.__totalCount = 0
442 self.__runCount = 0 486 self.__runCount = 0
447 self.sbLabel.setText(self.tr("Running")) 491 self.sbLabel.setText(self.tr("Running"))
448 self.tabWidget.setCurrentIndex(1) 492 self.tabWidget.setCurrentIndex(1)
449 self.__updateButtonBoxButtons() 493 self.__updateButtonBoxButtons()
450 self.__updateProgress() 494 self.__updateProgress()
451 495
452 self.__resultsModel.clear() 496 self.progressGroupBox.show()
453 497
498 @pyqtSlot()
454 def __setStoppedMode(self): 499 def __setStoppedMode(self):
455 """ 500 """
456 Private method to switch the widget to stopped mode. 501 Private slot to switch the widget to stopped mode.
457 """ 502 """
458 self.__mode = UnittestWidgetModes.STOPPED 503 self.__mode = UnittestWidgetModes.STOPPED
504 if self.__totalCount == 0:
505 self.progressProgressBar.setMaximum(100)
506
507 self.progressGroupBox.hide()
459 508
460 self.__updateButtonBoxButtons() 509 self.__updateButtonBoxButtons()
461 510
462 self.raise_() 511 self.raise_()
463 self.activateWindow() 512 self.activateWindow()
513
514 @pyqtSlot()
515 def on_testsuitePicker_aboutToShowPathPickerDialog(self):
516 """
517 Private slot called before the test file selection dialog is shown.
518 """
519 # TODO: implement eric-ide mode
520 # if self.__dbs:
521 # py3Extensions = ' '.join(
522 # ["*{0}".format(ext)
523 # for ext in self.__dbs.getExtensions('Python3')]
524 # )
525 # fileFilter = self.tr(
526 # "Python3 Files ({0});;All Files (*)"
527 # ).format(py3Extensions)
528 # else:
529 fileFilter = self.tr("Python Files (*.py);;All Files (*)")
530 self.testsuitePicker.setFilters(fileFilter)
531
532 defaultDirectory = Preferences.getMultiProject("Workspace")
533 if not defaultDirectory:
534 defaultDirectory = os.path.expanduser("~")
535 # if self.__dbs:
536 # project = ericApp().getObject("Project")
537 # if self.__forProject and project.isOpen():
538 # defaultDirectory = project.getProjectPath()
539 self.testsuitePicker.setDefaultDirectory(defaultDirectory)
464 540
465 @pyqtSlot(QAbstractButton) 541 @pyqtSlot(QAbstractButton)
466 def on_buttonBox_clicked(self, button): 542 def on_buttonBox_clicked(self, button):
467 """ 543 """
468 Private slot called by a button of the button box clicked. 544 Private slot called by a button of the button box clicked.
473 if button == self.__startButton: 549 if button == self.__startButton:
474 self.startTests() 550 self.startTests()
475 self.__saveRecent() 551 self.__saveRecent()
476 elif button == self.__stopButton: 552 elif button == self.__stopButton:
477 self.__stopTests() 553 self.__stopTests()
478 # elif button == self.__startFailedButton: 554 elif button == self.__startFailedButton:
479 # self.startTests(failedOnly=True) 555 self.startTests(failedOnly=True)
480 556
481 @pyqtSlot(int) 557 @pyqtSlot(int)
482 def on_venvComboBox_currentIndexChanged(self, index): 558 def on_venvComboBox_currentIndexChanged(self, index):
483 """ 559 """
484 Private slot handling the selection of a virtual environment. 560 Private slot handling the selection of a virtual environment.
546 return 622 return
547 623
548 self.__recentEnvironment = self.venvComboBox.currentText() 624 self.__recentEnvironment = self.venvComboBox.currentText()
549 self.__recentFramework = self.frameworkComboBox.currentText() 625 self.__recentFramework = self.frameworkComboBox.currentText()
550 626
627 self.__failedTests = (
628 self.__resultsModel.getFailedTests()
629 if failedOnly else
630 []
631 )
551 discover = self.discoverCheckBox.isChecked() 632 discover = self.discoverCheckBox.isChecked()
552 if discover: 633 if discover:
553 discoveryStart = self.discoveryPicker.currentText() 634 discoveryStart = self.discoveryPicker.currentText()
554 testFileName = "" 635 testFileName = ""
555 testName = "" 636 testName = ""
577 discover=self.discoverCheckBox.isChecked(), 658 discover=self.discoverCheckBox.isChecked(),
578 discoveryStart=discoveryStart, 659 discoveryStart=discoveryStart,
579 testFilename=testFileName, 660 testFilename=testFileName,
580 testName=testName, 661 testName=testName,
581 failFast=self.failfastCheckBox.isChecked(), 662 failFast=self.failfastCheckBox.isChecked(),
663 failedOnly=failedOnly,
582 collectCoverage=self.coverageCheckBox.isChecked(), 664 collectCoverage=self.coverageCheckBox.isChecked(),
583 eraseCoverage=self.coverageEraseCheckBox.isChecked(), 665 eraseCoverage=self.coverageEraseCheckBox.isChecked(),
584 ) 666 )
585 667
586 self.__resultsModel.clear()
587 self.__testExecutor = self.__frameworkRegistry.createExecutor( 668 self.__testExecutor = self.__frameworkRegistry.createExecutor(
588 self.__recentFramework, self) 669 self.__recentFramework, self)
589 self.__testExecutor.collected.connect(self.__testsCollected) 670 self.__testExecutor.collected.connect(self.__testsCollected)
590 self.__testExecutor.collectError.connect(self.__testsCollectError) 671 self.__testExecutor.collectError.connect(self.__testsCollectError)
591 self.__testExecutor.startTest.connect(self.__testStarted) 672 self.__testExecutor.startTest.connect(self.__testStarted)
592 self.__testExecutor.testResult.connect(self.__processTestResult) 673 self.__testExecutor.testResult.connect(self.__processTestResult)
593 self.__testExecutor.testFinished.connect(self.__testProcessFinished) 674 self.__testExecutor.testFinished.connect(self.__testProcessFinished)
594 self.__testExecutor.testRunFinished.connect(self.__testRunFinished) 675 self.__testExecutor.testRunFinished.connect(self.__testRunFinished)
595 self.__testExecutor.stop.connect(self.__testsStopped) 676 self.__testExecutor.stop.connect(self.__testsStopped)
596 self.__testExecutor.coverageDataSaved.connect(self.__coverageData) 677 self.__testExecutor.coverageDataSaved.connect(self.__coverageData)
678 self.__testExecutor.testRunAboutToBeStarted.connect(
679 self.__testRunAboutToBeStarted)
597 680
598 self.__setRunningMode() 681 self.__setRunningMode()
599 self.__testExecutor.start(config, []) 682 self.__testExecutor.start(config, [])
600 683
601 @pyqtSlot() 684 @pyqtSlot()
734 """ 817 """
735 self.sbLabel.setText(self.tr("Ran %n test(s)", "", self.__runCount)) 818 self.sbLabel.setText(self.tr("Ran %n test(s)", "", self.__runCount))
736 819
737 self.__setStoppedMode() 820 self.__setStoppedMode()
738 821
822 @pyqtSlot()
823 def __testRunAboutToBeStarted(self):
824 """
825 Private slot to handle the 'testRunAboutToBeStarted' signal of the
826 executor.
827 """
828 self.__resultsModel.clear()
829
739 @pyqtSlot(str) 830 @pyqtSlot(str)
740 def __coverageData(self, coverageFile): 831 def __coverageData(self, coverageFile):
741 """ 832 """
742 Private slot to handle the 'coverageData' signal of the executor. 833 Private slot to handle the 'coverageData' signal of the executor.
743 834

eric ide

mercurial