src/eric7/Testing/TestingWidget.py

branch
eric7-maintenance
changeset 9442
906485dcd210
parent 9371
1da8bc75946f
parent 9413
80c06d472826
child 9549
67295777d9fe
equal deleted inserted replaced
9379:f23c43e18046 9442:906485dcd210
13 import os 13 import os
14 14
15 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent, QCoreApplication 15 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent, QCoreApplication
16 from PyQt6.QtWidgets import QAbstractButton, QComboBox, QDialogButtonBox, QWidget 16 from PyQt6.QtWidgets import QAbstractButton, QComboBox, QDialogButtonBox, QWidget
17 17
18 from EricWidgets import EricMessageBox 18 from eric7.EricWidgets import EricMessageBox
19 from EricWidgets.EricApplication import ericApp 19 from eric7.EricWidgets.EricApplication import ericApp
20 from EricWidgets.EricMainWindow import EricMainWindow 20 from eric7.EricWidgets.EricMainWindow import EricMainWindow
21 from EricWidgets.EricPathPicker import EricPathPickerModes 21 from eric7.EricWidgets.EricPathPicker import EricPathPickerModes
22 22
23 from .Ui_TestingWidget import Ui_TestingWidget 23 from .Ui_TestingWidget import Ui_TestingWidget
24 24
25 from .TestResultsTree import TestResultsModel, TestResultsTreeView 25 from .TestResultsTree import TestResultsModel, TestResultsTreeView
26 from .Interfaces import Frameworks 26 from .Interfaces import Frameworks
27 from .Interfaces.TestExecutorBase import TestConfig, TestResult, TestResultCategory 27 from .Interfaces.TestExecutorBase import TestConfig, TestResult, TestResultCategory
28 from .Interfaces.TestFrameworkRegistry import TestFrameworkRegistry 28 from .Interfaces.TestFrameworkRegistry import TestFrameworkRegistry
29 29
30 import Preferences 30 from eric7 import Preferences
31 import UI.PixmapCache 31 from eric7.EricGui import EricPixmapCache
32 32
33 from Globals import ( 33 from eric7.Globals import (
34 recentNameTestDiscoverHistory, 34 recentNameTestDiscoverHistory,
35 recentNameTestFileHistory, 35 recentNameTestFileHistory,
36 recentNameTestNameHistory, 36 recentNameTestNameHistory,
37 recentNameTestFramework, 37 recentNameTestFramework,
38 recentNameTestEnvironment, 38 recentNameTestEnvironment,
78 self.__resultsTree = TestResultsTreeView(self) 78 self.__resultsTree = TestResultsTreeView(self)
79 self.__resultsTree.setModel(self.__resultsModel) 79 self.__resultsTree.setModel(self.__resultsModel)
80 self.__resultsTree.goto.connect(self.__showSource) 80 self.__resultsTree.goto.connect(self.__showSource)
81 self.resultsGroupBox.layout().addWidget(self.__resultsTree) 81 self.resultsGroupBox.layout().addWidget(self.__resultsTree)
82 82
83 self.versionsButton.setIcon(UI.PixmapCache.getIcon("info")) 83 self.versionsButton.setIcon(EricPixmapCache.getIcon("info"))
84 self.clearHistoriesButton.setIcon(UI.PixmapCache.getIcon("clearPrivateData")) 84 self.clearHistoriesButton.setIcon(EricPixmapCache.getIcon("clearPrivateData"))
85 self.showMarkersButton.setIcon(UI.PixmapCache.getIcon("select")) 85 self.showMarkersButton.setIcon(EricPixmapCache.getIcon("select"))
86 86
87 self.testsuitePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) 87 self.testsuitePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
88 self.testsuitePicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop) 88 self.testsuitePicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop)
89 self.testsuitePicker.setSizeAdjustPolicy( 89 self.testsuitePicker.setSizeAdjustPolicy(
90 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon 90 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon
163 ) 163 )
164 164
165 self.setWindowFlags( 165 self.setWindowFlags(
166 self.windowFlags() | Qt.WindowType.WindowContextHelpButtonHint 166 self.windowFlags() | Qt.WindowType.WindowContextHelpButtonHint
167 ) 167 )
168 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) 168 self.setWindowIcon(EricPixmapCache.getIcon("eric"))
169 self.setWindowTitle(self.tr("Testing")) 169 self.setWindowTitle(self.tr("Testing"))
170 170
171 try: 171 try:
172 # we are called from within the eric IDE 172 # we are called from within the eric IDE
173 self.__venvManager = ericApp().getObject("VirtualEnvManager") 173 self.__venvManager = ericApp().getObject("VirtualEnvManager")
174 self.__project = ericApp().getObject("Project") 174 self.__project = ericApp().getObject("Project")
175 self.__project.projectOpened.connect(self.__projectOpened) 175 self.__project.projectOpened.connect(self.__projectOpened)
176 self.__project.projectClosed.connect(self.__projectClosed) 176 self.__project.projectClosed.connect(self.__projectClosed)
177 self.__projectEnvironmentMarker = self.tr("<project>")
177 except KeyError: 178 except KeyError:
178 # we were called as a standalone application 179 # we were called as a standalone application
179 from VirtualEnv.VirtualenvManager import VirtualenvManager 180 from eric7.VirtualEnv.VirtualenvManager import VirtualenvManager
180 181
181 self.__venvManager = VirtualenvManager(self) 182 self.__venvManager = VirtualenvManager(self)
182 self.__venvManager.virtualEnvironmentAdded.connect( 183 self.__venvManager.virtualEnvironmentAdded.connect(
183 self.__populateVenvComboBox 184 self.__populateVenvComboBox
184 ) 185 )
189 self.__populateVenvComboBox 190 self.__populateVenvComboBox
190 ) 191 )
191 ericApp().registerObject("VirtualEnvManager", self.__venvManager) 192 ericApp().registerObject("VirtualEnvManager", self.__venvManager)
192 193
193 self.__project = None 194 self.__project = None
195 self.__projectEnvironmentMarker = ""
194 196
195 self.__discoverHistory = [] 197 self.__discoverHistory = []
196 self.__fileHistory = [] 198 self.__fileHistory = []
197 self.__testNameHistory = [] 199 self.__testNameHistory = []
198 self.__recentFramework = "" 200 self.__recentFramework = ""
236 238
237 self.clearHistoriesButton.clicked.connect(self.clearRecent) 239 self.clearHistoriesButton.clicked.connect(self.clearRecent)
238 240
239 self.tabWidget.setCurrentIndex(0) 241 self.tabWidget.setCurrentIndex(0)
240 242
243 def __determineInterpreter(self, venvName):
244 """
245 Private method to determine the interpreter to be used.
246
247 @param venvName name of the virtual environment
248 @type str
249 @return path of the interpreter executable
250 @rtype str
251 """
252 if self.__project and venvName == self.__projectEnvironmentMarker:
253 return self.__project.getProjectInterpreter()
254 else:
255 return self.__venvManager.getVirtualenvInterpreter(venvName)
256
241 def __populateVenvComboBox(self): 257 def __populateVenvComboBox(self):
242 """ 258 """
243 Private method to (re-)populate the virtual environments selector. 259 Private method to (re-)populate the virtual environments selector.
244 """ 260 """
245 currentText = self.venvComboBox.currentText() 261 currentText = self.venvComboBox.currentText()
246 if not currentText: 262 if not currentText:
247 currentText = self.__recentEnvironment 263 currentText = self.__recentEnvironment
248 264
249 self.venvComboBox.clear() 265 self.venvComboBox.clear()
250 self.venvComboBox.addItem("") 266 self.venvComboBox.addItem("")
267 if self.__project and self.__project.isOpen():
268 self.venvComboBox.addItem(self.__projectEnvironmentMarker)
251 self.venvComboBox.addItems(sorted(self.__venvManager.getVirtualenvNames())) 269 self.venvComboBox.addItems(sorted(self.__venvManager.getVirtualenvNames()))
252 self.venvComboBox.setCurrentText(currentText) 270 self.venvComboBox.setCurrentText(currentText)
253 271
254 def __populateTestFrameworkComboBox(self): 272 def __populateTestFrameworkComboBox(self):
255 """ 273 """
260 currentText = self.__recentFramework 278 currentText = self.__recentFramework
261 279
262 self.frameworkComboBox.clear() 280 self.frameworkComboBox.clear()
263 281
264 if bool(self.venvComboBox.currentText()): 282 if bool(self.venvComboBox.currentText()):
265 interpreter = self.__venvManager.getVirtualenvInterpreter( 283 interpreter = self.__determineInterpreter(self.venvComboBox.currentText())
266 self.venvComboBox.currentText()
267 )
268 self.frameworkComboBox.addItem("") 284 self.frameworkComboBox.addItem("")
269 for index, (name, executor) in enumerate( 285 for index, (name, executor) in enumerate(
270 sorted(self.__frameworkRegistry.getFrameworks().items()), start=1 286 sorted(self.__frameworkRegistry.getFrameworks().items()), start=1
271 ): 287 ):
272 isInstalled = executor.isInstalled(interpreter) 288 isInstalled = executor.isInstalled(interpreter)
697 713
698 venvName = self.venvComboBox.currentText() 714 venvName = self.venvComboBox.currentText()
699 if venvName: 715 if venvName:
700 framework = self.frameworkComboBox.currentText() 716 framework = self.frameworkComboBox.currentText()
701 if framework: 717 if framework:
702 interpreter = self.__venvManager.getVirtualenvInterpreter(venvName) 718 interpreter = self.__determineInterpreter(venvName)
703 executor = self.__frameworkRegistry.createExecutor(framework, self) 719 executor = self.__frameworkRegistry.createExecutor(framework, self)
704 hasCoverage = executor.hasCoverage(interpreter) 720 hasCoverage = executor.hasCoverage(interpreter)
705 721
706 self.coverageCheckBox.setEnabled(hasCoverage) 722 self.coverageCheckBox.setEnabled(hasCoverage)
707 if not hasCoverage: 723 if not hasCoverage:
717 733
718 venvName = self.venvComboBox.currentText() 734 venvName = self.venvComboBox.currentText()
719 if venvName: 735 if venvName:
720 framework = self.frameworkComboBox.currentText() 736 framework = self.frameworkComboBox.currentText()
721 if framework: 737 if framework:
722 interpreter = self.__venvManager.getVirtualenvInterpreter(venvName) 738 interpreter = self.__determineInterpreter(venvName)
723 executor = self.__frameworkRegistry.createExecutor(framework, self) 739 executor = self.__frameworkRegistry.createExecutor(framework, self)
724 supportsMarkers = executor.supportsMarkers(interpreter) 740 supportsMarkers = executor.supportsMarkers(interpreter)
725 741
726 # 1. marker expression line edit 742 # 1. marker expression line edit
727 self.markerExpressionEdit.setEnabled(supportsMarkers) 743 self.markerExpressionEdit.setEnabled(supportsMarkers)
747 elif self.testsuitePicker.currentText(): 763 elif self.testsuitePicker.currentText():
748 workdir = os.path.dirname(self.testsuitePicker.currentText()) 764 workdir = os.path.dirname(self.testsuitePicker.currentText())
749 else: 765 else:
750 workdir = "" 766 workdir = ""
751 767
752 interpreter = self.__venvManager.getVirtualenvInterpreter(venvName) 768 interpreter = self.__determineInterpreter(venvName)
753 executor = self.__frameworkRegistry.createExecutor(framework, self) 769 executor = self.__frameworkRegistry.createExecutor(framework, self)
754 markers = executor.getMarkers(interpreter, workdir) 770 markers = executor.getMarkers(interpreter, workdir)
755 771
756 if self.__markersWindow is None: 772 if self.__markersWindow is None:
757 from .MarkersWindow import MarkersWindow 773 from .MarkersWindow import MarkersWindow
769 785
770 venvName = self.venvComboBox.currentText() 786 venvName = self.venvComboBox.currentText()
771 if venvName: 787 if venvName:
772 framework = self.frameworkComboBox.currentText() 788 framework = self.frameworkComboBox.currentText()
773 if framework: 789 if framework:
774 interpreter = self.__venvManager.getVirtualenvInterpreter(venvName) 790 interpreter = self.__determineInterpreter(venvName)
775 executor = self.__frameworkRegistry.createExecutor(framework, self) 791 executor = self.__frameworkRegistry.createExecutor(framework, self)
776 supportsPatterns = executor.supportsPatterns(interpreter) 792 supportsPatterns = executor.supportsPatterns(interpreter)
777 793
778 self.testNamePatternEdit.setEnabled(supportsPatterns) 794 self.testNamePatternEdit.setEnabled(supportsPatterns)
779 self.testNamePatternEdit.clear() 795 self.testNamePatternEdit.clear()
785 """ 801 """
786 venvName = self.venvComboBox.currentText() 802 venvName = self.venvComboBox.currentText()
787 if venvName: 803 if venvName:
788 headerText = self.tr("<h3>Versions of Frameworks and their" " Plugins</h3>") 804 headerText = self.tr("<h3>Versions of Frameworks and their" " Plugins</h3>")
789 versionsText = "" 805 versionsText = ""
790 interpreter = self.__venvManager.getVirtualenvInterpreter(venvName) 806 interpreter = self.__determineInterpreter(venvName)
791 for framework in sorted(self.__frameworkRegistry.getFrameworks().keys()): 807 for framework in sorted(self.__frameworkRegistry.getFrameworks().keys()):
792 executor = self.__frameworkRegistry.createExecutor(framework, self) 808 executor = self.__frameworkRegistry.createExecutor(framework, self)
793 versions = executor.getVersions(interpreter) 809 versions = executor.getVersions(interpreter)
794 if versions: 810 if versions:
795 txt = "<p><strong>{0} {1}</strong>".format( 811 txt = "<p><strong>{0} {1}</strong>".format(
856 coverageFile = ( 872 coverageFile = (
857 os.path.splitext(mainScript)[0] + ".coverage" if mainScript else "" 873 os.path.splitext(mainScript)[0] + ".coverage" if mainScript else ""
858 ) 874 )
859 else: 875 else:
860 coverageFile = "" 876 coverageFile = ""
861 interpreter = self.__venvManager.getVirtualenvInterpreter( 877 interpreter = self.__determineInterpreter(self.__recentEnvironment)
862 self.__recentEnvironment
863 )
864 config = TestConfig( 878 config = TestConfig(
865 interpreter=interpreter, 879 interpreter=interpreter,
866 discover=discover, 880 discover=discover,
867 discoveryStart=discoveryStart, 881 discoveryStart=discoveryStart,
868 testFilename=testFileName, 882 testFilename=testFileName,
1078 """ 1092 """
1079 Private slot to show a code coverage dialog for the most recent test 1093 Private slot to show a code coverage dialog for the most recent test
1080 run. 1094 run.
1081 """ 1095 """
1082 if self.__coverageDialog is None: 1096 if self.__coverageDialog is None:
1083 from DataViews.PyCoverageDialog import PyCoverageDialog 1097 from eric7.DataViews.PyCoverageDialog import PyCoverageDialog
1084 1098
1085 self.__coverageDialog = PyCoverageDialog(self) 1099 self.__coverageDialog = PyCoverageDialog(self)
1086 self.__coverageDialog.openFile.connect(self.__openEditor) 1100 self.__coverageDialog.openFile.connect(self.__openEditor)
1087 1101
1088 testDir = ( 1102 testDir = (
1097 @pyqtSlot() 1111 @pyqtSlot()
1098 def __showLogOutput(self): 1112 def __showLogOutput(self):
1099 """ 1113 """
1100 Private slot to show the output of the most recent test run. 1114 Private slot to show the output of the most recent test run.
1101 """ 1115 """
1102 from EricWidgets.EricPlainTextDialog import EricPlainTextDialog 1116 from eric7.EricWidgets.EricPlainTextDialog import EricPlainTextDialog
1103 1117
1104 dlg = EricPlainTextDialog( 1118 dlg = EricPlainTextDialog(
1105 title=self.tr("Test Run Output"), text=self.__recentLog 1119 title=self.tr("Test Run Output"), text=self.__recentLog
1106 ) 1120 )
1107 dlg.exec() 1121 dlg.exec()
1119 @pyqtSlot() 1133 @pyqtSlot()
1120 def __projectOpened(self): 1134 def __projectOpened(self):
1121 """ 1135 """
1122 Private slot to handle a project being opened. 1136 Private slot to handle a project being opened.
1123 """ 1137 """
1124 self.venvComboBox.setCurrentText(self.__project.getProjectVenv()) 1138 self.venvComboBox.insertItem(1, self.__projectEnvironmentMarker)
1139 self.venvComboBox.setCurrentIndex(1)
1125 self.frameworkComboBox.setCurrentText( 1140 self.frameworkComboBox.setCurrentText(
1126 self.__project.getProjectTestingFramework() 1141 self.__project.getProjectTestingFramework()
1127 ) 1142 )
1128 self.__insertDiscovery(self.__project.getProjectPath()) 1143 self.__insertDiscovery(self.__project.getProjectPath())
1129 1144
1130 @pyqtSlot() 1145 @pyqtSlot()
1131 def __projectClosed(self): 1146 def __projectClosed(self):
1132 """ 1147 """
1133 Private slot to handle a project being closed. 1148 Private slot to handle a project being closed.
1134 """ 1149 """
1150 self.venvComboBox.removeItem(1) # <project> is always at index 1
1135 self.venvComboBox.setCurrentText("") 1151 self.venvComboBox.setCurrentText("")
1136 self.frameworkComboBox.setCurrentText("") 1152 self.frameworkComboBox.setCurrentText("")
1137 self.__insertDiscovery("") 1153 self.__insertDiscovery("")
1138 1154
1139 @pyqtSlot(str, int) 1155 @pyqtSlot(str, int)
1162 @param filename path of the file to be opened 1178 @param filename path of the file to be opened
1163 @type str 1179 @type str
1164 @param linenumber line number to place the cursor at (defaults to 1) 1180 @param linenumber line number to place the cursor at (defaults to 1)
1165 @type int (optional) 1181 @type int (optional)
1166 """ 1182 """
1167 from QScintilla.MiniEditor import MiniEditor 1183 from eric7.QScintilla.MiniEditor import MiniEditor
1168 1184
1169 editor = MiniEditor(filename, "Python3", self) 1185 editor = MiniEditor(filename, "Python3", self)
1170 editor.gotoLine(linenumber) 1186 editor.gotoLine(linenumber)
1171 editor.show() 1187 editor.show()
1172 1188

eric ide

mercurial