PyUnit/UnittestDialog.py

changeset 6896
3716c4af48bb
parent 6894
df83ac87e0db
child 6897
701256697721
--- a/PyUnit/UnittestDialog.py	Sun Mar 24 12:57:08 2019 +0100
+++ b/PyUnit/UnittestDialog.py	Sun Mar 24 16:11:19 2019 +0100
@@ -75,6 +75,7 @@
         self.discoveryPicker.setSizeAdjustPolicy(
             QComboBox.AdjustToMinimumContentsLength)
         
+        # TODO: add a "Discover" button enabled upon selection of 'auto-discovery'
         self.startButton = self.buttonBox.addButton(
             self.tr("Start"), QDialogButtonBox.ActionRole)
         self.startButton.setToolTip(self.tr(
@@ -111,12 +112,20 @@
         if dbs:
             self.ui = ui
             
-            self.venvComboBox.addItem("")
-            self.venvComboBox.addItems(
-                sorted(e5App().getObject("VirtualEnvManager")
-                       .getVirtualenvNames()))
-        self.venvComboBox.setVisible(bool(self.__dbs))
-        self.venvLabel.setVisible(bool(self.__dbs))
+            # virtual environment manager is only used in the integrated
+            # variant
+            self.__venvManager = e5App().getObject("VirtualEnvManager")
+            self.__populateVenvComboBox()
+            self.__venvManager.virtualEnvironmentAdded.connect(
+                self.__populateVenvComboBox)
+            self.__venvManager.virtualEnvironmentRemoved.connect(
+                self.__populateVenvComboBox)
+            self.__venvManager.virtualEnvironmentChanged.connect(
+                self.__populateVenvComboBox)
+        else:
+            self.__venvManager = None
+        self.venvComboBox.setVisible(bool(self.__venvManager))
+        self.venvLabel.setVisible(bool(self.__venvManager))
         
         self.__setProgressColor("green")
         self.progressLed.setDarkFactor(150)
@@ -165,6 +174,20 @@
         if evt.key() == Qt.Key_Escape and self.__dbs:
             self.close()
     
+    def __populateVenvComboBox(self):
+        """
+        Private method to (re-)populate the virtual environments selector.
+        """
+        currentText = self.venvComboBox.currentText()
+        self.venvComboBox.clear()
+        self.venvComboBox.addItem("")
+        self.venvComboBox.addItems(
+            sorted(self.__venvManager.getVirtualenvNames()))
+        index = self.venvComboBox.findText(currentText)
+        if index < 0:
+            index = 0
+        self.venvComboBox.setCurrentIndex(index)
+    
     def __setProgressColor(self, color):
         """
         Private methode to set the color of the progress color label.
@@ -264,6 +287,7 @@
             project = e5App().getObject("Project")
             if self.__forProject and project.isOpen():
                 defaultDirectory = project.getProjectPath()
+        self.testsuitePicker.setDefaultDirectory(defaultDirectory)
     
     @pyqtSlot(str)
     def on_testsuitePicker_pathSelected(self, suite):
@@ -303,61 +327,68 @@
         @param button button that was clicked (QAbstractButton)
         """
         if button == self.startButton:
-            self.on_startButton_clicked()
+            self.startTests()
         elif button == self.stopButton:
-            self.on_stopButton_clicked()
+            self.__stopTests()
         elif button == self.startFailedButton:
-            self.on_startButton_clicked(failedOnly=True)
+            self.startTests(failedOnly=True)
     
     @pyqtSlot()
-    def on_startButton_clicked(self, failedOnly=False):
+    def startTests(self, failedOnly=False):
         """
-        Private slot to start the test.
+        Public slot to start the test.
         
         @keyparam failedOnly flag indicating to run only failed tests (boolean)
         """
+        # TODO: run only failed test ignoring test parameters when failedOnly is set
         if self.running:
             return
         
         discover = self.discoverCheckBox.isChecked()
         if discover:
             discoveryStart = self.discoveryPicker.currentText()
-            prog = ""
+            testFileName = ""
+            testName = ""
         else:
             discoveryStart = ""
-            prog = self.testsuitePicker.currentText()
+            testFileName = self.testsuitePicker.currentText()
+            testName = self.testComboBox.currentText()
+            if testName:
+                self.insertTestName(testName)
+            if testFileName and not testName:
+                testName = "suite"
         
-        if not prog and not discover:
+        if not discover and not testFileName and not testName:
             E5MessageBox.critical(
                 self,
                 self.tr("Unittest"),
-                self.tr("You must enter a test suite file or select"
-                        " auto-discovery."))
+                self.tr("You must select auto-discovery or enter a test suite"
+                        " file or a dotted test name."))
             return
         
         # prepend the selected file to the testsuite combobox
-        self.insertProg(prog)
+        self.insertProg(testFileName)
         self.sbLabel.setText(self.tr("Preparing Testsuite"))
         QApplication.processEvents()
         
         if discover:
-            testFunctionName = ""
             self.testName = self.tr("Unittest with auto-discovery")
         else:
-            testFunctionName = self.testComboBox.currentText()
-            if testFunctionName:
-                self.insertTestName(testFunctionName)
+            # build the module name from the filename without extension
+            if testFileName:
+                self.testName = os.path.splitext(
+                    os.path.basename(testFileName))[0]
+            elif testName:
+                self.testName = testName
             else:
-                testFunctionName = "suite"
-            
-            # build the module name from the filename without extension
-            self.testName = os.path.splitext(os.path.basename(prog))[0]
+                self.testName = self.tr("<Unnamed Test>")
         
         if self.__dbs:
+            venvName = self.venvComboBox.currentText()
+            
             # we are cooperating with the eric6 IDE
             project = e5App().getObject("Project")
-            if self.__forProject and project.isOpen() and \
-               (discover or project.isProjectSource(prog)):
+            if self.__forProject:
                 mainScript = os.path.abspath(project.getMainScript(True))
                 clientType = project.getProjectLanguage()
                 if mainScript:
@@ -365,6 +396,7 @@
                 else:
                     workdir = project.getProjectPath()
                 sysPath = [workdir]
+                coverageFile = os.path.splitext(mainScript)[0]
                 if discover and not discoveryStart:
                     discoveryStart = workdir
             else:
@@ -376,14 +408,18 @@
                             self.tr("You must enter a start directory for"
                                     " auto-discovery."))
                         return
