73 self.discoveryPicker.setMode(E5PathPickerModes.DirectoryMode) |
73 self.discoveryPicker.setMode(E5PathPickerModes.DirectoryMode) |
74 self.discoveryPicker.setInsertPolicy(QComboBox.InsertAtTop) |
74 self.discoveryPicker.setInsertPolicy(QComboBox.InsertAtTop) |
75 self.discoveryPicker.setSizeAdjustPolicy( |
75 self.discoveryPicker.setSizeAdjustPolicy( |
76 QComboBox.AdjustToMinimumContentsLength) |
76 QComboBox.AdjustToMinimumContentsLength) |
77 |
77 |
78 # TODO: add a "Discover" button enabled upon selection of 'auto-discovery' |
|
79 self.discoverButton = self.buttonBox.addButton( |
78 self.discoverButton = self.buttonBox.addButton( |
80 self.tr("Discover"), QDialogButtonBox.ActionRole) |
79 self.tr("Discover"), QDialogButtonBox.ActionRole) |
81 self.discoverButton.setToolTip(self.tr( |
80 self.discoverButton.setToolTip(self.tr( |
82 "Discover tests")) |
81 "Discover tests")) |
83 self.discoverButton.setWhatsThis(self.tr( |
82 self.discoverButton.setWhatsThis(self.tr( |
159 |
158 |
160 self.__failedTests = [] |
159 self.__failedTests = [] |
161 |
160 |
162 # now connect the debug server signals if called from the eric6 IDE |
161 # now connect the debug server signals if called from the eric6 IDE |
163 if self.__dbs: |
162 if self.__dbs: |
|
163 self.__dbs.utDiscovered.connect(self.__UTDiscovered) |
164 self.__dbs.utPrepared.connect(self.__UTPrepared) |
164 self.__dbs.utPrepared.connect(self.__UTPrepared) |
165 self.__dbs.utFinished.connect(self.__setStoppedMode) |
165 self.__dbs.utFinished.connect(self.__setStoppedMode) |
166 self.__dbs.utStartTest.connect(self.testStarted) |
166 self.__dbs.utStartTest.connect(self.testStarted) |
167 self.__dbs.utStopTest.connect(self.testFinished) |
167 self.__dbs.utStopTest.connect(self.testFinished) |
168 self.__dbs.utTestFailed.connect(self.testFailed) |
168 self.__dbs.utTestFailed.connect(self.testFailed) |
219 self.insertDiscovery(project.getProjectPath()) |
219 self.insertDiscovery(project.getProjectPath()) |
220 else: |
220 else: |
221 self.insertDiscovery("") |
221 self.insertDiscovery("") |
222 else: |
222 else: |
223 self.insertDiscovery("") |
223 self.insertDiscovery("") |
|
224 |
|
225 self.discoveryList.clear() |
|
226 self.tabWidget.setCurrentIndex(0) |
224 |
227 |
225 def insertDiscovery(self, start): |
228 def insertDiscovery(self, start): |
226 """ |
229 """ |
227 Public slot to insert the discovery start directory into the |
230 Public slot to insert the discovery start directory into the |
228 discoveryPicker object. |
231 discoveryPicker object. |
367 self.sbLabel.setText(self.tr("Discovering Tests")) |
370 self.sbLabel.setText(self.tr("Discovering Tests")) |
368 QApplication.processEvents() |
371 QApplication.processEvents() |
369 |
372 |
370 self.testName = self.tr("Unittest with auto-discovery") |
373 self.testName = self.tr("Unittest with auto-discovery") |
371 if self.__dbs: |
374 if self.__dbs: |
372 # TODO: implement this later |
375 venvName = self.venvComboBox.currentText() |
373 pass |
376 |
|
377 # we are cooperating with the eric6 IDE |
|
378 project = e5App().getObject("Project") |
|
379 if self.__forProject: |
|
380 mainScript = os.path.abspath(project.getMainScript(True)) |
|
381 clientType = project.getProjectLanguage() |
|
382 if mainScript: |
|
383 workdir = os.path.dirname(mainScript) |
|
384 else: |
|
385 workdir = project.getProjectPath() |
|
386 sysPath = [workdir] |
|
387 if not discoveryStart: |
|
388 discoveryStart = workdir |
|
389 else: |
|
390 if not discoveryStart: |
|
391 E5MessageBox.critical( |
|
392 self, |
|
393 self.tr("Unittest"), |
|
394 self.tr("You must enter a start directory for" |
|
395 " auto-discovery.")) |
|
396 return |
|
397 |
|
398 workdir = "" |
|
399 clientType = \ |
|
400 self.__venvManager.getVirtualenvVariant(venvName) |
|
401 if not clientType: |
|
402 # assume Python 3 |
|
403 clientType = "Python3" |
|
404 self.__dbs.remoteUTDiscover(clientType, self.__forProject, |
|
405 workdir, venvName, sysPath, |
|
406 discoveryStart) |
374 else: |
407 else: |
375 # we are running as an application |
408 # we are running as an application |
376 if not discoveryStart: |
409 if not discoveryStart: |
377 E5MessageBox.critical( |
410 E5MessageBox.critical( |
378 self, |
411 self, |
397 # now try to discover the testsuite |
430 # now try to discover the testsuite |
398 os.chdir(discoveryStart) |
431 os.chdir(discoveryStart) |
399 try: |
432 try: |
400 testLoader = unittest.TestLoader() |
433 testLoader = unittest.TestLoader() |
401 test = testLoader.discover(discoveryStart) |
434 test = testLoader.discover(discoveryStart) |
402 if test: |
435 if hasattr(testLoader, "errors") and \ |
403 if hasattr(testLoader, "errors") and \ |
436 bool(testLoader.errors): |
404 bool(testLoader.errors): |
437 E5MessageBox.critical( |
405 E5MessageBox.critical( |
438 self, |
406 self, |
439 self.tr("Unittest"), |
407 self.tr("Unittest"), |
440 self.tr( |
408 self.tr( |
441 "<p>Unable to discover tests.</p>" |
409 "<p>Unable to discover tests.</p>" |
442 "<p>{0}</p>" |
410 "<p>{0}</p>" |
443 ).format("<br/>".join(testLoader.errors) |
411 ).format("<br/>".join(testLoader.errors) |
444 .replace("\n", "<br/>")) |
412 .replace("\n", "<br/>")) |
445 ) |
413 ) |
446 self.sbLabel.clear() |
414 self.sbLabel.clear() |
447 else: |
415 else: |
448 testsList = self.__assembleTestCasesList(test) |
416 testsList = self.__assembleTestCasesList(test) |
449 self.__populateDiscoveryResults(testsList) |
417 self.__populateDiscoveryResults(testsList) |
450 self.sbLabel.setText( |
418 self.sbLabel.setText( |
451 self.tr("Discovered %n Test(s)", "", |
419 self.tr("Discovered %n Test(s)", "", |
452 len(testsList))) |
420 len(testsList))) |
453 self.tabWidget.setCurrentIndex(0) |
421 self.tabWidget.setCurrentIndex(0) |
|
422 except Exception: |
454 except Exception: |
423 exc_type, exc_value, exc_tb = sys.exc_info() |
455 exc_type, exc_value, exc_tb = sys.exc_info() |
424 E5MessageBox.critical( |
456 E5MessageBox.critical( |
425 self, |
457 self, |
426 self.tr("Unittest"), |
458 self.tr("Unittest"), |
500 itm.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) |
532 itm.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) |
501 itm.setCheckState(0, Qt.Unchecked) |
533 itm.setCheckState(0, Qt.Unchecked) |
502 itm.setData(0, Qt.UserRole, modulePath) |
534 itm.setData(0, Qt.UserRole, modulePath) |
503 pitm = itm |
535 pitm = itm |
504 |
536 |
|
537 def __selectedTestCases(self, parent=None): |
|
538 """ |
|
539 Private method to assemble the list of selected test cases and suites. |
|
540 |
|
541 @param parent reference to the parent item |
|
542 @type QTreeWidgetItem |
|
543 @return list of selected test cases |
|
544 @rtype list of str |
|
545 """ |
|
546 selectedTests = [] |
|
547 if parent is None: |
|
548 # top level |
|
549 for index in range(self.discoveryList.topLevelItemCount()): |
|
550 itm = self.discoveryList.topLevelItem(index) |
|
551 if itm.checkState(0) == Qt.Checked: |
|
552 selectedTests.append(itm.data(0, Qt.UserRole)) |
|
553 # ignore children because they are included implicitly |
|
554 elif itm.childCount(): |
|
555 # recursively check children |
|
556 selectedTests.extend(self.__selectedTestCases(itm)) |
|
557 |
|
558 else: |
|
559 # parent item with children |
|
560 for index in range(parent.childCount()): |
|
561 itm = parent.child(index) |
|
562 if itm.checkState(0) == Qt.Checked: |
|
563 selectedTests.append(itm.data(0, Qt.UserRole)) |
|
564 # ignore children because they are included implicitly |
|
565 elif itm.childCount(): |
|
566 # recursively check children |
|
567 selectedTests.extend(self.__selectedTestCases(itm)) |
|
568 |
|
569 return selectedTests |
|
570 |
|
571 def __UTDiscovered(self, testCases, exc_type, exc_value): |
|
572 """ |
|
573 Private slot to handle the utPrepared signal. |
|
574 |
|
575 If the unittest suite was loaded successfully, we ask the |
|
576 client to run the test suite. |
|
577 |
|
578 @param testCases list of detected test cases |
|
579 @type str |
|
580 @param exc_type exception type occured during discovery |
|
581 @type str |
|
582 @param exc_value value of exception occured during discovery |
|
583 @type str |
|
584 """ |
|
585 if testCases: |
|
586 self.__populateDiscoveryResults(testCases) |
|
587 self.sbLabel.setText( |
|
588 self.tr("Discovered %n Test(s)", "", |
|
589 len(testCases))) |
|
590 self.tabWidget.setCurrentIndex(0) |
|
591 else: |
|
592 E5MessageBox.critical( |
|
593 self, |
|
594 self.tr("Unittest"), |
|
595 self.tr("<p>Unable to discover tests.</p>" |
|
596 "<p>{0}<br>{1}</p>") |
|
597 .format(exc_type, exc_value.replace("\n", "<br/>")) |
|
598 ) |
|
599 |
505 @pyqtSlot() |
600 @pyqtSlot() |
506 def startTests(self, failedOnly=False): |
601 def startTests(self, failedOnly=False): |
507 """ |
602 """ |
508 Public slot to start the test. |
603 Public slot to start the test. |
509 |
604 |
618 testFileName, self.testName, testName, failed, |
718 testFileName, self.testName, testName, failed, |
619 self.coverageCheckBox.isChecked(), coverageFile, |
719 self.coverageCheckBox.isChecked(), coverageFile, |
620 self.coverageEraseCheckBox.isChecked(), clientType=clientType, |
720 self.coverageEraseCheckBox.isChecked(), clientType=clientType, |
621 forProject=self.__forProject, workdir=workdir, |
721 forProject=self.__forProject, workdir=workdir, |
622 venvName=venvName, syspath=sysPath, |
722 venvName=venvName, syspath=sysPath, |
623 discover=discover, discoveryStart=discoveryStart) |
723 discover=discover, discoveryStart=discoveryStart, |
|
724 testCases=testCases) |
624 else: |
725 else: |
625 # we are running as an application |
726 # we are running as an application |
626 if discover and not discoveryStart: |
727 if discover and not discoveryStart: |
627 E5MessageBox.critical( |
728 E5MessageBox.critical( |
628 self, |
729 self, |