PyUnit/UnittestDialog.py

changeset 6901
f2c774c8db7e
parent 6900
060a30488316
child 6902
67d0ad66b59a
--- a/PyUnit/UnittestDialog.py	Mon Mar 25 20:18:47 2019 +0100
+++ b/PyUnit/UnittestDialog.py	Tue Mar 26 19:29:30 2019 +0100
@@ -75,7 +75,6 @@
         self.discoveryPicker.setSizeAdjustPolicy(
             QComboBox.AdjustToMinimumContentsLength)
         
-        # TODO: add a "Discover" button enabled upon selection of 'auto-discovery'
         self.discoverButton = self.buttonBox.addButton(
             self.tr("Discover"), QDialogButtonBox.ActionRole)
         self.discoverButton.setToolTip(self.tr(
@@ -161,6 +160,7 @@
         
         # now connect the debug server signals if called from the eric6 IDE
         if self.__dbs:
+            self.__dbs.utDiscovered.connect(self.__UTDiscovered)
             self.__dbs.utPrepared.connect(self.__UTPrepared)
             self.__dbs.utFinished.connect(self.__setStoppedMode)
             self.__dbs.utStartTest.connect(self.testStarted)
@@ -221,6 +221,9 @@
                 self.insertDiscovery("")
         else:
             self.insertDiscovery("")
+        
+        self.discoveryList.clear()
+        self.tabWidget.setCurrentIndex(0)
     
     def insertDiscovery(self, start):
         """
@@ -369,8 +372,38 @@
         
         self.testName = self.tr("Unittest with auto-discovery")
         if self.__dbs:
-            # TODO: implement this later
-            pass
+            venvName = self.venvComboBox.currentText()
+            
+            # we are cooperating with the eric6 IDE
+            project = e5App().getObject("Project")
+            if self.__forProject:
+                mainScript = os.path.abspath(project.getMainScript(True))
+                clientType = project.getProjectLanguage()
+                if mainScript:
+                    workdir = os.path.dirname(mainScript)
+                else:
+                    workdir = project.getProjectPath()
+                sysPath = [workdir]
+                if not discoveryStart:
+                    discoveryStart = workdir
+            else:
+                if not discoveryStart:
+                    E5MessageBox.critical(
+                        self,
+                        self.tr("Unittest"),
+                        self.tr("You must enter a start directory for"
+                                " auto-discovery."))
+                    return
+                
+                workdir = ""
+                clientType = \
+                    self.__venvManager.getVirtualenvVariant(venvName)
+                if not clientType:
+                    # assume Python 3
+                    clientType = "Python3"
+            self.__dbs.remoteUTDiscover(clientType, self.__forProject,
+                                        workdir, venvName, sysPath,
+                                        discoveryStart)
         else:
             # we are running as an application
             if not discoveryStart:
@@ -399,26 +432,25 @@
             try:
                 testLoader = unittest.TestLoader()
                 test = testLoader.discover(discoveryStart)
-                if test:
-                    if hasattr(testLoader, "errors") and \
-                       bool(testLoader.errors):
-                        E5MessageBox.critical(
-                            self,
-                            self.tr("Unittest"),
-                            self.tr(
-                                "<p>Unable to discover tests.</p>"
-                                "<p>{0}</p>"
-                            ).format("<br/>".join(testLoader.errors)
-                                     .replace("\n", "<br/>"))
-                        )
-                        self.sbLabel.clear()
-                    else:
-                        testsList = self.__assembleTestCasesList(test)
-                        self.__populateDiscoveryResults(testsList)
-                        self.sbLabel.setText(
-                            self.tr("Discovered %n Test(s)", "",
-                                    len(testsList)))
-                        self.tabWidget.setCurrentIndex(0)
+                if hasattr(testLoader, "errors") and \
+                   bool(testLoader.errors):
+                    E5MessageBox.critical(
+                        self,
+                        self.tr("Unittest"),
+                        self.tr(
+                            "<p>Unable to discover tests.</p>"
+                            "<p>{0}</p>"
+                        ).format("<br/>".join(testLoader.errors)
+                                 .replace("\n", "<br/>"))
+                    )
+                    self.sbLabel.clear()
+                else:
+                    testsList = self.__assembleTestCasesList(test)
+                    self.__populateDiscoveryResults(testsList)
+                    self.sbLabel.setText(
+                        self.tr("Discovered %n Test(s)", "",
+                                len(testsList)))
+                    self.tabWidget.setCurrentIndex(0)
             except Exception:
                 exc_type, exc_value, exc_tb = sys.exc_info()
                 E5MessageBox.critical(
@@ -502,6 +534,69 @@
                     itm.setData(0, Qt.UserRole, modulePath)
                     pitm = itm
     
+    def __selectedTestCases(self, parent=None):
+        """
+        Private method to assemble the list of selected test cases and suites.
+        
+        @param parent reference to the parent item
+        @type QTreeWidgetItem
+        @return list of selected test cases
+        @rtype list of str
+        """
+        selectedTests = []
+        if parent is None:
+            # top level
+            for index in range(self.discoveryList.topLevelItemCount()):
+                itm = self.discoveryList.topLevelItem(index)
+                if itm.checkState(0) == Qt.Checked:
+                    selectedTests.append(itm.data(0, Qt.UserRole))
+                    # ignore children because they are included implicitly
+                elif itm.childCount():
+                    # recursively check children
+                    selectedTests.extend(self.__selectedTestCases(itm))
+        
+        else:
+            # parent item with children
+            for index in range(parent.childCount()):
+                itm = parent.child(index)
+                if itm.checkState(0) == Qt.Checked:
+                    selectedTests.append(itm.data(0, Qt.UserRole))
+                    # ignore children because they are included implicitly
+                elif itm.childCount():
+                    # recursively check children
+                    selectedTests.extend(self.__selectedTestCases(itm))
+        
+        return selectedTests
+    
+    def __UTDiscovered(self, testCases, exc_type, exc_value):
+        """
+        Private slot to handle the utPrepared signal.
+        
+        If the unittest suite was loaded successfully, we ask the
+        client to run the test suite.
+        
+        @param testCases list of detected test cases
+        @type str
+        @param exc_type exception type occured during discovery
+        @type str
+        @param exc_value value of exception occured during discovery
+        @type str
+        """
+        if testCases:
+            self.__populateDiscoveryResults(testCases)
+            self.sbLabel.setText(
+                self.tr("Discovered %n Test(s)", "",
+                        len(testCases)))
+            self.tabWidget.setCurrentIndex(0)
+        else:
+            E5MessageBox.critical(
+                self,
+                self.tr("Unittest"),
+                self.tr("<p>Unable to discover tests.</p>"
+                        "<p>{0}<br>{1}</p>")
+                .format(exc_type, exc_value.replace("\n", "<br/>"))
+            )
+    
     @pyqtSlot()
     def startTests(self, failedOnly=False):
         """
@@ -551,6 +646,11 @@
             else:
                 self.testName = self.tr("<Unnamed Test>")
         
+        if failedOnly:
+            testCases = []
+        else:
+            testCases = self.__selectedTestCases()
+        
         if self.__dbs:
             venvName = self.venvComboBox.currentText()
             
@@ -620,7 +720,8 @@
                 self.coverageEraseCheckBox.isChecked(), clientType=clientType,
                 forProject=self.__forProject, workdir=workdir,
                 venvName=venvName, syspath=sysPath,
-                discover=discover, discoveryStart=discoveryStart)
+                discover=discover, discoveryStart=discoveryStart,
+                testCases=testCases)
         else:
             # we are running as an application
             if discover and not discoveryStart:
@@ -660,7 +761,10 @@
                 else:
                     failed = []
                 if discover:
-                    test = testLoader.discover(discoveryStart)
+                    if testCases:
+                        test = testLoader.loadTestsFromNames(testCases)
+                    else:
+                        test = testLoader.discover(discoveryStart)
                 else:
                     if testFileName:
                         module = __import__(self.testName)

eric ide

mercurial