-                    mainScript = os.path.join(discoveryStart, "unittest")
+                    
+                    coverageFile = os.path.join(discoveryStart, "unittest")
                     workdir = ""
-                    # assume Python3 for auto-discovery
-                    clientType = "Python3"
-                else:
-                    mainScript = os.path.abspath(prog)
+                    clientType = \
+                        self.__venvManager.getVirtualenvVariant(venvName)
+                    if not clientType:
+                        # assume Python 3
+                        clientType = "Python3"
+                elif testFileName:
+                    mainScript = os.path.abspath(testFileName)
+                    flags = Utilities.extractFlagsFromFile(mainScript)
                     workdir = os.path.dirname(mainScript)
-                    flags = Utilities.extractFlagsFromFile(mainScript)
                     if mainScript.endswith(
                         tuple(Preferences.getPython("PythonExtensions"))) or \
                        ("FileType" in flags and
@@ -392,24 +428,33 @@
                     else:
                         # if it is not Python2 it must be Python3!
                         clientType = "Python3"
+                    coverageFile = os.path.splitext(mainScript)[0]
+                else:
+                    coverageFile = os.path.abspath("unittest")
+                    workdir = ""
+                    clientType = \
+                        self.__venvManager.getVirtualenvVariant(venvName)
+                    if not clientType:
+                        # assume Python 3
+                        clientType = "Python3"
                 sysPath = []
             if not discover and failedOnly and self.__failedTests:
-                failed = [t.split(".", 1)[1] for t in self.__failedTests]
+                failed = self.__failedTests[:]
             else:
                 failed = []
             self.__failedTests = []
             self.__dbs.remoteUTPrepare(
-                prog, self.testName, testFunctionName, failed,
-                self.coverageCheckBox.isChecked(), mainScript,
+                testFileName, self.testName, testName, failed,
+                self.coverageCheckBox.isChecked(), coverageFile,
                 self.coverageEraseCheckBox.isChecked(), clientType=clientType,
                 forProject=self.__forProject, workdir=workdir,
-                venvName=self.venvComboBox.currentText(), syspath=sysPath,
+                venvName=venvName, syspath=sysPath,
                 discover=discover, discoveryStart=discoveryStart)
         else:
-            # TODO: add discovery
             # we are running as an application
-            sys.path = [os.path.dirname(os.path.abspath(prog))] + \
-                self.savedSysPath
+            if testFileName:
+                sys.path = [os.path.dirname(os.path.abspath(testFileName))] + \
+                    self.savedSysPath
             
             # clean up list of imported modules to force a reimport upon
             # running the test
@@ -432,22 +477,23 @@
                         return
                     
                     test = unittest.defaultTestLoader.discover(discoveryStart)
+#                    testsList = self.__assembleTestCasesList(test)
                 else:
-                    module = __import__(self.testName)
-                    try:
-                        if failedOnly and self.__failedTests:
-                            test = \
-                                unittest.defaultTestLoader.loadTestsFromNames(
-                                    [t.split(".", 1)[1]
-                                     for t in self.__failedTests],
-                                    module)
+                    if testFileName:
+                        module = __import__(self.testName)
+                    else:
+                        module = None
+                    if failedOnly and self.__failedTests:
+                        if module:
+                            failed = [t.split(".", 1)[1]
+                                      for t in self.__failedTests]
                         else:
-                            test = \
-                                unittest.defaultTestLoader.loadTestsFromName(
-                                    testFunctionName, module)
-                    except AttributeError:
-                        test = unittest.defaultTestLoader.loadTestsFromModule(
-                            module)
+                            failed = self.__failedTests[:]
+                        test = unittest.defaultTestLoader.loadTestsFromNames(
+                            failed, module)
+                    else:
+                        test = unittest.defaultTestLoader.loadTestsFromName(
+                            testName, module)
             except Exception:
                 exc_type, exc_value, exc_tb = sys.exc_info()
                 E5MessageBox.critical(
@@ -464,8 +510,9 @@
             if self.coverageCheckBox.isChecked():
                 if discover:
                     covname = os.path.join(discoveryStart, "unittest")
-                elif prog:
-                    covname = os.path.splitext(os.path.abspath(prog))[0]
+                elif testFileName:
+                    covname = \
+                        os.path.splitext(os.path.abspath(testFileName))[0]
                 else:
                     covname = "unittest"
                 
@@ -489,6 +536,25 @@
             self.__setStoppedMode()
             sys.path = self.savedSysPath
     
+    def __assembleTestCasesList(self, suite):
+        """
+        Private method to assemble a list of test cases included in a test
+        suite.
+        
+        @param suite test suite to be inspected
+        @type unittest.TestSuite
+        @return list of tuples containing the test case ID and short
+            description
+        @rtype list of tuples of (str, str)
+        """
+        testCases = []
+        for test in suite:
+            if isinstance(test, unittest.TestSuite):
+                testCases.extend(self.__assembleTestCasesList(test))
+            else:
+                testCases.append((test.id(), test.shortDescription()))
+        return testCases
+    
     def __UTPrepared(self, nrTests, exc_type, exc_value):
         """
         Private slot to handle the utPrepared signal.
@@ -514,7 +580,7 @@
         self.__dbs.remoteUTRun()
     
     @pyqtSlot()
-    def on_stopButton_clicked(self):
+    def __stopTests(self):
         """
         Private slot to stop the test.
         """
@@ -925,6 +991,9 @@
         
         self.setStyle(Preferences.getUI("Style"),
                       Preferences.getUI("StyleSheet"))
+        
+        self.cw.buttonBox.accepted.connect(self.close)
+        self.cw.buttonBox.rejected.connect(self.close)
     
     def eventFilter(self, obj, event):
         """

eric ide

mercurial