eric7/Unittest/UnittestWidget.py

branch
unittest
changeset 9064
339bb8c8007d
parent 9063
f1d7dd7ae471
child 9065
39405e6eba20
diff -r f1d7dd7ae471 -r 339bb8c8007d eric7/Unittest/UnittestWidget.py
--- a/eric7/Unittest/UnittestWidget.py	Sat May 14 18:56:52 2022 +0200
+++ b/eric7/Unittest/UnittestWidget.py	Sun May 15 18:08:31 2022 +0200
@@ -100,29 +100,23 @@
             "Start the selected testsuite"))
         self.__startButton.setWhatsThis(self.tr(
             """<b>Start Test</b>"""
-            """<p>This button starts the selected testsuite.</p>"""))
+            """<p>This button starts the test run.</p>"""))
         
-        # TODO: implement "Rerun Failed"
-##        self.__startFailedButton = self.buttonBox.addButton(
-##            self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole)
-##        self.__startFailedButton.setToolTip(
-##            self.tr("Reruns failed tests of the selected testsuite"))
-##        self.__startFailedButton.setWhatsThis(self.tr(
-##            """<b>Rerun Failed</b>"""
-##            """<p>This button reruns all failed tests of the selected"""
-##            """ testsuite.</p>"""))
-##        
+        self.__startFailedButton = self.buttonBox.addButton(
+            self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole)
+        self.__startFailedButton.setToolTip(
+            self.tr("Reruns failed tests of the selected testsuite"))
+        self.__startFailedButton.setWhatsThis(self.tr(
+            """<b>Rerun Failed</b>"""
+            """<p>This button reruns all failed tests of the most recent"""
+            """ test run.</p>"""))
+        
         self.__stopButton = self.buttonBox.addButton(
             self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole)
         self.__stopButton.setToolTip(self.tr("Stop the running unittest"))
         self.__stopButton.setWhatsThis(self.tr(
             """<b>Stop Test</b>"""
-            """<p>This button stops a running unittest.</p>"""))
-        
-        self.__stopButton.setEnabled(False)
-        self.__startButton.setDefault(True)
-        self.__startButton.setEnabled(False)
-##        self.__startFailedButton.setEnabled(False)
+            """<p>This button stops a running test.</p>"""))
         
         self.setWindowFlags(
             self.windowFlags() |
@@ -148,21 +142,22 @@
         self.__testNameHistory = []
         self.__recentFramework = ""
         self.__recentEnvironment = ""
-        
-        self.__failedTests = set()
+        self.__failedTests = []
         
         self.__editors = []
         self.__testExecutor = None
         
         # connect some signals
         self.frameworkComboBox.currentIndexChanged.connect(
-            self.__updateButtonBoxButtons)
+            self.__resetResults)
         self.discoverCheckBox.toggled.connect(
-            self.__updateButtonBoxButtons)
+            self.__resetResults)
         self.discoveryPicker.editTextChanged.connect(
-            self.__updateButtonBoxButtons)
+            self.__resetResults)
         self.testsuitePicker.editTextChanged.connect(
-            self.__updateButtonBoxButtons)
+            self.__resetResults)
+        self.testComboBox.editTextChanged.connect(
+            self.__resetResults)
         
         self.__frameworkRegistry = UTFrameworkRegistry()
         for framework in Frameworks:
@@ -235,6 +230,25 @@
             
             self.frameworkComboBox.setCurrentText(self.__recentFramework)
     
+    def getResultsModel(self):
+        """
+        Public method to get a reference to the model containing the test
+        result data.
+        
+        @return reference to the test results model
+        @rtype TestResultsModel
+        """
+        return self.__resultsModel
+    
+    def getFailedTests(self):
+        """
+        Public method to get the list of failed tests (if any).
+        
+        @return list of IDs of failed tests
+        @rtype list of str
+        """
+        return self.__failedTests[:]
+    
     @pyqtSlot(str)
     def __insertHistory(self, widget, history, item):
         """
@@ -370,11 +384,30 @@
         # sync histories
         self.__saveRecent()
     
+    @pyqtSlot()
+    def __resetResults(self):
+        """
+        Private slot to reset the test results tab and data.
+        """
+        self.__totalCount = 0
+        self.__runCount = 0
+        
+        self.progressCounterRunCount.setText("0")
+        self.progressCounterRemCount.setText("0")
+        self.progressProgressBar.setMaximum(100)
+        self.progressProgressBar.setValue(0)
+        
+        self.statusLabel.clear()
+        
+        self.__resultsModel.clear()
+        self.__updateButtonBoxButtons()
+    
+    @pyqtSlot()
     def __updateButtonBoxButtons(self):
         """
-        Private method to update the state of the buttons of the button box.
+        Private slot to update the state of the buttons of the button box.
         """
-        failedAvailable = bool(self.__failedTests)
+        failedAvailable = bool(self.__resultsModel.getFailedTests())
         
         # Start button
         if self.__mode in (
@@ -398,7 +431,14 @@
             self.__startButton.setDefault(False)
         
         # Start Failed button
-        # TODO: not implemented yet (Start Failed button)
+        self.__startFailedButton.setEnabled(
+            self.__mode == UnittestWidgetModes.STOPPED and
+            failedAvailable
+        )
+        self.__startFailedButton.setDefault(
+            self.__mode == UnittestWidgetModes.STOPPED and
+            failedAvailable
+        )
         
         # Stop button
         self.__stopButton.setEnabled(
@@ -413,9 +453,10 @@
             UnittestWidgetModes.IDLE, UnittestWidgetModes.STOPPED
         ))
     
+    @pyqtSlot()
     def __updateProgress(self):
         """
