diff -r 938039ea15ca -r eab09a1ab8ce eric7/Testing/TestingWidget.py --- a/eric7/Testing/TestingWidget.py Tue May 17 14:21:13 2022 +0200 +++ b/eric7/Testing/TestingWidget.py Tue May 17 17:23:07 2022 +0200 @@ -50,8 +50,6 @@ STOPPED = 2 # test run finished -# TODO: add a "Show Coverage" function using PyCoverageDialog - class TestingWidget(QWidget, Ui_TestingWidget): """ Class implementing a widget to orchestrate unit test execution. @@ -102,6 +100,16 @@ self.testComboBox.lineEdit().setClearButtonEnabled(True) # create some more dialog buttons for orchestration + self.__showCoverageButton = self.buttonBox.addButton( + self.tr("Show Coverage..."), + QDialogButtonBox.ButtonRole.ActionRole) + self.__showCoverageButton.setToolTip( + self.tr("Show code coverage in a new dialog")) + self.__showCoverageButton.setWhatsThis(self.tr( + """<b>Show Coverage...</b>""" + """<p>This button opens a dialog containing the collected code""" + """ coverage data.</p>""")) + self.__startButton = self.buttonBox.addButton( self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole) @@ -160,6 +168,9 @@ self.__recentEnvironment = "" self.__failedTests = [] + self.__coverageFile = "" + self.__coverageDialog = None + self.__editors = [] self.__testExecutor = None @@ -477,6 +488,17 @@ self.__stopButton.setDefault( self.__mode == TestingWidgetModes.RUNNING) + # Code coverage button + self.__showCoverageButton.setEnabled( + self.__mode == TestingWidgetModes.STOPPED and + bool(self.__coverageFile) and + ( + (self.discoverCheckBox.isChecked() and + bool(self.discoveryPicker.currentText())) or + bool(self.testsuitePicker.currentText()) + ) + ) + # Close button self.buttonBox.button( QDialogButtonBox.StandardButton.Close @@ -517,7 +539,6 @@ self.__runCount = 0 self.__coverageFile = "" - # TODO: implement the handling of the 'Show Coverage' button self.sbLabel.setText(self.tr("Running")) self.tabWidget.setCurrentIndex(1) @@ -605,6 +626,8 @@ self.__stopTests() elif button == self.__startFailedButton: self.startTests(failedOnly=True) + elif button == self.__showCoverageButton: + self.__showCoverageDialog() @pyqtSlot(int) def on_venvComboBox_currentIndexChanged(self, index): @@ -703,11 +726,16 @@ self.sbLabel.setText(self.tr("Preparing Testsuite")) QCoreApplication.processEvents() + if self.__project: + mainScript = self.__project.getMainScript(True) + coverageFile = os.path.splitext(mainScript)[0] + ".coverage" + else: + coverageFile = "" interpreter = self.__venvManager.getVirtualenvInterpreter( self.__recentEnvironment) config = TestConfig( interpreter=interpreter, - discover=self.discoverCheckBox.isChecked(), + discover=discover, discoveryStart=discoveryStart, testFilename=testFileName, testName=testName, @@ -715,6 +743,7 @@ failedOnly=failedOnly, collectCoverage=self.coverageCheckBox.isChecked(), eraseCoverage=self.coverageEraseCheckBox.isChecked(), + coverageFile=coverageFile, ) self.__testExecutor = self.__frameworkRegistry.createExecutor( @@ -888,8 +917,25 @@ @type str """ self.__coverageFile = coverageFile + + @pyqtSlot() + def __showCoverageDialog(self): + """ + Private slot to show a code coverage dialog for the most recent test + run. + """ + if self.__coverageDialog is None: + from DataViews.PyCoverageDialog import PyCoverageDialog + self.__coverageDialog = PyCoverageDialog(self) + self.__coverageDialog.openFile.connect(self.__openEditor) - # TODO: implement the handling of the 'Show Coverage' button + if self.discoverCheckBox.isChecked(): + testDir = self.discoveryPicker.currentText() + else: + testDir = os.path.dirname(self.testsuitePicker.currentText()) + if testDir: + self.__coverageDialog.show() + self.__coverageDialog.start(self.__coverageFile, testDir) @pyqtSlot(str) def __setStatusLabel(self, statusText): @@ -936,7 +982,7 @@ else: self.__openEditor(filename, lineno) - def __openEditor(self, filename, linenumber): + def __openEditor(self, filename, linenumber=1): """ Private method to open an editor window for the given file. @@ -945,8 +991,8 @@ @param filename path of the file to be opened @type str - @param linenumber line number to place the cursor at - @type int + @param linenumber line number to place the cursor at (defaults to 1) + @type int (optional) """ from QScintilla.MiniEditor import MiniEditor editor = MiniEditor(filename, "Python3", self)