eric7/Testing/TestingWidget.py

branch
unittest
changeset 9070
eab09a1ab8ce
parent 9066
a219ade50f7c
child 9072
8d3ae97ee666
equal deleted inserted replaced
9069:938039ea15ca 9070:eab09a1ab8ce
48 IDLE = 0 # idle, no test were run yet 48 IDLE = 0 # idle, no test were run yet
49 RUNNING = 1 # test run being performed 49 RUNNING = 1 # test run being performed
50 STOPPED = 2 # test run finished 50 STOPPED = 2 # test run finished
51 51
52 52
53 # TODO: add a "Show Coverage" function using PyCoverageDialog
54
55 class TestingWidget(QWidget, Ui_TestingWidget): 53 class TestingWidget(QWidget, Ui_TestingWidget):
56 """ 54 """
57 Class implementing a widget to orchestrate unit test execution. 55 Class implementing a widget to orchestrate unit test execution.
58 56
59 @signal testFile(str, int, bool) emitted to show the source of a 57 @signal testFile(str, int, bool) emitted to show the source of a
100 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) 98 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
101 99
102 self.testComboBox.lineEdit().setClearButtonEnabled(True) 100 self.testComboBox.lineEdit().setClearButtonEnabled(True)
103 101
104 # create some more dialog buttons for orchestration 102 # create some more dialog buttons for orchestration
103 self.__showCoverageButton = self.buttonBox.addButton(
104 self.tr("Show Coverage..."),
105 QDialogButtonBox.ButtonRole.ActionRole)
106 self.__showCoverageButton.setToolTip(
107 self.tr("Show code coverage in a new dialog"))
108 self.__showCoverageButton.setWhatsThis(self.tr(
109 """<b>Show Coverage...</b>"""
110 """<p>This button opens a dialog containing the collected code"""
111 """ coverage data.</p>"""))
112
105 self.__startButton = self.buttonBox.addButton( 113 self.__startButton = self.buttonBox.addButton(
106 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole) 114 self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole)
107 115
108 self.__startButton.setToolTip(self.tr( 116 self.__startButton.setToolTip(self.tr(
109 "Start the selected testsuite")) 117 "Start the selected testsuite"))
157 self.__fileHistory = [] 165 self.__fileHistory = []
158 self.__testNameHistory = [] 166 self.__testNameHistory = []
159 self.__recentFramework = "" 167 self.__recentFramework = ""
160 self.__recentEnvironment = "" 168 self.__recentEnvironment = ""
161 self.__failedTests = [] 169 self.__failedTests = []
170
171 self.__coverageFile = ""
172 self.__coverageDialog = None
162 173
163 self.__editors = [] 174 self.__editors = []
164 self.__testExecutor = None 175 self.__testExecutor = None
165 176
166 # connect some signals 177 # connect some signals
475 self.__stopButton.setEnabled( 486 self.__stopButton.setEnabled(
476 self.__mode == TestingWidgetModes.RUNNING) 487 self.__mode == TestingWidgetModes.RUNNING)
477 self.__stopButton.setDefault( 488 self.__stopButton.setDefault(
478 self.__mode == TestingWidgetModes.RUNNING) 489 self.__mode == TestingWidgetModes.RUNNING)
479 490
491 # Code coverage button
492 self.__showCoverageButton.setEnabled(
493 self.__mode == TestingWidgetModes.STOPPED and
494 bool(self.__coverageFile) and
495 (
496 (self.discoverCheckBox.isChecked() and
497 bool(self.discoveryPicker.currentText())) or
498 bool(self.testsuitePicker.currentText())
499 )
500 )
501
480 # Close button 502 # Close button
481 self.buttonBox.button( 503 self.buttonBox.button(
482 QDialogButtonBox.StandardButton.Close 504 QDialogButtonBox.StandardButton.Close
483 ).setEnabled(self.__mode in ( 505 ).setEnabled(self.__mode in (
484 TestingWidgetModes.IDLE, TestingWidgetModes.STOPPED 506 TestingWidgetModes.IDLE, TestingWidgetModes.STOPPED
515 537
516 self.__totalCount = 0 538 self.__totalCount = 0
517 self.__runCount = 0 539 self.__runCount = 0
518 540
519 self.__coverageFile = "" 541 self.__coverageFile = ""
520 # TODO: implement the handling of the 'Show Coverage' button
521 542
522 self.sbLabel.setText(self.tr("Running")) 543 self.sbLabel.setText(self.tr("Running"))
523 self.tabWidget.setCurrentIndex(1) 544 self.tabWidget.setCurrentIndex(1)
524 self.__updateButtonBoxButtons() 545 self.__updateButtonBoxButtons()
525 self.__updateProgress() 546 self.__updateProgress()
603 self.__saveRecent() 624 self.__saveRecent()
604 elif button == self.__stopButton: 625 elif button == self.__stopButton:
605 self.__stopTests() 626 self.__stopTests()
606 elif button == self.__startFailedButton: 627 elif button == self.__startFailedButton:
607 self.startTests(failedOnly=True) 628 self.startTests(failedOnly=True)
629 elif button == self.__showCoverageButton:
630 self.__showCoverageDialog()
608 631
609 @pyqtSlot(int) 632 @pyqtSlot(int)
610 def on_venvComboBox_currentIndexChanged(self, index): 633 def on_venvComboBox_currentIndexChanged(self, index):
611 """ 634 """
612 Private slot handling the selection of a virtual environment. 635 Private slot handling the selection of a virtual environment.
701 testName = "suite" 724 testName = "suite"
702 725
703 self.sbLabel.setText(self.tr("Preparing Testsuite")) 726 self.sbLabel.setText(self.tr("Preparing Testsuite"))
704 QCoreApplication.processEvents() 727 QCoreApplication.processEvents()
705 728
729 if self.__project:
730 mainScript = self.__project.getMainScript(True)
731 coverageFile = os.path.splitext(mainScript)[0] + ".coverage"
732 else:
733 coverageFile = ""
706 interpreter = self.__venvManager.getVirtualenvInterpreter( 734 interpreter = self.__venvManager.getVirtualenvInterpreter(
707 self.__recentEnvironment) 735 self.__recentEnvironment)
708 config = TestConfig( 736 config = TestConfig(
709 interpreter=interpreter, 737 interpreter=interpreter,
710 discover=self.discoverCheckBox.isChecked(), 738 discover=discover,
711 discoveryStart=discoveryStart, 739 discoveryStart=discoveryStart,
712 testFilename=testFileName, 740 testFilename=testFileName,
713 testName=testName, 741 testName=testName,
714 failFast=self.failfastCheckBox.isChecked(), 742 failFast=self.failfastCheckBox.isChecked(),
715 failedOnly=failedOnly, 743 failedOnly=failedOnly,
716 collectCoverage=self.coverageCheckBox.isChecked(), 744 collectCoverage=self.coverageCheckBox.isChecked(),
717 eraseCoverage=self.coverageEraseCheckBox.isChecked(), 745 eraseCoverage=self.coverageEraseCheckBox.isChecked(),
746 coverageFile=coverageFile,
718 ) 747 )
719 748
720 self.__testExecutor = self.__frameworkRegistry.createExecutor( 749 self.__testExecutor = self.__frameworkRegistry.createExecutor(
721 self.__recentFramework, self) 750 self.__recentFramework, self)
722 self.__testExecutor.collected.connect(self.__testsCollected) 751 self.__testExecutor.collected.connect(self.__testsCollected)
886 915
887 @param coverageFile file containing the coverage data 916 @param coverageFile file containing the coverage data
888 @type str 917 @type str
889 """ 918 """
890 self.__coverageFile = coverageFile 919 self.__coverageFile = coverageFile
891 920
892 # TODO: implement the handling of the 'Show Coverage' button 921 @pyqtSlot()
922 def __showCoverageDialog(self):
923 """
924 Private slot to show a code coverage dialog for the most recent test
925 run.
926 """
927 if self.__coverageDialog is None:
928 from DataViews.PyCoverageDialog import PyCoverageDialog
929 self.__coverageDialog = PyCoverageDialog(self)
930 self.__coverageDialog.openFile.connect(self.__openEditor)
931
932 if self.discoverCheckBox.isChecked():
933 testDir = self.discoveryPicker.currentText()
934 else:
935 testDir = os.path.dirname(self.testsuitePicker.currentText())
936 if testDir:
937 self.__coverageDialog.show()
938 self.__coverageDialog.start(self.__coverageFile, testDir)
893 939
894 @pyqtSlot(str) 940 @pyqtSlot(str)
895 def __setStatusLabel(self, statusText): 941 def __setStatusLabel(self, statusText):
896 """ 942 """
897 Private slot to set the status label to the text sent by the model. 943 Private slot to set the status label to the text sent by the model.
934 # running as part of eric IDE 980 # running as part of eric IDE
935 self.testFile.emit(filename, lineno, True) 981 self.testFile.emit(filename, lineno, True)
936 else: 982 else:
937 self.__openEditor(filename, lineno) 983 self.__openEditor(filename, lineno)
938 984
939 def __openEditor(self, filename, linenumber): 985 def __openEditor(self, filename, linenumber=1):
940 """ 986 """
941 Private method to open an editor window for the given file. 987 Private method to open an editor window for the given file.
942 988
943 Note: This method opens an editor window when the testing dialog 989 Note: This method opens an editor window when the testing dialog
944 is called as a standalone application. 990 is called as a standalone application.
945 991
946 @param filename path of the file to be opened 992 @param filename path of the file to be opened
947 @type str 993 @type str
948 @param linenumber line number to place the cursor at 994 @param linenumber line number to place the cursor at (defaults to 1)
949 @type int 995 @type int (optional)
950 """ 996 """
951 from QScintilla.MiniEditor import MiniEditor 997 from QScintilla.MiniEditor import MiniEditor
952 editor = MiniEditor(filename, "Python3", self) 998 editor = MiniEditor(filename, "Python3", self)
953 editor.gotoLine(linenumber) 999 editor.gotoLine(linenumber)
954 editor.show() 1000 editor.show()

eric ide

mercurial