-        Private method update the progress indicators.
+        Private slot update the progress indicators.
         """
         self.progressCounterRunCount.setText(
             str(self.__runCount))
@@ -424,17 +465,20 @@
         self.progressProgressBar.setMaximum(self.__totalCount)
         self.progressProgressBar.setValue(self.__runCount)
     
+    @pyqtSlot()
     def __setIdleMode(self):
         """
-        Private method to switch the widget to idle mode.
+        Private slot to switch the widget to idle mode.
         """
         self.__mode = UnittestWidgetModes.IDLE
         self.__updateButtonBoxButtons()
+        self.progressGroupBox.hide()
         self.tabWidget.setCurrentIndex(0)
     
+    @pyqtSlot()
     def __setRunningMode(self):
         """
-        Private method to switch the widget to running mode.
+        Private slot to switch the widget to running mode.
         """
         self.__mode = UnittestWidgetModes.RUNNING
         
@@ -449,19 +493,51 @@
         self.__updateButtonBoxButtons()
         self.__updateProgress()
         
-        self.__resultsModel.clear()
+        self.progressGroupBox.show()
     
+    @pyqtSlot()
     def __setStoppedMode(self):
         """
-        Private method to switch the widget to stopped mode.
+        Private slot to switch the widget to stopped mode.
         """
         self.__mode = UnittestWidgetModes.STOPPED
+        if self.__totalCount == 0:
+            self.progressProgressBar.setMaximum(100)
+        
+        self.progressGroupBox.hide()
         
         self.__updateButtonBoxButtons()
         
         self.raise_()
         self.activateWindow()
     
+    @pyqtSlot()
+    def on_testsuitePicker_aboutToShowPathPickerDialog(self):
+        """
+        Private slot called before the test file selection dialog is shown.
+        """
+        # TODO: implement eric-ide mode
+#        if self.__dbs:
+#            py3Extensions = ' '.join(
+#                ["*{0}".format(ext)
+#                 for ext in self.__dbs.getExtensions('Python3')]
+#            )
+#            fileFilter = self.tr(
+#                "Python3 Files ({0});;All Files (*)"
+#            ).format(py3Extensions)
+#        else:
+        fileFilter = self.tr("Python Files (*.py);;All Files (*)")
+        self.testsuitePicker.setFilters(fileFilter)
+        
+        defaultDirectory = Preferences.getMultiProject("Workspace")
+        if not defaultDirectory:
+            defaultDirectory = os.path.expanduser("~")
+#        if self.__dbs:
+#            project = ericApp().getObject("Project")
+#            if self.__forProject and project.isOpen():
+#                defaultDirectory = project.getProjectPath()
+        self.testsuitePicker.setDefaultDirectory(defaultDirectory)
+    
     @pyqtSlot(QAbstractButton)
     def on_buttonBox_clicked(self, button):
         """
@@ -475,8 +551,8 @@
             self.__saveRecent()
         elif button == self.__stopButton:
             self.__stopTests()
-#        elif button == self.__startFailedButton:
-#            self.startTests(failedOnly=True)
+        elif button == self.__startFailedButton:
+            self.startTests(failedOnly=True)
     
     @pyqtSlot(int)
     def on_venvComboBox_currentIndexChanged(self, index):
@@ -548,6 +624,11 @@
         self.__recentEnvironment = self.venvComboBox.currentText()
         self.__recentFramework = self.frameworkComboBox.currentText()
         
+        self.__failedTests = (
+            self.__resultsModel.getFailedTests()
+            if failedOnly else
+            []
+        )
         discover = self.discoverCheckBox.isChecked()
         if discover:
             discoveryStart = self.discoveryPicker.currentText()
@@ -579,11 +660,11 @@
             testFilename=testFileName,
             testName=testName,
             failFast=self.failfastCheckBox.isChecked(),
+            failedOnly=failedOnly,
             collectCoverage=self.coverageCheckBox.isChecked(),
             eraseCoverage=self.coverageEraseCheckBox.isChecked(),
         )
         
-        self.__resultsModel.clear()
         self.__testExecutor = self.__frameworkRegistry.createExecutor(
             self.__recentFramework, self)
         self.__testExecutor.collected.connect(self.__testsCollected)
@@ -594,6 +675,8 @@
         self.__testExecutor.testRunFinished.connect(self.__testRunFinished)
         self.__testExecutor.stop.connect(self.__testsStopped)
         self.__testExecutor.coverageDataSaved.connect(self.__coverageData)
+        self.__testExecutor.testRunAboutToBeStarted.connect(
+            self.__testRunAboutToBeStarted)
         
         self.__setRunningMode()
         self.__testExecutor.start(config, [])
@@ -736,6 +819,14 @@
         
         self.__setStoppedMode()
     
+    @pyqtSlot()
+    def __testRunAboutToBeStarted(self):
+        """
+        Private slot to handle the 'testRunAboutToBeStarted' signal of the
+        executor.
+        """
+        self.__resultsModel.clear()
+    
     @pyqtSlot(str)
     def __coverageData(self, coverageFile):
         """

eric ide

mercurial