Wed, 18 May 2022 10:54:32 +0200
Removed unit test related functionality from the debugger in favor of the new Testing interface.
--- a/eric7.epj Wed May 18 09:19:09 2022 +0200 +++ b/eric7.epj Wed May 18 10:54:32 2022 +0200 @@ -623,8 +623,6 @@ "eric7/Project/TranslationPropertiesDialog.ui", "eric7/Project/UicCompilerOptionsDialog.ui", "eric7/Project/UserPropertiesDialog.ui", - "eric7/PyUnit/UnittestDialog.ui", - "eric7/PyUnit/UnittestStacktraceDialog.ui", "eric7/QScintilla/EditorOutlineSizesDialog.ui", "eric7/QScintilla/GotoDialog.ui", "eric7/QScintilla/MarkupProviders/HyperlinkMarkupDialog.ui", @@ -1819,8 +1817,6 @@ "eric7/Project/UserProjectFile.py", "eric7/Project/UserPropertiesDialog.py", "eric7/Project/__init__.py", - "eric7/PyUnit/UnittestDialog.py", - "eric7/PyUnit/__init__.py", "eric7/QScintilla/APIsManager.py", "eric7/QScintilla/DocstringGenerator/BaseDocstringGenerator.py", "eric7/QScintilla/DocstringGenerator/EricdocGenerator.py",
--- a/eric7/DebugClients/Python/DCTestResult.py Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2003 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a TestResult derivative for the eric debugger. -""" - -import select -from unittest import TestResult - - -class DCTestResult(TestResult): - """ - A TestResult derivative to work with eric's debug client. - - For more details see unittest.py of the standard python distribution. - """ - def __init__(self, dbgClient, failfast): - """ - Constructor - - @param dbgClient reference to the debug client - @type DebugClientBase - @param failfast flag indicating to stop at the first error - @type bool - """ - TestResult.__init__(self) - self.__dbgClient = dbgClient - self.failfast = failfast - - def addFailure(self, test, err): - """ - Public method called if a test failed. - - @param test Reference to the test object - @param err The error traceback - """ - TestResult.addFailure(self, test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.__dbgClient.sendJsonCommand("ResponseUTTestFailed", { - "testname": str(test), - "traceback": tracebackLines, - "id": test.id(), - }) - - def addError(self, test, err): - """ - Public method called if a test errored. - - @param test Reference to the test object - @param err The error traceback - """ - TestResult.addError(self, test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.__dbgClient.sendJsonCommand("ResponseUTTestErrored", { - "testname": str(test), - "traceback": tracebackLines, - "id": test.id(), - }) - - def addSubTest(self, test, subtest, err): - """ - Public method called for each subtest to record its result. - - @param test reference to the test object - @param subtest reference to the subtest object - @param err error traceback - """ - if err is not None: - TestResult.addSubTest(self, test, subtest, err) - tracebackLines = self._exc_info_to_string(err, test) - if issubclass(err[0], test.failureException): - self.__dbgClient.sendJsonCommand("ResponseUTTestFailed", { - "testname": str(subtest), - "traceback": tracebackLines, - "id": test.id(), - }) - else: - self.__dbgClient.sendJsonCommand("ResponseUTTestErrored", { - "testname": str(subtest), - "traceback": tracebackLines, - "id": test.id(), - }) - - def addSkip(self, test, reason): - """ - Public method called if a test was skipped. - - @param test reference to the test object - @param reason reason for skipping the test (string) - """ - TestResult.addSkip(self, test, reason) - self.__dbgClient.sendJsonCommand("ResponseUTTestSkipped", { - "testname": str(test), - "reason": reason, - "id": test.id(), - }) - - def addExpectedFailure(self, test, err): - """ - Public method called if a test failed expected. - - @param test reference to the test object - @param err error traceback - """ - TestResult.addExpectedFailure(self, test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.__dbgClient.sendJsonCommand("ResponseUTTestFailedExpected", { - "testname": str(test), - "traceback": tracebackLines, - "id": test.id(), - }) - - def addUnexpectedSuccess(self, test): - """ - Public method called if a test succeeded expectedly. - - @param test reference to the test object - """ - TestResult.addUnexpectedSuccess(self, test) - self.__dbgClient.sendJsonCommand("ResponseUTTestSucceededUnexpected", { - "testname": str(test), - "id": test.id(), - }) - - def startTest(self, test): - """ - Public method called at the start of a test. - - @param test Reference to the test object - """ - TestResult.startTest(self, test) - self.__dbgClient.sendJsonCommand("ResponseUTStartTest", { - "testname": str(test), - "description": test.shortDescription(), - }) - - def stopTest(self, test): - """ - Public method called at the end of a test. - - @param test Reference to the test object - """ - TestResult.stopTest(self, test) - self.__dbgClient.sendJsonCommand("ResponseUTStopTest", {}) - - # ensure that pending input is processed - rrdy, wrdy, xrdy = select.select( - [self.__dbgClient.readstream], [], [], 0.01) - - if self.__dbgClient.readstream in rrdy: - self.__dbgClient.readReady(self.__dbgClient.readstream)
--- a/eric7/DebugClients/Python/DebugClientBase.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/DebugClients/Python/DebugClientBase.py Wed May 18 10:54:32 2022 +0200 @@ -799,194 +799,6 @@ elif method == "RequestCompletion": self.__completionList(params["text"]) - - elif method == "RequestUTDiscover": - if params["syspath"]: - sys.path = params["syspath"] + sys.path - - discoveryStart = params["discoverystart"] - if not discoveryStart: - discoveryStart = params["workdir"] - - top_level_dir = params["workdir"] - - os.chdir(params["discoverystart"]) - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - try: - import unittest - testLoader = unittest.TestLoader() - test = testLoader.discover( - discoveryStart, top_level_dir=top_level_dir) - if (hasattr(testLoader, "errors") and - bool(testLoader.errors)): - self.sendJsonCommand("ResponseUTDiscover", { - "testCasesList": [], - "exception": "DiscoveryError", - "message": "\n\n".join(testLoader.errors), - }) - else: - testsList = self.__assembleTestCasesList(test, - discoveryStart) - self.sendJsonCommand("ResponseUTDiscover", { - "testCasesList": testsList, - "exception": "", - "message": "", - }) - except Exception: - exc_type, exc_value, exc_tb = sys.exc_info() - self.sendJsonCommand("ResponseUTDiscover", { - "testCasesList": [], - "exception": exc_type.__name__, - "message": str(exc_value), - }) - - elif method == "RequestUTPrepare": - if params["syspath"]: - sys.path = params["syspath"] + sys.path - top_level_dir = None - if params["workdir"]: - os.chdir(params["workdir"]) - top_level_dir = params["workdir"] - - # set the system exception handling function to ensure, that - # we report on all unhandled exceptions - sys.excepthook = self.__unhandled_exception - self.__interceptSignals() - - try: - import unittest - testLoader = unittest.TestLoader() - if params["discover"]: - discoveryStart = params["discoverystart"] - if not discoveryStart: - discoveryStart = params["workdir"] - sys.path.insert( - 0, os.path.abspath(discoveryStart)) - if params["testcases"]: - self.test = testLoader.loadTestsFromNames( - params["testcases"]) - else: - self.test = testLoader.discover( - discoveryStart, top_level_dir=top_level_dir) - else: - sys.path.insert( - 0, - os.path.dirname(os.path.abspath(params["filename"])) - ) - if params["filename"]: - utModule = __import__(params["testname"]) - else: - utModule = None - if params["failed"]: - if utModule: - failed = [t.split(".", 1)[1] - for t in params["failed"]] - else: - failed = params["failed"][:] - self.test = testLoader.loadTestsFromNames( - failed, utModule) - else: - self.test = testLoader.loadTestsFromName( - params["testfunctionname"], utModule) - except Exception: - exc_type, exc_value, exc_tb = sys.exc_info() - self.sendJsonCommand("ResponseUTPrepared", { - "count": 0, - "exception": exc_type.__name__, - "message": str(exc_value), - }) - return - - # generate a coverage object - if params["coverage"]: - from coverage import Coverage - self.cover = Coverage( - auto_data=True, - data_file="{0}.coverage".format( - os.path.splitext(params["coveragefile"])[0])) - if params["coverageerase"]: - self.cover.erase() - else: - self.cover = None - - if params["debug"]: - Breakpoint.clear_all_breaks() - Watch.clear_all_watches() - - self.sendJsonCommand("ResponseUTPrepared", { - "count": self.test.countTestCases(), - "exception": "", - "message": "", - }) - - elif method == "RequestUTRun": - from DCTestResult import DCTestResult - self.disassembly = None - self.testResult = DCTestResult(self, params["failfast"]) - if self.cover: - self.cover.start() - self.debugging = params["debug"] - if params["debug"]: - self.multiprocessSupport = False - locals_ = locals() - self.threads.clear() - self.attachThread(mainThread=True) - sys.setprofile(None) - self.running = sys.argv[0] - self.mainThread.run( - "result = self.test.run(self.testResult)\n", - self.debugMod.__dict__, - localsDict=locals_, - debug=True, - closeSession=False) - result = locals_["result"] - else: - result = self.test.run(self.testResult) - if self.cover: - self.cover.stop() - self.cover.save() - self.sendJsonCommand("ResponseUTFinished", { - "status": 0 if result.wasSuccessful() else 1, - }) - - elif method == "RequestUTStop": - self.testResult.stop() - - def __assembleTestCasesList(self, suite, start): - """ - Private method to assemble a list of test cases included in a test - suite. - - @param suite test suite to be inspected - @type unittest.TestSuite - @param start name of directory discovery was started at - @type str - @return list of tuples containing the test case ID, a short description - and the path of the test file name - @rtype list of tuples of (str, str, str) - """ - import unittest - testCases = [] - for test in suite: - if isinstance(test, unittest.TestSuite): - testCases.extend(self.__assembleTestCasesList(test, start)) - else: - testId = test.id() - if ("ModuleImportFailure" not in testId and - "LoadTestsFailure" not in testId and - "_FailedTest" not in testId): - filename = os.path.join( - start, - test.__module__.replace(".", os.sep) + ".py") - testCases.append( - (test.id(), test.shortDescription(), filename) - ) - return testCases def setDisassembly(self, disassembly): """
--- a/eric7/DebugClients/Python/DebugClientCapabilities.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/DebugClients/Python/DebugClientCapabilities.py Wed May 18 10:54:32 2022 +0200 @@ -7,15 +7,12 @@ Module defining the debug clients capabilities. """ -# TODO: remove unittest support from Python debugger - HasDebugger = 0x0001 HasInterpreter = 0x0002 HasProfiler = 0x0004 HasCoverage = 0x0008 HasCompleter = 0x0010 -HasUnittest = 0x0020 -HasShell = 0x0040 +HasShell = 0x0020 -HasAll = (HasDebugger | HasInterpreter | HasProfiler | - HasCoverage | HasCompleter | HasUnittest | HasShell) +HasAll = (HasDebugger | HasInterpreter | HasProfiler | HasCoverage | + HasCompleter | HasShell)
--- a/eric7/DebugClients/Python/__init__.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/DebugClients/Python/__init__.py Wed May 18 10:54:32 2022 +0200 @@ -8,5 +8,3 @@ It consists of different kinds of debug clients. """ - -# TODO: remove the unittest support from the debug client
--- a/eric7/DebugClients/__init__.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/DebugClients/__init__.py Wed May 18 10:54:32 2022 +0200 @@ -6,5 +6,3 @@ """ Package implementing debug clients for various languages. """ - -# TODO: remove the unittest support from the debug client
--- a/eric7/Debugger/DebugClientCapabilities.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Debugger/DebugClientCapabilities.py Wed May 18 10:54:32 2022 +0200 @@ -12,8 +12,7 @@ HasProfiler = 0x0004 HasCoverage = 0x0008 HasCompleter = 0x0010 -HasUnittest = 0x0020 -HasShell = 0x0040 +HasShell = 0x0020 -HasAll = (HasDebugger | HasInterpreter | HasProfiler | - HasCoverage | HasCompleter | HasUnittest | HasShell) +HasAll = (HasDebugger | HasInterpreter | HasProfiler | HasCoverage | + HasCompleter | HasShell)
--- a/eric7/Debugger/DebugServer.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Debugger/DebugServer.py Wed May 18 10:54:32 2022 +0200 @@ -101,25 +101,6 @@ unplanned) @signal clientInterpreterChanged(str) emitted to signal a change of the client interpreter - @signal utDiscovered(testCases, exc_type, exc_value) emitted after the - client has performed a test case discovery action - @signal utPrepared(nrTests, exc_type, exc_value) emitted after the client - has loaded a unittest suite - @signal utFinished() emitted after the client signalled the end of the - unittest - @signal utStartTest(testname, testdocu) emitted after the client has - started a test - @signal utStopTest() emitted after the client has finished a test - @signal utTestFailed(testname, exc_info, id) emitted after the client - reported a failed test - @signal utTestErrored(testname, exc_info, id) emitted after the client - reported an errored test - @signal utTestSkipped(testname, reason, id) emitted after the client - reported a skipped test - @signal utTestFailedExpected(testname, exc_info, id) emitted after the - client reported an expected test failure - @signal utTestSucceededUnexpected(testname, id) emitted after the client - reported an unexpected test success @signal callTraceInfo emitted after the client reported the call trace data (isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction, debuggerId) @@ -158,16 +139,6 @@ clientCompletionList = pyqtSignal(list, str) clientInterpreterChanged = pyqtSignal(str) clientDebuggerId = pyqtSignal(str) - utDiscovered = pyqtSignal(list, str, str) - utPrepared = pyqtSignal(int, str, str) - utStartTest = pyqtSignal(str, str) - utStopTest = pyqtSignal() - utTestFailed = pyqtSignal(str, str, str) - utTestErrored = pyqtSignal(str, str, str) - utTestSkipped = pyqtSignal(str, str, str) - utTestFailedExpected = pyqtSignal(str, str, str) - utTestSucceededUnexpected = pyqtSignal(str, str) - utFinished = pyqtSignal() passiveDebugStarted = pyqtSignal(str, bool) callTraceInfo = pyqtSignal(bool, str, str, str, str, str, str, str) appendStdout = pyqtSignal(str) @@ -1539,137 +1510,6 @@ """ self.debuggerInterface.remoteCompletion(debuggerId, text) - def remoteUTDiscover(self, clientType, forProject, venvName, syspath, - workdir, discoveryStart): - """ - Public method to perform a test case discovery. - - @param clientType client type to be used - @type str - @param forProject flag indicating a project related action - @type bool - @param venvName name of a virtual environment - @type str - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discoveryStart directory to start auto-discovery at - @type str - """ - if clientType and clientType not in self.getSupportedLanguages(): - # a not supported client language was requested - EricMessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger type <b>{0}</b> is not supported""" - """ or not configured.</p>""").format(clientType) - ) - return - - # Restart the client if there is already a program loaded. - try: - if clientType: - self.__setClientType(clientType) - except KeyError: - self.__setClientType('Python3') # assume it is a Python3 file - self.startClient(False, forProject=forProject, venvName=venvName) - - self.debuggerInterface.remoteUTDiscover( - syspath, workdir, discoveryStart) - - def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase, - clientType="", forProject=False, venvName="", - syspath=None, workdir="", discover=False, - discoveryStart="", testCases=None, debug=False): - """ - Public method to prepare a new unittest run. - - @param fn the filename to load - @type str - @param tn the testname to load - @type str - @param tfn the test function name to load tests from - @type str - @param failed list of failed test, if only failed test should be run - @type list of str - @param cov flag indicating collection of coverage data is requested - @type bool - @param covname filename to be used to assemble the coverage caches - filename - @type str - @param coverase flag indicating erasure of coverage data is requested - @type bool - @param clientType client type to be used - @type str - @param forProject flag indicating a project related action - @type bool - @param venvName name of a virtual environment - @type str - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discover flag indicating to discover the tests automatically - @type bool - @param discoveryStart directory to start auto-discovery at - @type str - @param testCases list of test cases to be loaded - @type list of str - @param debug flag indicating to run unittest with debugging - @type bool - """ - if clientType and clientType not in self.getSupportedLanguages(): - # a not supported client language was requested - EricMessageBox.critical( - None, - self.tr("Start Debugger"), - self.tr( - """<p>The debugger type <b>{0}</b> is not supported""" - """ or not configured.</p>""").format(clientType) - ) - return - - # Restart the client if there is already a program loaded. - try: - if clientType: - self.__setClientType(clientType) - else: - self.__setClientType( - self.__findLanguageForExtension(os.path.splitext(fn)[1])) - except KeyError: - self.__setClientType('Python3') # assume it is a Python3 file - self.startClient(False, forProject=forProject, venvName=venvName) - - self.debuggerInterface.remoteUTPrepare( - fn, tn, tfn, failed, cov, covname, coverase, syspath, workdir, - discover, discoveryStart, testCases, debug) - self.running = True - self.debugging = debug - if debug: - self.__restoreBreakpoints() - self.__restoreWatchpoints() - - def remoteUTRun(self, debug=False, failfast=False): - """ - Public method to start a unittest run. - - @param debug flag indicating to run unittest with debugging - @type bool - @param failfast flag indicating to stop at the first error - @type bool - """ - self.debuggerInterface.remoteUTRun(debug, failfast) - - def remoteUTStop(self): - """ - public method to stop a unittest run. - """ - self.debuggerInterface.remoteUTStop() - def signalClientOutput(self, line, debuggerId): """ Public method to process a line of client output. @@ -2036,125 +1876,6 @@ isCall, fromFile, fromLine, fromFunction, toFile, toLine, toFunction, debuggerId) - def clientUtDiscovered(self, testCases, exceptionType, exceptionValue): - """ - Public method to process the client unittest discover info. - - @param testCases list of detected test cases - @type str - @param exceptionType exception type - @type str - @param exceptionValue exception message - @type str - """ - self.utDiscovered.emit(testCases, exceptionType, exceptionValue) - - def clientUtPrepared(self, result, exceptionType, exceptionValue): - """ - Public method to process the client unittest prepared info. - - @param result number of test cases (0 = error) - @type int - @param exceptionType exception type - @type str - @param exceptionValue exception message - @type str - """ - self.utPrepared.emit(result, exceptionType, exceptionValue) - - def clientUtStartTest(self, testname, doc): - """ - Public method to process the client start test info. - - @param testname name of the test - @type str - @param doc short description of the test - @type str - """ - self.utStartTest.emit(testname, doc) - - def clientUtStopTest(self): - """ - Public method to process the client stop test info. - """ - self.utStopTest.emit() - - def clientUtTestFailed(self, testname, traceback, testId): - """ - Public method to process the client test failed info. - - @param testname name of the test - @type str - @param traceback lines of traceback info - @type list of str - @param testId id of the test - @type str - """ - self.utTestFailed.emit(testname, traceback, testId) - - def clientUtTestErrored(self, testname, traceback, testId): - """ - Public method to process the client test errored info. - - @param testname name of the test - @type str - @param traceback lines of traceback info - @type list of str - @param testId id of the test - @type str - """ - self.utTestErrored.emit(testname, traceback, testId) - - def clientUtTestSkipped(self, testname, reason, testId): - """ - Public method to process the client test skipped info. - - @param testname name of the test - @type str - @param reason reason for skipping the test - @type str - @param testId id of the test - @type str - """ - self.utTestSkipped.emit(testname, reason, testId) - - def clientUtTestFailedExpected(self, testname, traceback, testId): - """ - Public method to process the client test failed expected info. - - @param testname name of the test - @type str - @param traceback lines of traceback info - @type list of str - @param testId id of the test - @type str - """ - self.utTestFailedExpected.emit(testname, traceback, testId) - - def clientUtTestSucceededUnexpected(self, testname, testId): - """ - Public method to process the client test succeeded unexpected info. - - @param testname name of the test - @type str - @param testId id of the test - @type str - """ - self.utTestSucceededUnexpected.emit(testname, testId) - - def clientUtFinished(self, status): - """ - Public method to process the client unit test finished info. - - @param status exit status of the unit test - @type int - """ - self.utFinished.emit() - - self.clientExit.emit("", int(status), "", True, "") - self.debugging = False - self.running = False - def passiveStartUp(self, fn, exc, debuggerId): """ Public method to handle a passive debug connection.
--- a/eric7/Debugger/DebuggerInterfaceNone.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Debugger/DebuggerInterfaceNone.py Wed May 18 10:54:32 2022 +0200 @@ -543,75 +543,7 @@ @type str """ return - - def remoteUTDiscover(self, syspath, workdir, discoveryStart): - """ - Public method to perform a test case discovery. - - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discoveryStart directory to start auto-discovery at - @type str - """ - return - - def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase, - syspath, workdir, discover, discoveryStart, testCases, - debug): - """ - Public method to prepare a new unittest run. - - @param fn name of file to load - @type str - @param tn name of test to load - @type str - @param tfn test function name to load tests from - @type str - @param failed list of failed test, if only failed test should be run - @type list of str - @param cov flag indicating collection of coverage data is requested - @type bool - @param covname name of file to be used to assemble the coverage caches - filename - @type str - @param coverase flag indicating erasure of coverage data is requested - @type bool - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discover flag indicating to discover the tests automatically - @type bool - @param discoveryStart directory to start auto-discovery at - @type str - @param testCases list of test cases to be loaded - @type list of str - @param debug flag indicating to run unittest with debugging - @type bool - """ - return - - def remoteUTRun(self, debug, failfast): - """ - Public method to start a unittest run. - - @param debug flag indicating to run unittest with debugging - @type bool - @param failfast flag indicating to stop at the first error - @type bool - """ - return - - def remoteUTStop(self): - """ - public method to stop a unittest run. - """ - return - + def createDebuggerInterfaceNone(debugServer, passive): """
--- a/eric7/Debugger/DebuggerInterfacePython.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Debugger/DebuggerInterfacePython.py Wed May 18 10:54:32 2022 +0200 @@ -1205,104 +1205,6 @@ "text": text, }, debuggerId) - def remoteUTDiscover(self, syspath, workdir, discoveryStart): - """ - Public method to perform a test case discovery. - - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discoveryStart directory to start auto-discovery at - @type str - """ - self.__sendJsonCommand("RequestUTDiscover", { - "syspath": [] if syspath is None else syspath, - "workdir": workdir, - "discoverystart": discoveryStart, - }) - - def remoteUTPrepare(self, fn, tn, tfn, failed, cov, covname, coverase, - syspath, workdir, discover, discoveryStart, testCases, - debug): - """ - Public method to prepare a new unittest run. - - @param fn name of file to load - @type str - @param tn name of test to load - @type str - @param tfn test function name to load tests from - @type str - @param failed list of failed test, if only failed test should be run - @type list of str - @param cov flag indicating collection of coverage data is requested - @type bool - @param covname name of file to be used to assemble the coverage caches - filename - @type str - @param coverase flag indicating erasure of coverage data is requested - @type bool - @param syspath list of directories to be added to sys.path on the - remote side - @type list of str - @param workdir path name of the working directory - @type str - @param discover flag indicating to discover the tests automatically - @type bool - @param discoveryStart directory to start auto-discovery at - @type str - @param testCases list of test cases to be loaded - @type list of str - @param debug flag indicating to run unittest with debugging - @type bool - """ - if fn: - self.__scriptName = os.path.abspath(fn) - - fn = self.translate(os.path.abspath(fn), False) - else: - self.__scriptName = "unittest discover" - - self.__sendJsonCommand("RequestUTPrepare", { - "filename": fn, - "testname": tn, - "testfunctionname": tfn, - "failed": failed, - "coverage": cov, - "coveragefile": covname, - "coverageerase": coverase, - "syspath": [] if syspath is None else syspath, - "workdir": workdir, - "discover": discover, - "discoverystart": discoveryStart, - "testcases": [] if testCases is None else testCases, - "debug": debug, - }) - - def remoteUTRun(self, debug, failfast): - """ - Public method to start a unittest run. - - @param debug flag indicating to run unittest with debugging - @type bool - @param failfast flag indicating to stop at the first error - @type bool - """ - if debug: - self.__autoContinue = True - self.__sendJsonCommand("RequestUTRun", { - "debug": debug, - "failfast": failfast, - }) - - def remoteUTStop(self): - """ - Public method to stop a unittest run. - """ - self.__sendJsonCommand("RequestUTStop", {}) - def __parseClientLine(self, sock): """ Private method to handle data from the client. @@ -1509,49 +1411,6 @@ elif method == "ResponseCompletion": self.debugServer.signalClientCompletionList( params["completions"], params["text"], params["debuggerId"]) - - ################################################################### - ## Unit test related stuff is not done with multi processing - ################################################################### - - elif method == "ResponseUTDiscover": - self.debugServer.clientUtDiscovered( - params["testCasesList"], params["exception"], - params["message"]) - - elif method == "ResponseUTPrepared": - self.debugServer.clientUtPrepared( - params["count"], params["exception"], params["message"]) - - elif method == "ResponseUTFinished": - self.debugServer.clientUtFinished(params["status"]) - - elif method == "ResponseUTStartTest": - self.debugServer.clientUtStartTest( - params["testname"], params["description"]) - - elif method == "ResponseUTStopTest": - self.debugServer.clientUtStopTest() - - elif method == "ResponseUTTestFailed": - self.debugServer.clientUtTestFailed( - params["testname"], params["traceback"], params["id"]) - - elif method == "ResponseUTTestErrored": - self.debugServer.clientUtTestErrored( - params["testname"], params["traceback"], params["id"]) - - elif method == "ResponseUTTestSkipped": - self.debugServer.clientUtTestSkipped( - params["testname"], params["reason"], params["id"]) - - elif method == "ResponseUTTestFailedExpected": - self.debugServer.clientUtTestFailedExpected( - params["testname"], params["traceback"], params["id"]) - - elif method == "ResponseUTTestSucceededUnexpected": - self.debugServer.clientUtTestSucceededUnexpected( - params["testname"], params["id"]) def __sendJsonCommand(self, command, params, debuggerId="", sock=None): """
--- a/eric7/Debugger/__init__.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Debugger/__init__.py Wed May 18 10:54:32 2022 +0200 @@ -9,5 +9,3 @@ This package implements the graphical debugger. It consists of the debugger related HMI part, supporting dialogs and the debug server. """ - -# TODO: remove the unittest support from the debugger
--- a/eric7/Documentation/Source/eric7.DebugClients.Python.DCTestResult.html Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,259 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric7.DebugClients.Python.DCTestResult</title> -<meta charset="UTF-8"> -<link rel="stylesheet" href="styles.css"> -</head> -<body> -<a NAME="top" ID="top"></a> -<h1>eric7.DebugClients.Python.DCTestResult</h1> - -<p> -Module implementing a TestResult derivative for the eric debugger. -</p> -<h3>Global Attributes</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> - -<table> - -<tr> -<td><a href="#DCTestResult">DCTestResult</a></td> -<td>A TestResult derivative to work with eric's debug client.</td> -</tr> -</table> -<h3>Functions</h3> - -<table> -<tr><td>None</td></tr> -</table> -<hr /> -<hr /> -<a NAME="DCTestResult" ID="DCTestResult"></a> -<h2>DCTestResult</h2> - -<p> - A TestResult derivative to work with eric's debug client. -</p> -<p> - For more details see unittest.py of the standard python distribution. -</p> -<h3>Derived from</h3> -TestResult -<h3>Class Attributes</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Class Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> - -<table> - -<tr> -<td><a href="#DCTestResult.__init__">DCTestResult</a></td> -<td>Constructor</td> -</tr> -<tr> -<td><a href="#DCTestResult.addError">addError</a></td> -<td>Public method called if a test errored.</td> -</tr> -<tr> -<td><a href="#DCTestResult.addExpectedFailure">addExpectedFailure</a></td> -<td>Public method called if a test failed expected.</td> -</tr> -<tr> -<td><a href="#DCTestResult.addFailure">addFailure</a></td> -<td>Public method called if a test failed.</td> -</tr> -<tr> -<td><a href="#DCTestResult.addSkip">addSkip</a></td> -<td>Public method called if a test was skipped.</td> -</tr> -<tr> -<td><a href="#DCTestResult.addSubTest">addSubTest</a></td> -<td>Public method called for each subtest to record its result.</td> -</tr> -<tr> -<td><a href="#DCTestResult.addUnexpectedSuccess">addUnexpectedSuccess</a></td> -<td>Public method called if a test succeeded expectedly.</td> -</tr> -<tr> -<td><a href="#DCTestResult.startTest">startTest</a></td> -<td>Public method called at the start of a test.</td> -</tr> -<tr> -<td><a href="#DCTestResult.stopTest">stopTest</a></td> -<td>Public method called at the end of a test.</td> -</tr> -</table> -<h3>Static Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> - -<a NAME="DCTestResult.__init__" ID="DCTestResult.__init__"></a> -<h4>DCTestResult (Constructor)</h4> -<b>DCTestResult</b>(<i>dbgClient, failfast</i>) - -<p> - Constructor -</p> -<dl> - -<dt><i>dbgClient</i> (DebugClientBase)</dt> -<dd> -reference to the debug client -</dd> -<dt><i>failfast</i> (bool)</dt> -<dd> -flag indicating to stop at the first error -</dd> -</dl> -<a NAME="DCTestResult.addError" ID="DCTestResult.addError"></a> -<h4>DCTestResult.addError</h4> -<b>addError</b>(<i>test, err</i>) - -<p> - Public method called if a test errored. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -The error traceback -</dd> -</dl> -<a NAME="DCTestResult.addExpectedFailure" ID="DCTestResult.addExpectedFailure"></a> -<h4>DCTestResult.addExpectedFailure</h4> -<b>addExpectedFailure</b>(<i>test, err</i>) - -<p> - Public method called if a test failed expected. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="DCTestResult.addFailure" ID="DCTestResult.addFailure"></a> -<h4>DCTestResult.addFailure</h4> -<b>addFailure</b>(<i>test, err</i>) - -<p> - Public method called if a test failed. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -The error traceback -</dd> -</dl> -<a NAME="DCTestResult.addSkip" ID="DCTestResult.addSkip"></a> -<h4>DCTestResult.addSkip</h4> -<b>addSkip</b>(<i>test, reason</i>) - -<p> - Public method called if a test was skipped. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>reason</i></dt> -<dd> -reason for skipping the test (string) -</dd> -</dl> -<a NAME="DCTestResult.addSubTest" ID="DCTestResult.addSubTest"></a> -<h4>DCTestResult.addSubTest</h4> -<b>addSubTest</b>(<i>test, subtest, err</i>) - -<p> - Public method called for each subtest to record its result. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>subtest</i></dt> -<dd> -reference to the subtest object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="DCTestResult.addUnexpectedSuccess" ID="DCTestResult.addUnexpectedSuccess"></a> -<h4>DCTestResult.addUnexpectedSuccess</h4> -<b>addUnexpectedSuccess</b>(<i>test</i>) - -<p> - Public method called if a test succeeded expectedly. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -</dl> -<a NAME="DCTestResult.startTest" ID="DCTestResult.startTest"></a> -<h4>DCTestResult.startTest</h4> -<b>startTest</b>(<i>test</i>) - -<p> - Public method called at the start of a test. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -</dl> -<a NAME="DCTestResult.stopTest" ID="DCTestResult.stopTest"></a> -<h4>DCTestResult.stopTest</h4> -<b>stopTest</b>(<i>test</i>) - -<p> - Public method called at the end of a test. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/eric7/Documentation/Source/eric7.PyUnit.UnittestDialog.html Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1236 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric7.PyUnit.UnittestDialog</title> -<meta charset="UTF-8"> -<link rel="stylesheet" href="styles.css"> -</head> -<body> -<a NAME="top" ID="top"></a> -<h1>eric7.PyUnit.UnittestDialog</h1> - -<p> -Module implementing the UI to the pyunit package. -</p> -<h3>Global Attributes</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Classes</h3> - -<table> - -<tr> -<td><a href="#QtTestResult">QtTestResult</a></td> -<td>A TestResult derivative to work with a graphical GUI.</td> -</tr> -<tr> -<td><a href="#UnittestDialog">UnittestDialog</a></td> -<td>Class implementing the UI to the pyunit package.</td> -</tr> -<tr> -<td><a href="#UnittestWindow">UnittestWindow</a></td> -<td>Main window class for the standalone dialog.</td> -</tr> -</table> -<h3>Functions</h3> - -<table> - -<tr> -<td><a href="#clearSavedHistories">clearSavedHistories</a></td> -<td>Function to clear the saved history lists.</td> -</tr> -</table> -<hr /> -<hr /> -<a NAME="QtTestResult" ID="QtTestResult"></a> -<h2>QtTestResult</h2> - -<p> - A TestResult derivative to work with a graphical GUI. -</p> -<p> - For more details see pyunit.py of the standard Python distribution. -</p> -<h3>Derived from</h3> -unittest.TestResult -<h3>Class Attributes</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Class Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> - -<table> - -<tr> -<td><a href="#QtTestResult.__init__">QtTestResult</a></td> -<td>Constructor</td> -</tr> -<tr> -<td><a href="#QtTestResult.addError">addError</a></td> -<td>Public method called if a test errored.</td> -</tr> -<tr> -<td><a href="#QtTestResult.addExpectedFailure">addExpectedFailure</a></td> -<td>Public method called if a test failed expected.</td> -</tr> -<tr> -<td><a href="#QtTestResult.addFailure">addFailure</a></td> -<td>Public method called if a test failed.</td> -</tr> -<tr> -<td><a href="#QtTestResult.addSkip">addSkip</a></td> -<td>Public method called if a test was skipped.</td> -</tr> -<tr> -<td><a href="#QtTestResult.addSubTest">addSubTest</a></td> -<td>Public method called for each subtest to record its result.</td> -</tr> -<tr> -<td><a href="#QtTestResult.addUnexpectedSuccess">addUnexpectedSuccess</a></td> -<td>Public method called if a test succeeded expectedly.</td> -</tr> -<tr> -<td><a href="#QtTestResult.startTest">startTest</a></td> -<td>Public method called at the start of a test.</td> -</tr> -<tr> -<td><a href="#QtTestResult.stopTest">stopTest</a></td> -<td>Public method called at the end of a test.</td> -</tr> -</table> -<h3>Static Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> - -<a NAME="QtTestResult.__init__" ID="QtTestResult.__init__"></a> -<h4>QtTestResult (Constructor)</h4> -<b>QtTestResult</b>(<i>parent, failfast</i>) - -<p> - Constructor -</p> -<dl> - -<dt><i>parent</i> (UnittestDialog)</dt> -<dd> -reference to the parent widget -</dd> -<dt><i>failfast</i> (bool)</dt> -<dd> -flag indicating to stop at the first error -</dd> -</dl> -<a NAME="QtTestResult.addError" ID="QtTestResult.addError"></a> -<h4>QtTestResult.addError</h4> -<b>addError</b>(<i>test, err</i>) - -<p> - Public method called if a test errored. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="QtTestResult.addExpectedFailure" ID="QtTestResult.addExpectedFailure"></a> -<h4>QtTestResult.addExpectedFailure</h4> -<b>addExpectedFailure</b>(<i>test, err</i>) - -<p> - Public method called if a test failed expected. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="QtTestResult.addFailure" ID="QtTestResult.addFailure"></a> -<h4>QtTestResult.addFailure</h4> -<b>addFailure</b>(<i>test, err</i>) - -<p> - Public method called if a test failed. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="QtTestResult.addSkip" ID="QtTestResult.addSkip"></a> -<h4>QtTestResult.addSkip</h4> -<b>addSkip</b>(<i>test, reason</i>) - -<p> - Public method called if a test was skipped. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>reason</i></dt> -<dd> -reason for skipping the test (string) -</dd> -</dl> -<a NAME="QtTestResult.addSubTest" ID="QtTestResult.addSubTest"></a> -<h4>QtTestResult.addSubTest</h4> -<b>addSubTest</b>(<i>test, subtest, err</i>) - -<p> - Public method called for each subtest to record its result. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -<dt><i>subtest</i></dt> -<dd> -reference to the subtest object -</dd> -<dt><i>err</i></dt> -<dd> -error traceback -</dd> -</dl> -<a NAME="QtTestResult.addUnexpectedSuccess" ID="QtTestResult.addUnexpectedSuccess"></a> -<h4>QtTestResult.addUnexpectedSuccess</h4> -<b>addUnexpectedSuccess</b>(<i>test</i>) - -<p> - Public method called if a test succeeded expectedly. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -reference to the test object -</dd> -</dl> -<a NAME="QtTestResult.startTest" ID="QtTestResult.startTest"></a> -<h4>QtTestResult.startTest</h4> -<b>startTest</b>(<i>test</i>) - -<p> - Public method called at the start of a test. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -</dl> -<a NAME="QtTestResult.stopTest" ID="QtTestResult.stopTest"></a> -<h4>QtTestResult.stopTest</h4> -<b>stopTest</b>(<i>test</i>) - -<p> - Public method called at the end of a test. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -Reference to the test object -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -<hr /> -<a NAME="UnittestDialog" ID="UnittestDialog"></a> -<h2>UnittestDialog</h2> - -<p> - Class implementing the UI to the pyunit package. -</p> -<h3>Signals</h3> -<dl> - -<dt>unittestFile(str, int, bool)</dt> -<dd> -emitted to show the source of a - unittest file -</dd> -<dt>unittestStopped()</dt> -<dd> -emitted after a unit test was run -</dd> -</dl> -<h3>Derived from</h3> -QWidget, Ui_UnittestDialog -<h3>Class Attributes</h3> - -<table> -<tr><td>ErrorsInfoRole</td></tr><tr><td>FailedExpectedColorDarkTheme</td></tr><tr><td>FailedExpectedColorLightTheme</td></tr><tr><td>SkippedColorDarkTheme</td></tr><tr><td>SkippedColorLightTheme</td></tr><tr><td>SucceededUnexpectedColorDarkTheme</td></tr><tr><td>SucceededUnexpectedColorLightTheme</td></tr><tr><td>TestCaseFileRole</td></tr><tr><td>TestCaseNameRole</td></tr> -</table> -<h3>Class Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> - -<table> - -<tr> -<td><a href="#UnittestDialog.__init__">UnittestDialog</a></td> -<td>Constructor</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__UTDiscovered">__UTDiscovered</a></td> -<td>Private slot to handle the utDiscovered signal.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__UTPrepared">__UTPrepared</a></td> -<td>Private slot to handle the utPrepared signal.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__assembleTestCasesList">__assembleTestCasesList</a></td> -<td>Private method to assemble a list of test cases included in a test suite.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__discover">__discover</a></td> -<td>Private slot to discover unit test but don't run them.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__findDiscoveryItem">__findDiscoveryItem</a></td> -<td>Private method to find an item given the module path.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__loadRecent">__loadRecent</a></td> -<td>Private method to load the most recently used lists.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__openEditor">__openEditor</a></td> -<td>Private method to open an editor window for the given file.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__populateDiscoveryResults">__populateDiscoveryResults</a></td> -<td>Private method to populate the test discovery results list.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__populateVenvComboBox">__populateVenvComboBox</a></td> -<td>Private method to (re-)populate the virtual environments selector.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__saveRecent">__saveRecent</a></td> -<td>Private method to save the most recently used lists.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__selectedTestCases">__selectedTestCases</a></td> -<td>Private method to assemble the list of selected test cases and suites.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__setProgressColor">__setProgressColor</a></td> -<td>Private method to set the color of the progress color label.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__setRunningMode">__setRunningMode</a></td> -<td>Private method to set the GUI in running mode.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__setStoppedMode">__setStoppedMode</a></td> -<td>Private method to set the GUI in stopped mode.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__showSource">__showSource</a></td> -<td>Private slot to show the source of a traceback in an eric editor.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.__stopTests">__stopTests</a></td> -<td>Private slot to stop the test.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.clearRecent">clearRecent</a></td> -<td>Public slot to clear the recently used lists.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.closeEvent">closeEvent</a></td> -<td>Protected method to handle the close event.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.hasFailedTests">hasFailedTests</a></td> -<td>Public method to check, if there are failed tests from the last run.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.insertDiscovery">insertDiscovery</a></td> -<td>Public slot to insert the discovery start directory into the discoveryPicker object.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.insertProg">insertProg</a></td> -<td>Public slot to insert the filename prog into the testsuitePicker object.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.insertTestName">insertTestName</a></td> -<td>Public slot to insert a test name into the testComboBox object.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.keyPressEvent">keyPressEvent</a></td> -<td>Protected slot to handle key press events.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_buttonBox_clicked">on_buttonBox_clicked</a></td> -<td>Private slot called by a button of the button box clicked.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_discoverCheckBox_toggled">on_discoverCheckBox_toggled</a></td> -<td>Private slot handling state changes of the 'discover' checkbox.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_discoveryList_itemChanged">on_discoveryList_itemChanged</a></td> -<td>Private slot handling the user checking or unchecking an item.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_discoveryList_itemDoubleClicked">on_discoveryList_itemDoubleClicked</a></td> -<td>Private slot handling the user double clicking an item.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_errorsListWidget_currentTextChanged">on_errorsListWidget_currentTextChanged</a></td> -<td>Private slot to handle the highlighted signal.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_errorsListWidget_itemDoubleClicked">on_errorsListWidget_itemDoubleClicked</a></td> -<td>Private slot called by doubleclicking an errorlist entry.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog">on_testsuitePicker_aboutToShowPathPickerDialog</a></td> -<td>Private slot called before the test suite selection dialog is shown.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_testsuitePicker_editTextChanged">on_testsuitePicker_editTextChanged</a></td> -<td>Private slot handling changes of the test suite path.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.on_testsuitePicker_pathSelected">on_testsuitePicker_pathSelected</a></td> -<td>Private slot called after a test suite has been selected.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.setProjectMode">setProjectMode</a></td> -<td>Public method to set the project mode of the dialog.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.startTests">startTests</a></td> -<td>Public slot to start the test.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testErrored">testErrored</a></td> -<td>Public method called if a test errors.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testFailed">testFailed</a></td> -<td>Public method called if a test fails.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testFailedExpected">testFailedExpected</a></td> -<td>Public method called if a test fails as expected.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testFinished">testFinished</a></td> -<td>Public method called if a test has finished.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testSkipped">testSkipped</a></td> -<td>Public method called if a test was skipped.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testStarted">testStarted</a></td> -<td>Public method called if a test is about to be run.</td> -</tr> -<tr> -<td><a href="#UnittestDialog.testSucceededUnexpected">testSucceededUnexpected</a></td> -<td>Public method called if a test succeeds unexpectedly.</td> -</tr> -</table> -<h3>Static Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> - -<a NAME="UnittestDialog.__init__" ID="UnittestDialog.__init__"></a> -<h4>UnittestDialog (Constructor)</h4> -<b>UnittestDialog</b>(<i>prog=None, dbs=None, ui=None, parent=None, name=None</i>) - -<p> - Constructor -</p> -<dl> - -<dt><i>prog</i> (str)</dt> -<dd> -filename of the program to open -</dd> -<dt><i>dbs</i> (DebugServer)</dt> -<dd> -reference to the debug server object. It is an indication - whether we were called from within the eric IDE. -</dd> -<dt><i>ui</i> (UserInterface)</dt> -<dd> -reference to the UI object -</dd> -<dt><i>parent</i> (QWidget)</dt> -<dd> -parent widget of this dialog -</dd> -<dt><i>name</i> (str)</dt> -<dd> -name of this dialog -</dd> -</dl> -<a NAME="UnittestDialog.__UTDiscovered" ID="UnittestDialog.__UTDiscovered"></a> -<h4>UnittestDialog.__UTDiscovered</h4> -<b>__UTDiscovered</b>(<i>testCases, exc_type, exc_value</i>) - -<p> - Private slot to handle the utDiscovered signal. -</p> -<p> - If the unittest suite was loaded successfully, we ask the - client to run the test suite. -</p> -<dl> - -<dt><i>testCases</i> (str)</dt> -<dd> -list of detected test cases -</dd> -<dt><i>exc_type</i> (str)</dt> -<dd> -exception type occured during discovery -</dd> -<dt><i>exc_value</i> (str)</dt> -<dd> -value of exception occured during discovery -</dd> -</dl> -<a NAME="UnittestDialog.__UTPrepared" ID="UnittestDialog.__UTPrepared"></a> -<h4>UnittestDialog.__UTPrepared</h4> -<b>__UTPrepared</b>(<i>nrTests, exc_type, exc_value</i>) - -<p> - Private slot to handle the utPrepared signal. -</p> -<p> - If the unittest suite was loaded successfully, we ask the - client to run the test suite. -</p> -<dl> - -<dt><i>nrTests</i></dt> -<dd> -number of tests contained in the test suite (integer) -</dd> -<dt><i>exc_type</i></dt> -<dd> -type of exception occured during preparation (string) -</dd> -<dt><i>exc_value</i></dt> -<dd> -value of exception occured during preparation (string) -</dd> -</dl> -<a NAME="UnittestDialog.__assembleTestCasesList" ID="UnittestDialog.__assembleTestCasesList"></a> -<h4>UnittestDialog.__assembleTestCasesList</h4> -<b>__assembleTestCasesList</b>(<i>suite, start</i>) - -<p> - Private method to assemble a list of test cases included in a test - suite. -</p> -<dl> - -<dt><i>suite</i> (unittest.TestSuite)</dt> -<dd> -test suite to be inspected -</dd> -<dt><i>start</i> (str)</dt> -<dd> -name of directory discovery was started at -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -list of tuples containing the test case ID, a short description - and the path of the test file name -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -list of tuples of (str, str, str) -</dd> -</dl> -<a NAME="UnittestDialog.__discover" ID="UnittestDialog.__discover"></a> -<h4>UnittestDialog.__discover</h4> -<b>__discover</b>(<i></i>) - -<p> - Private slot to discover unit test but don't run them. -</p> -<a NAME="UnittestDialog.__findDiscoveryItem" ID="UnittestDialog.__findDiscoveryItem"></a> -<h4>UnittestDialog.__findDiscoveryItem</h4> -<b>__findDiscoveryItem</b>(<i>modulePath</i>) - -<p> - Private method to find an item given the module path. -</p> -<dl> - -<dt><i>modulePath</i> (str)</dt> -<dd> -path of the module in dotted notation -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -reference to the item or None -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -QTreeWidgetItem or None -</dd> -</dl> -<a NAME="UnittestDialog.__loadRecent" ID="UnittestDialog.__loadRecent"></a> -<h4>UnittestDialog.__loadRecent</h4> -<b>__loadRecent</b>(<i></i>) - -<p> - Private method to load the most recently used lists. -</p> -<a NAME="UnittestDialog.__openEditor" ID="UnittestDialog.__openEditor"></a> -<h4>UnittestDialog.__openEditor</h4> -<b>__openEditor</b>(<i>filename, linenumber</i>) - -<p> - Private method to open an editor window for the given file. -</p> -<p> - Note: This method opens an editor window when the unittest dialog - is called as a standalone application. -</p> -<dl> - -<dt><i>filename</i> (str)</dt> -<dd> -path of the file to be opened -</dd> -<dt><i>linenumber</i> (int)</dt> -<dd> -line number to place the cursor at -</dd> -</dl> -<a NAME="UnittestDialog.__populateDiscoveryResults" ID="UnittestDialog.__populateDiscoveryResults"></a> -<h4>UnittestDialog.__populateDiscoveryResults</h4> -<b>__populateDiscoveryResults</b>(<i>tests</i>) - -<p> - Private method to populate the test discovery results list. -</p> -<dl> - -<dt><i>tests</i> (list of tuples of (str, str, str))</dt> -<dd> -list of tuples containing the discovery results -</dd> -</dl> -<a NAME="UnittestDialog.__populateVenvComboBox" ID="UnittestDialog.__populateVenvComboBox"></a> -<h4>UnittestDialog.__populateVenvComboBox</h4> -<b>__populateVenvComboBox</b>(<i></i>) - -<p> - Private method to (re-)populate the virtual environments selector. -</p> -<a NAME="UnittestDialog.__saveRecent" ID="UnittestDialog.__saveRecent"></a> -<h4>UnittestDialog.__saveRecent</h4> -<b>__saveRecent</b>(<i></i>) - -<p> - Private method to save the most recently used lists. -</p> -<a NAME="UnittestDialog.__selectedTestCases" ID="UnittestDialog.__selectedTestCases"></a> -<h4>UnittestDialog.__selectedTestCases</h4> -<b>__selectedTestCases</b>(<i>parent=None</i>) - -<p> - Private method to assemble the list of selected test cases and suites. -</p> -<dl> - -<dt><i>parent</i> (QTreeWidgetItem)</dt> -<dd> -reference to the parent item -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -list of selected test cases -</dd> -</dl> -<dl> -<dt>Return Type:</dt> -<dd> -list of str -</dd> -</dl> -<a NAME="UnittestDialog.__setProgressColor" ID="UnittestDialog.__setProgressColor"></a> -<h4>UnittestDialog.__setProgressColor</h4> -<b>__setProgressColor</b>(<i>color</i>) - -<p> - Private method to set the color of the progress color label. -</p> -<dl> - -<dt><i>color</i></dt> -<dd> -colour to be shown (string) -</dd> -</dl> -<a NAME="UnittestDialog.__setRunningMode" ID="UnittestDialog.__setRunningMode"></a> -<h4>UnittestDialog.__setRunningMode</h4> -<b>__setRunningMode</b>(<i></i>) - -<p> - Private method to set the GUI in running mode. -</p> -<a NAME="UnittestDialog.__setStoppedMode" ID="UnittestDialog.__setStoppedMode"></a> -<h4>UnittestDialog.__setStoppedMode</h4> -<b>__setStoppedMode</b>(<i></i>) - -<p> - Private method to set the GUI in stopped mode. -</p> -<a NAME="UnittestDialog.__showSource" ID="UnittestDialog.__showSource"></a> -<h4>UnittestDialog.__showSource</h4> -<b>__showSource</b>(<i></i>) - -<p> - Private slot to show the source of a traceback in an eric editor. -</p> -<a NAME="UnittestDialog.__stopTests" ID="UnittestDialog.__stopTests"></a> -<h4>UnittestDialog.__stopTests</h4> -<b>__stopTests</b>(<i></i>) - -<p> - Private slot to stop the test. -</p> -<a NAME="UnittestDialog.clearRecent" ID="UnittestDialog.clearRecent"></a> -<h4>UnittestDialog.clearRecent</h4> -<b>clearRecent</b>(<i></i>) - -<p> - Public slot to clear the recently used lists. -</p> -<a NAME="UnittestDialog.closeEvent" ID="UnittestDialog.closeEvent"></a> -<h4>UnittestDialog.closeEvent</h4> -<b>closeEvent</b>(<i>event</i>) - -<p> - Protected method to handle the close event. -</p> -<dl> - -<dt><i>event</i> (QCloseEvent)</dt> -<dd> -close event -</dd> -</dl> -<a NAME="UnittestDialog.hasFailedTests" ID="UnittestDialog.hasFailedTests"></a> -<h4>UnittestDialog.hasFailedTests</h4> -<b>hasFailedTests</b>(<i></i>) - -<p> - Public method to check, if there are failed tests from the last run. -</p> -<dl> -<dt>Return:</dt> -<dd> -flag indicating the presence of failed tests (boolean) -</dd> -</dl> -<a NAME="UnittestDialog.insertDiscovery" ID="UnittestDialog.insertDiscovery"></a> -<h4>UnittestDialog.insertDiscovery</h4> -<b>insertDiscovery</b>(<i>start</i>) - -<p> - Public slot to insert the discovery start directory into the - discoveryPicker object. -</p> -<dl> - -<dt><i>start</i> (str)</dt> -<dd> -start directory name to be inserted -</dd> -</dl> -<a NAME="UnittestDialog.insertProg" ID="UnittestDialog.insertProg"></a> -<h4>UnittestDialog.insertProg</h4> -<b>insertProg</b>(<i>prog</i>) - -<p> - Public slot to insert the filename prog into the testsuitePicker - object. -</p> -<dl> - -<dt><i>prog</i></dt> -<dd> -filename to be inserted (string) -</dd> -</dl> -<a NAME="UnittestDialog.insertTestName" ID="UnittestDialog.insertTestName"></a> -<h4>UnittestDialog.insertTestName</h4> -<b>insertTestName</b>(<i>testName</i>) - -<p> - Public slot to insert a test name into the testComboBox object. -</p> -<dl> - -<dt><i>testName</i></dt> -<dd> -name of the test to be inserted (string) -</dd> -</dl> -<a NAME="UnittestDialog.keyPressEvent" ID="UnittestDialog.keyPressEvent"></a> -<h4>UnittestDialog.keyPressEvent</h4> -<b>keyPressEvent</b>(<i>evt</i>) - -<p> - Protected slot to handle key press events. -</p> -<dl> - -<dt><i>evt</i></dt> -<dd> -key press event to handle (QKeyEvent) -</dd> -</dl> -<a NAME="UnittestDialog.on_buttonBox_clicked" ID="UnittestDialog.on_buttonBox_clicked"></a> -<h4>UnittestDialog.on_buttonBox_clicked</h4> -<b>on_buttonBox_clicked</b>(<i>button</i>) - -<p> - Private slot called by a button of the button box clicked. -</p> -<dl> - -<dt><i>button</i></dt> -<dd> -button that was clicked (QAbstractButton) -</dd> -</dl> -<a NAME="UnittestDialog.on_discoverCheckBox_toggled" ID="UnittestDialog.on_discoverCheckBox_toggled"></a> -<h4>UnittestDialog.on_discoverCheckBox_toggled</h4> -<b>on_discoverCheckBox_toggled</b>(<i>checked</i>) - -<p> - Private slot handling state changes of the 'discover' checkbox. -</p> -<dl> - -<dt><i>checked</i> (bool)</dt> -<dd> -state of the checkbox -</dd> -</dl> -<a NAME="UnittestDialog.on_discoveryList_itemChanged" ID="UnittestDialog.on_discoveryList_itemChanged"></a> -<h4>UnittestDialog.on_discoveryList_itemChanged</h4> -<b>on_discoveryList_itemChanged</b>(<i>item, column</i>) - -<p> - Private slot handling the user checking or unchecking an item. -</p> -<dl> - -<dt><i>item</i> (QTreeWidgetItem)</dt> -<dd> -reference to the item -</dd> -<dt><i>column</i> (int)</dt> -<dd> -changed column -</dd> -</dl> -<a NAME="UnittestDialog.on_discoveryList_itemDoubleClicked" ID="UnittestDialog.on_discoveryList_itemDoubleClicked"></a> -<h4>UnittestDialog.on_discoveryList_itemDoubleClicked</h4> -<b>on_discoveryList_itemDoubleClicked</b>(<i>item, column</i>) - -<p> - Private slot handling the user double clicking an item. -</p> -<dl> - -<dt><i>item</i> (QTreeWidgetItem)</dt> -<dd> -reference to the item -</dd> -<dt><i>column</i> (int)</dt> -<dd> -column of the double click -</dd> -</dl> -<a NAME="UnittestDialog.on_errorsListWidget_currentTextChanged" ID="UnittestDialog.on_errorsListWidget_currentTextChanged"></a> -<h4>UnittestDialog.on_errorsListWidget_currentTextChanged</h4> -<b>on_errorsListWidget_currentTextChanged</b>(<i>text</i>) - -<p> - Private slot to handle the highlighted signal. -</p> -<dl> - -<dt><i>text</i></dt> -<dd> -current text (string) -</dd> -</dl> -<a NAME="UnittestDialog.on_errorsListWidget_itemDoubleClicked" ID="UnittestDialog.on_errorsListWidget_itemDoubleClicked"></a> -<h4>UnittestDialog.on_errorsListWidget_itemDoubleClicked</h4> -<b>on_errorsListWidget_itemDoubleClicked</b>(<i>lbitem</i>) - -<p> - Private slot called by doubleclicking an errorlist entry. -</p> -<p> - It will popup a dialog showing the stacktrace. - If called from eric, an additional button is displayed - to show the python source in an eric source viewer (in - erics main window. -</p> -<dl> - -<dt><i>lbitem</i></dt> -<dd> -the listbox item that was double clicked -</dd> -</dl> -<a NAME="UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog" ID="UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog"></a> -<h4>UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog</h4> -<b>on_testsuitePicker_aboutToShowPathPickerDialog</b>(<i></i>) - -<p> - Private slot called before the test suite selection dialog is shown. -</p> -<a NAME="UnittestDialog.on_testsuitePicker_editTextChanged" ID="UnittestDialog.on_testsuitePicker_editTextChanged"></a> -<h4>UnittestDialog.on_testsuitePicker_editTextChanged</h4> -<b>on_testsuitePicker_editTextChanged</b>(<i>path</i>) - -<p> - Private slot handling changes of the test suite path. -</p> -<dl> - -<dt><i>path</i> (str)</dt> -<dd> -path of the test suite file -</dd> -</dl> -<a NAME="UnittestDialog.on_testsuitePicker_pathSelected" ID="UnittestDialog.on_testsuitePicker_pathSelected"></a> -<h4>UnittestDialog.on_testsuitePicker_pathSelected</h4> -<b>on_testsuitePicker_pathSelected</b>(<i>suite</i>) - -<p> - Private slot called after a test suite has been selected. -</p> -<dl> - -<dt><i>suite</i> (str)</dt> -<dd> -file name of the test suite -</dd> -</dl> -<a NAME="UnittestDialog.setProjectMode" ID="UnittestDialog.setProjectMode"></a> -<h4>UnittestDialog.setProjectMode</h4> -<b>setProjectMode</b>(<i>forProject</i>) - -<p> - Public method to set the project mode of the dialog. -</p> -<dl> - -<dt><i>forProject</i> (bool)</dt> -<dd> -flag indicating to run for the open project -</dd> -</dl> -<a NAME="UnittestDialog.startTests" ID="UnittestDialog.startTests"></a> -<h4>UnittestDialog.startTests</h4> -<b>startTests</b>(<i>failedOnly=False</i>) - -<p> - Public slot to start the test. -</p> -<dl> - -<dt><i>failedOnly</i></dt> -<dd> -flag indicating to run only failed tests (boolean) -</dd> -</dl> -<a NAME="UnittestDialog.testErrored" ID="UnittestDialog.testErrored"></a> -<h4>UnittestDialog.testErrored</h4> -<b>testErrored</b>(<i>test, exc, testId</i>) - -<p> - Public method called if a test errors. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the test (string) -</dd> -<dt><i>exc</i></dt> -<dd> -string representation of the exception (string) -</dd> -<dt><i>testId</i></dt> -<dd> -id of the test (string) -</dd> -</dl> -<a NAME="UnittestDialog.testFailed" ID="UnittestDialog.testFailed"></a> -<h4>UnittestDialog.testFailed</h4> -<b>testFailed</b>(<i>test, exc, testId</i>) - -<p> - Public method called if a test fails. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the test (string) -</dd> -<dt><i>exc</i></dt> -<dd> -string representation of the exception (string) -</dd> -<dt><i>testId</i></dt> -<dd> -id of the test (string) -</dd> -</dl> -<a NAME="UnittestDialog.testFailedExpected" ID="UnittestDialog.testFailedExpected"></a> -<h4>UnittestDialog.testFailedExpected</h4> -<b>testFailedExpected</b>(<i>test, exc, testId</i>) - -<p> - Public method called if a test fails as expected. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the test (string) -</dd> -<dt><i>exc</i></dt> -<dd> -string representation of the exception (string) -</dd> -<dt><i>testId</i></dt> -<dd> -id of the test (string) -</dd> -</dl> -<a NAME="UnittestDialog.testFinished" ID="UnittestDialog.testFinished"></a> -<h4>UnittestDialog.testFinished</h4> -<b>testFinished</b>(<i></i>) - -<p> - Public method called if a test has finished. -</p> -<p> - <b>Note</b>: It is also called if it has already failed or errored. -</p> -<a NAME="UnittestDialog.testSkipped" ID="UnittestDialog.testSkipped"></a> -<h4>UnittestDialog.testSkipped</h4> -<b>testSkipped</b>(<i>test, reason, testId</i>) - -<p> - Public method called if a test was skipped. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the test (string) -</dd> -<dt><i>reason</i></dt> -<dd> -reason for skipping the test (string) -</dd> -<dt><i>testId</i></dt> -<dd> -id of the test (string) -</dd> -</dl> -<a NAME="UnittestDialog.testStarted" ID="UnittestDialog.testStarted"></a> -<h4>UnittestDialog.testStarted</h4> -<b>testStarted</b>(<i>test, doc</i>) - -<p> - Public method called if a test is about to be run. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the started test (string) -</dd> -<dt><i>doc</i></dt> -<dd> -documentation of the started test (string) -</dd> -</dl> -<a NAME="UnittestDialog.testSucceededUnexpected" ID="UnittestDialog.testSucceededUnexpected"></a> -<h4>UnittestDialog.testSucceededUnexpected</h4> -<b>testSucceededUnexpected</b>(<i>test, testId</i>) - -<p> - Public method called if a test succeeds unexpectedly. -</p> -<dl> - -<dt><i>test</i></dt> -<dd> -name of the test (string) -</dd> -<dt><i>testId</i></dt> -<dd> -id of the test (string) -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -<hr /> -<a NAME="UnittestWindow" ID="UnittestWindow"></a> -<h2>UnittestWindow</h2> - -<p> - Main window class for the standalone dialog. -</p> -<h3>Derived from</h3> -EricMainWindow -<h3>Class Attributes</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Class Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> -<h3>Methods</h3> - -<table> - -<tr> -<td><a href="#UnittestWindow.__init__">UnittestWindow</a></td> -<td>Constructor</td> -</tr> -<tr> -<td><a href="#UnittestWindow.eventFilter">eventFilter</a></td> -<td>Public method to filter events.</td> -</tr> -</table> -<h3>Static Methods</h3> - -<table> -<tr><td>None</td></tr> -</table> - -<a NAME="UnittestWindow.__init__" ID="UnittestWindow.__init__"></a> -<h4>UnittestWindow (Constructor)</h4> -<b>UnittestWindow</b>(<i>prog=None, parent=None</i>) - -<p> - Constructor -</p> -<dl> - -<dt><i>prog</i></dt> -<dd> -filename of the program to open -</dd> -<dt><i>parent</i></dt> -<dd> -reference to the parent widget (QWidget) -</dd> -</dl> -<a NAME="UnittestWindow.eventFilter" ID="UnittestWindow.eventFilter"></a> -<h4>UnittestWindow.eventFilter</h4> -<b>eventFilter</b>(<i>obj, event</i>) - -<p> - Public method to filter events. -</p> -<dl> - -<dt><i>obj</i></dt> -<dd> -reference to the object the event is meant for (QObject) -</dd> -<dt><i>event</i></dt> -<dd> -reference to the event object (QEvent) -</dd> -</dl> -<dl> -<dt>Return:</dt> -<dd> -flag indicating, whether the event was handled (boolean) -</dd> -</dl> -<div align="right"><a href="#top">Up</a></div> -<hr /> -<hr /> -<a NAME="clearSavedHistories" ID="clearSavedHistories"></a> -<h2>clearSavedHistories</h2> -<b>clearSavedHistories</b>(<i>self</i>) - -<p> - Function to clear the saved history lists. -</p> -<div align="right"><a href="#top">Up</a></div> -<hr /> -</body></html> \ No newline at end of file
--- a/eric7/Documentation/Source/index-eric7.PyUnit.html Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html><head> -<title>eric7.PyUnit</title> -<meta charset="UTF-8"> -<link rel="stylesheet" href="styles.css"> -</head> -<body> -<h1>eric7.PyUnit</h1> - -<p> -Package implementing an interface to the pyunit unittest package. -</p> -<p> -The package consist of a single dialog, which may be called as a -standalone version using the eric7_unittest script or from within the eric -IDE. If it is called from within eric, it has the additional function to -open a source file that failed a test. -</p> - - -<h3>Modules</h3> -<table> - -<tr> -<td><a href="eric7.PyUnit.UnittestDialog.html">UnittestDialog</a></td> -<td>Module implementing the UI to the pyunit package.</td> -</tr> -</table> -</body></html> \ No newline at end of file
--- a/eric7/Project/PropertiesDialog.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Project/PropertiesDialog.py Wed May 18 10:54:32 2022 +0200 @@ -55,10 +55,10 @@ getSupportedDocstringTypes() ): self.docstringStyleComboBox.addItem(docstringStyle, docstringType) - - self.testingFrameworkComboBox.addItem(self.tr("None"), "") - for framework in sorted(FrameworkNames): - self.testingFrameworkComboBox.addItem(framework, framework) +## +## self.testingFrameworkComboBox.addItem(self.tr("None"), "") +## for framework in sorted(FrameworkNames): +## self.testingFrameworkComboBox.addItem(framework, framework) self.project = project self.newProject = new @@ -160,29 +160,36 @@ bool(self.dirPicker.text()) and self.dirPicker.text() not in self.__initPaths) - @pyqtSlot(int) - def on_languageComboBox_currentIndexChanged(self, index): + @pyqtSlot(str) + def on_languageComboBox_currentTextChanged(self, language): """ Private slot handling the selection of a programming language. - @param index index of the current item - @type int + @param language text of the current item + @type str """ - language = self.languageComboBox.itemText(index) curProjectType = self.getProjectType() - projectTypes = [] - for projectTypeItem in self.project.getProjectTypes(language).items(): - projectTypes.append((projectTypeItem[1], projectTypeItem[0])) self.projectTypeComboBox.clear() - for projectType in sorted(projectTypes): + for projectType in sorted( + self.project.getProjectTypes(language).items(), + key=lambda k: k[1] + ): self.projectTypeComboBox.addItem( - projectType[0], projectType[1]) + projectType[1], projectType[0]) index = self.projectTypeComboBox.findData(curProjectType) if index == -1: index = 0 self.projectTypeComboBox.setCurrentIndex(index) + + curTestingFramework = self.testingFrameworkComboBox.currentText() + self.testingFrameworkComboBox.clear() + self.testingFrameworkComboBox.addItem(self.tr("None"), "") + with contextlib.suppress(KeyError): + for framework in sorted(FrameworkNames[language]): + self.testingFrameworkComboBox.addItem(framework, framework) + self.testingFrameworkComboBox.setCurrentText(curTestingFramework) @pyqtSlot(str) def on_dirPicker_textChanged(self, txt):
--- a/eric7/PyUnit/UnittestDialog.py Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1506 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing the UI to the pyunit package. -""" - -import unittest -import sys -import time -import re -import os -import contextlib - -from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent, QFileInfo -from PyQt6.QtGui import QColor -from PyQt6.QtWidgets import ( - QWidget, QDialog, QApplication, QDialogButtonBox, QListWidgetItem, - QComboBox, QTreeWidgetItem -) - -from EricWidgets.EricApplication import ericApp -from EricWidgets import EricMessageBox -from EricWidgets.EricMainWindow import EricMainWindow -from EricWidgets.EricPathPicker import EricPathPickerModes - -from .Ui_UnittestDialog import Ui_UnittestDialog - -import UI.PixmapCache - -import Preferences - -from Globals import ( - recentNameTestDiscoverHistory, recentNameTestFileHistory, - recentNameTestNameHistory -) - - -class UnittestDialog(QWidget, Ui_UnittestDialog): - """ - Class implementing the UI to the pyunit package. - - @signal unittestFile(str, int, bool) emitted to show the source of a - unittest file - @signal unittestStopped() emitted after a unit test was run - """ - unittestFile = pyqtSignal(str, int, bool) - unittestStopped = pyqtSignal() - - TestCaseNameRole = Qt.ItemDataRole.UserRole - TestCaseFileRole = Qt.ItemDataRole.UserRole + 1 - - ErrorsInfoRole = Qt.ItemDataRole.UserRole - - SkippedColorDarkTheme = QColor("#00aaff") - FailedExpectedColorDarkTheme = QColor("#ccaaff") - SucceededUnexpectedColorDarkTheme = QColor("#ff99dd") - SkippedColorLightTheme = QColor("#0000ff") - FailedExpectedColorLightTheme = QColor("#7700bb") - SucceededUnexpectedColorLightTheme = QColor("#ff0000") - - def __init__(self, prog=None, dbs=None, ui=None, parent=None, name=None): - """ - Constructor - - @param prog filename of the program to open - @type str - @param dbs reference to the debug server object. It is an indication - whether we were called from within the eric IDE. - @type DebugServer - @param ui reference to the UI object - @type UserInterface - @param parent parent widget of this dialog - @type QWidget - @param name name of this dialog - @type str - """ - super().__init__(parent) - if name: - self.setObjectName(name) - self.setupUi(self) - - self.clearHistoriesButton.setIcon( - UI.PixmapCache.getIcon("clearPrivateData")) - - self.testsuitePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) - self.testsuitePicker.setInsertPolicy( - QComboBox.InsertPolicy.InsertAtTop) - self.testsuitePicker.setSizeAdjustPolicy( - QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) - - self.discoveryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) - self.discoveryPicker.setInsertPolicy( - QComboBox.InsertPolicy.InsertAtTop) - self.discoveryPicker.setSizeAdjustPolicy( - QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon) - - self.testComboBox.lineEdit().setClearButtonEnabled(True) - - self.discoverButton = self.buttonBox.addButton( - self.tr("Discover"), QDialogButtonBox.ButtonRole.ActionRole) - self.discoverButton.setToolTip(self.tr( - "Discover tests")) - self.discoverButton.setWhatsThis(self.tr( - """<b>Discover</b>""" - """<p>This button starts a discovery of available tests.</p>""")) - self.startButton = self.buttonBox.addButton( - self.tr("Start"), QDialogButtonBox.ButtonRole.ActionRole) - - self.startButton.setToolTip(self.tr( - "Start the selected testsuite")) - self.startButton.setWhatsThis(self.tr( - """<b>Start Test</b>""" - """<p>This button starts the selected testsuite.</p>""")) - - self.startFailedButton = self.buttonBox.addButton( - self.tr("Rerun Failed"), QDialogButtonBox.ButtonRole.ActionRole) - self.startFailedButton.setToolTip( - self.tr("Reruns failed tests of the selected testsuite")) - self.startFailedButton.setWhatsThis(self.tr( - """<b>Rerun Failed</b>""" - """<p>This button reruns all failed tests of the selected""" - """ testsuite.</p>""")) - - self.stopButton = self.buttonBox.addButton( - self.tr("Stop"), QDialogButtonBox.ButtonRole.ActionRole) - self.stopButton.setToolTip(self.tr("Stop the running unittest")) - self.stopButton.setWhatsThis(self.tr( - """<b>Stop Test</b>""" - """<p>This button stops a running unittest.</p>""")) - - self.discoverButton.setEnabled(False) - self.stopButton.setEnabled(False) - self.startButton.setDefault(True) - self.startFailedButton.setEnabled(False) - - self.__dbs = dbs - self.__forProject = False - - self.setWindowFlags( - self.windowFlags() | - Qt.WindowType.WindowContextHelpButtonHint - ) - self.setWindowIcon(UI.PixmapCache.getIcon("eric")) - self.setWindowTitle(self.tr("Unittest")) - if dbs: - self.ui = ui - - self.debuggerCheckBox.setChecked(True) - - # virtual environment manager is only used in the integrated - # variant - self.__venvManager = ericApp().getObject("VirtualEnvManager") - self.__populateVenvComboBox() - self.__venvManager.virtualEnvironmentAdded.connect( - self.__populateVenvComboBox) - self.__venvManager.virtualEnvironmentRemoved.connect( - self.__populateVenvComboBox) - self.__venvManager.virtualEnvironmentChanged.connect( - self.__populateVenvComboBox) - else: - self.__venvManager = None - self.debuggerCheckBox.setVisible(False) - self.venvComboBox.setVisible(bool(self.__venvManager)) - self.venvLabel.setVisible(bool(self.__venvManager)) - - self.__setProgressColor("green") - self.progressLed.setDarkFactor(150) - self.progressLed.off() - - self.discoverHistory = [] - self.fileHistory = [] - self.testNameHistory = [] - self.running = False - self.savedModulelist = None - self.savedSysPath = sys.path - self.savedCwd = os.getcwd() - - self.rxPatterns = [ - self.tr("^Failure: "), - self.tr("^Error: "), - # These are for untranslated/partially translated situations - "^Failure: ", - "^Error: ", - ] - - self.__failedTests = set() - - # now connect the debug server signals if called from the eric 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) - self.__dbs.utStopTest.connect(self.testFinished) - self.__dbs.utTestFailed.connect(self.testFailed) - self.__dbs.utTestErrored.connect(self.testErrored) - self.__dbs.utTestSkipped.connect(self.testSkipped) - self.__dbs.utTestFailedExpected.connect(self.testFailedExpected) - self.__dbs.utTestSucceededUnexpected.connect( - self.testSucceededUnexpected) - - self.__editors = [] - - self.__loadRecent() - - self.insertProg(prog) - self.insertTestName("") - - self.clearHistoriesButton.clicked.connect(self.clearRecent) - - def keyPressEvent(self, evt): - """ - Protected slot to handle key press events. - - @param evt key press event to handle (QKeyEvent) - """ - if evt.key() == Qt.Key.Key_Escape and self.__dbs: - self.close() - - def __populateVenvComboBox(self): - """ - Private method to (re-)populate the virtual environments selector. - """ - currentText = self.venvComboBox.currentText() - self.venvComboBox.clear() - self.venvComboBox.addItem("") - self.venvComboBox.addItems( - sorted(self.__venvManager.getVirtualenvNames())) - index = self.venvComboBox.findText(currentText) - if index < 0: - index = 0 - self.venvComboBox.setCurrentIndex(index) - - def __setProgressColor(self, color): - """ - Private method to set the color of the progress color label. - - @param color colour to be shown (string) - """ - self.progressLed.setColor(QColor(color)) - - def setProjectMode(self, forProject): - """ - Public method to set the project mode of the dialog. - - @param forProject flag indicating to run for the open project - @type bool - """ - self.__forProject = forProject - if forProject: - project = ericApp().getObject("Project") - if project.isOpen(): - self.insertDiscovery(project.getProjectPath()) - else: - self.insertDiscovery("") - else: - self.insertDiscovery("") - - self.discoveryList.clear() - self.tabWidget.setCurrentIndex(0) - - def insertDiscovery(self, start): - """ - Public slot to insert the discovery start directory into the - discoveryPicker object. - - @param start start directory name to be inserted - @type str - """ - current = self.discoveryPicker.currentText() - - # prepend the given directory to the discovery picker - if start is None: - start = "" - if start in self.discoverHistory: - self.discoverHistory.remove(start) - self.discoverHistory.insert(0, start) - self.discoveryPicker.clear() - self.discoveryPicker.addItems(self.discoverHistory) - - if current: - self.discoveryPicker.setText(current) - - def insertProg(self, prog): - """ - Public slot to insert the filename prog into the testsuitePicker - object. - - @param prog filename to be inserted (string) - """ - current = self.testsuitePicker.currentText() - - # prepend the selected file to the testsuite picker - if prog is None: - prog = "" - if prog in self.fileHistory: - self.fileHistory.remove(prog) - self.fileHistory.insert(0, prog) - self.testsuitePicker.clear() - self.testsuitePicker.addItems(self.fileHistory) - - if current: - self.testsuitePicker.setText(current) - - def insertTestName(self, testName): - """ - Public slot to insert a test name into the testComboBox object. - - @param testName name of the test to be inserted (string) - """ - current = self.testComboBox.currentText() - - # prepend the selected file to the testsuite combobox - if testName is None: - testName = "" - if testName in self.testNameHistory: - self.testNameHistory.remove(testName) - self.testNameHistory.insert(0, testName) - self.testComboBox.clear() - self.testComboBox.addItems(self.testNameHistory) - - if current: - self.testComboBox.setCurrentText(current) - - @pyqtSlot() - def on_testsuitePicker_aboutToShowPathPickerDialog(self): - """ - Private slot called before the test suite selection dialog is shown. - """ - if self.__dbs: - py3Extensions = ' '.join( - ["*{0}".format(ext) - for ext in self.__dbs.getExtensions('Python3')] - ) - fileFilter = self.tr( - "Python3 Files ({0});;All Files (*)" - ).format(py3Extensions) - else: - fileFilter = self.tr("Python Files (*.py);;All Files (*)") - self.testsuitePicker.setFilters(fileFilter) - - defaultDirectory = Preferences.getMultiProject("Workspace") - if not defaultDirectory: - defaultDirectory = os.path.expanduser("~") - if self.__dbs: - project = ericApp().getObject("Project") - if self.__forProject and project.isOpen(): - defaultDirectory = project.getProjectPath() - self.testsuitePicker.setDefaultDirectory(defaultDirectory) - - @pyqtSlot(str) - def on_testsuitePicker_pathSelected(self, suite): - """ - Private slot called after a test suite has been selected. - - @param suite file name of the test suite - @type str - """ - self.insertProg(suite) - - @pyqtSlot(str) - def on_testsuitePicker_editTextChanged(self, path): - """ - Private slot handling changes of the test suite path. - - @param path path of the test suite file - @type str - """ - self.startFailedButton.setEnabled(False) - - @pyqtSlot(bool) - def on_discoverCheckBox_toggled(self, checked): - """ - Private slot handling state changes of the 'discover' checkbox. - - @param checked state of the checkbox - @type bool - """ - self.discoverButton.setEnabled(checked) - self.discoveryList.clear() - - if not bool(self.discoveryPicker.currentText()): - if self.__forProject: - project = ericApp().getObject("Project") - if project.isOpen(): - self.insertDiscovery(project.getProjectPath()) - return - - self.insertDiscovery(Preferences.getMultiProject("Workspace")) - - def on_buttonBox_clicked(self, button): - """ - Private slot called by a button of the button box clicked. - - @param button button that was clicked (QAbstractButton) - """ - if button == self.discoverButton: - self.__discover() - self.__saveRecent() - elif button == self.startButton: - self.startTests() - self.__saveRecent() - elif button == self.stopButton: - self.__stopTests() - elif button == self.startFailedButton: - self.startTests(failedOnly=True) - - def __loadRecent(self): - """ - Private method to load the most recently used lists. - """ - Preferences.Prefs.rsettings.sync() - - # 1. discovery history - self.discoverHistory = [] - rs = Preferences.Prefs.rsettings.value( - recentNameTestDiscoverHistory) - if rs is not None: - recent = [f - for f in Preferences.toList(rs) - if QFileInfo(f).exists()] - self.discoverHistory = recent[ - :Preferences.getDebugger("RecentNumber")] - - # 2. test file history - self.fileHistory = [] - rs = Preferences.Prefs.rsettings.value( - recentNameTestFileHistory) - if rs is not None: - recent = [f - for f in Preferences.toList(rs) - if QFileInfo(f).exists()] - self.fileHistory = recent[ - :Preferences.getDebugger("RecentNumber")] - - # 3. test name history - self.testNameHistory = [] - rs = Preferences.Prefs.rsettings.value( - recentNameTestNameHistory) - if rs is not None: - recent = [n for n in Preferences.toList(rs) if n] - self.testNameHistory = recent[ - :Preferences.getDebugger("RecentNumber")] - - def __saveRecent(self): - """ - Private method to save the most recently used lists. - """ - Preferences.Prefs.rsettings.setValue( - recentNameTestDiscoverHistory, self.discoverHistory) - Preferences.Prefs.rsettings.setValue( - recentNameTestFileHistory, self.fileHistory) - Preferences.Prefs.rsettings.setValue( - recentNameTestNameHistory, self.testNameHistory) - - Preferences.Prefs.rsettings.sync() - - @pyqtSlot() - def clearRecent(self): - """ - Public slot to clear the recently used lists. - """ - # clear histories - self.discoverHistory = [] - self.fileHistory = [] - self.testNameHistory = [] - - # clear widgets with histories - self.discoveryPicker.clear() - self.testsuitePicker.clear() - self.testComboBox.clear() - - # sync histories - self.__saveRecent() - - @pyqtSlot() - def __discover(self): - """ - Private slot to discover unit test but don't run them. - """ - if self.running: - return - - self.discoveryList.clear() - - discoveryStart = self.discoveryPicker.currentText() - self.insertDiscovery(discoveryStart) - self.sbLabel.setText(self.tr("Discovering Tests")) - QApplication.processEvents() - - self.testName = self.tr("Unittest with auto-discovery") - if self.__dbs: - venvName = self.venvComboBox.currentText() - - # we are cooperating with the eric IDE - project = ericApp().getObject("Project") - if self.__forProject: - mainScript = project.getMainScript(True) - clientType = project.getProjectLanguage() - if mainScript: - workdir = os.path.dirname(os.path.abspath(mainScript)) - else: - workdir = project.getProjectPath() - sysPath = [workdir] - if not discoveryStart: - discoveryStart = workdir - else: - if not discoveryStart: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr("You must enter a start directory for" - " auto-discovery.")) - return - - workdir = "" - clientType = "Python3" - sysPath = [] - self.__dbs.remoteUTDiscover(clientType, self.__forProject, - venvName, sysPath, workdir, - discoveryStart) - else: - # we are running as an application - if not discoveryStart: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr("You must enter a start directory for" - " auto-discovery.")) - return - - if discoveryStart: - sys.path = ( - [os.path.abspath(discoveryStart)] + - self.savedSysPath - ) - - # clean up list of imported modules to force a reimport upon - # running the test - if self.savedModulelist: - for modname in list(sys.modules.keys()): - if modname not in self.savedModulelist: - # delete it - del(sys.modules[modname]) - self.savedModulelist = sys.modules.copy() - - # now try to discover the testsuite - os.chdir(discoveryStart) - try: - testLoader = unittest.TestLoader() - test = testLoader.discover(discoveryStart) - if hasattr(testLoader, "errors") and bool(testLoader.errors): - EricMessageBox.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, discoveryStart) - 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() - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr( - "<p>Unable to discover tests.</p>" - "<p>{0}<br/>{1}</p>") - .format(str(exc_type), - str(exc_value).replace("\n", "<br/>")) - ) - self.sbLabel.clear() - - sys.path = self.savedSysPath - - def __assembleTestCasesList(self, suite, start): - """ - Private method to assemble a list of test cases included in a test - suite. - - @param suite test suite to be inspected - @type unittest.TestSuite - @param start name of directory discovery was started at - @type str - @return list of tuples containing the test case ID, a short description - and the path of the test file name - @rtype list of tuples of (str, str, str) - """ - testCases = [] - for test in suite: - if isinstance(test, unittest.TestSuite): - testCases.extend(self.__assembleTestCasesList(test, start)) - else: - testId = test.id() - if ( - "ModuleImportFailure" not in testId and - "LoadTestsFailure" not in testId and - "_FailedTest" not in testId - ): - filename = os.path.join( - start, - test.__module__.replace(".", os.sep) + ".py") - testCases.append( - (test.id(), test.shortDescription(), filename) - ) - return testCases - - def __findDiscoveryItem(self, modulePath): - """ - Private method to find an item given the module path. - - @param modulePath path of the module in dotted notation - @type str - @return reference to the item or None - @rtype QTreeWidgetItem or None - """ - itm = self.discoveryList.topLevelItem(0) - while itm is not None: - if itm.data(0, UnittestDialog.TestCaseNameRole) == modulePath: - return itm - itm = self.discoveryList.itemBelow(itm) - - return None - - def __populateDiscoveryResults(self, tests): - """ - Private method to populate the test discovery results list. - - @param tests list of tuples containing the discovery results - @type list of tuples of (str, str, str) - """ - for test, _testDescription, filename in tests: - testPath = test.split(".") - pitm = None - for index in range(1, len(testPath) + 1): - modulePath = ".".join(testPath[:index]) - itm = self.__findDiscoveryItem(modulePath) - if itm is not None: - pitm = itm - else: - if pitm is None: - itm = QTreeWidgetItem(self.discoveryList, - [testPath[index - 1]]) - else: - itm = QTreeWidgetItem(pitm, - [testPath[index - 1]]) - pitm.setExpanded(True) - itm.setFlags(Qt.ItemFlag.ItemIsUserCheckable | - Qt.ItemFlag.ItemIsEnabled) - itm.setCheckState(0, Qt.CheckState.Unchecked) - itm.setData(0, UnittestDialog.TestCaseNameRole, modulePath) - if ( - os.path.splitext(os.path.basename(filename))[0] == - itm.text(0) - ): - itm.setData(0, UnittestDialog.TestCaseFileRole, - filename) - elif pitm: - fn = pitm.data(0, UnittestDialog.TestCaseFileRole) - if fn: - itm.setData(0, UnittestDialog.TestCaseFileRole, fn) - 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 = [] - itemsList = [ - self.discoveryList.topLevelItem(index) - for index in range(self.discoveryList.topLevelItemCount()) - ] if parent is None else [ - parent.child(index) - for index in range(parent.childCount()) - ] - - for itm in itemsList: - if ( - itm.checkState(0) == Qt.CheckState.Checked and - itm.childCount() == 0 - ): - selectedTests.append( - itm.data(0, UnittestDialog.TestCaseNameRole)) - if 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 utDiscovered 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 list of 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: - EricMessageBox.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(QTreeWidgetItem, int) - def on_discoveryList_itemChanged(self, item, column): - """ - Private slot handling the user checking or unchecking an item. - - @param item reference to the item - @type QTreeWidgetItem - @param column changed column - @type int - """ - if column == 0: - for index in range(item.childCount()): - item.child(index).setCheckState(0, item.checkState(0)) - - @pyqtSlot(QTreeWidgetItem, int) - def on_discoveryList_itemDoubleClicked(self, item, column): - """ - Private slot handling the user double clicking an item. - - @param item reference to the item - @type QTreeWidgetItem - @param column column of the double click - @type int - """ - if item: - filename = item.data(0, UnittestDialog.TestCaseFileRole) - if filename: - if self.__dbs: - # running as part of eric IDE - self.unittestFile.emit(filename, 1, False) - else: - self.__openEditor(filename, 1) - - @pyqtSlot() - def startTests(self, failedOnly=False): - """ - Public slot to start the test. - - @param failedOnly flag indicating to run only failed tests (boolean) - """ - if self.running: - return - - discover = self.discoverCheckBox.isChecked() - if discover: - discoveryStart = self.discoveryPicker.currentText() - testFileName = "" - testName = "" - - if discoveryStart: - self.insertDiscovery(discoveryStart) - else: - discoveryStart = "" - testFileName = self.testsuitePicker.currentText() - testName = self.testComboBox.currentText() - if testName: - self.insertTestName(testName) - if testFileName and not testName: - testName = "suite" - - if not discover and not testFileName and not testName: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr("You must select auto-discovery or enter a test suite" - " file or a dotted test name.")) - return - - # prepend the selected file to the testsuite combobox - self.insertProg(testFileName) - self.sbLabel.setText(self.tr("Preparing Testsuite")) - QApplication.processEvents() - - if discover: - self.testName = self.tr("Unittest with auto-discovery") - else: - # build the module name from the filename without extension - if testFileName: - self.testName = os.path.splitext( - os.path.basename(testFileName))[0] - elif testName: - self.testName = testName - else: - self.testName = self.tr("<Unnamed Test>") - - if failedOnly: - testCases = [] - else: - testCases = self.__selectedTestCases() - - if not testCases and self.discoveryList.topLevelItemCount(): - ok = EricMessageBox.yesNo( - self, - self.tr("Unittest"), - self.tr("""No test case has been selected. Shall all""" - """ test cases be run?""")) - if not ok: - return - - if self.__dbs: - venvName = self.venvComboBox.currentText() - - # we are cooperating with the eric IDE - project = ericApp().getObject("Project") - if self.__forProject: - mainScript = project.getMainScript(True) - clientType = project.getProjectLanguage() - if mainScript: - workdir = os.path.dirname(os.path.abspath(mainScript)) - coverageFile = os.path.splitext(mainScript)[0] - else: - workdir = project.getProjectPath() - coverageFile = os.path.join(discoveryStart, "unittest") - sysPath = [workdir] - if discover and not discoveryStart: - discoveryStart = workdir - else: - if discover: - if not discoveryStart: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr("You must enter a start directory for" - " auto-discovery.")) - return - - coverageFile = os.path.join(discoveryStart, "unittest") - workdir = "" - clientType = "Python3" - elif testFileName: - mainScript = os.path.abspath(testFileName) - workdir = os.path.dirname(mainScript) - clientType = "Python3" - coverageFile = os.path.splitext(mainScript)[0] - else: - coverageFile = os.path.abspath("unittest") - workdir = "" - clientType = "Python3" - sysPath = [] - if failedOnly and self.__failedTests: - failed = list(self.__failedTests) - if discover: - workdir = discoveryStart - discover = False - else: - failed = [] - self.__failedTests = set() - self.__dbs.remoteUTPrepare( - testFileName, self.testName, testName, failed, - self.coverageCheckBox.isChecked(), coverageFile, - self.coverageEraseCheckBox.isChecked(), clientType=clientType, - forProject=self.__forProject, workdir=workdir, - venvName=venvName, syspath=sysPath, - discover=discover, discoveryStart=discoveryStart, - testCases=testCases, debug=self.debuggerCheckBox.isChecked()) - else: - # we are running as an application - if discover and not discoveryStart: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr("You must enter a start directory for" - " auto-discovery.")) - return - - if testFileName: - sys.path = ( - [os.path.dirname(os.path.abspath(testFileName))] + - self.savedSysPath - ) - elif discoveryStart: - sys.path = ( - [os.path.abspath(discoveryStart)] + - self.savedSysPath - ) - - # clean up list of imported modules to force a reimport upon - # running the test - if self.savedModulelist: - for modname in list(sys.modules.keys()): - if modname not in self.savedModulelist: - # delete it - del(sys.modules[modname]) - self.savedModulelist = sys.modules.copy() - - os.chdir(self.savedCwd) - - # now try to generate the testsuite - try: - testLoader = unittest.TestLoader() - if failedOnly and self.__failedTests: - failed = list(self.__failedTests) - if discover: - os.chdir(discoveryStart) - discover = False - else: - failed = [] - if discover: - if testCases: - test = testLoader.loadTestsFromNames(testCases) - else: - test = testLoader.discover(discoveryStart) - else: - if testFileName: - module = __import__(self.testName) - else: - module = None - if failedOnly and self.__failedTests: - if module: - failed = [t.split(".", 1)[1] - for t in self.__failedTests] - else: - failed = list(self.__failedTests) - test = testLoader.loadTestsFromNames( - failed, module) - else: - test = testLoader.loadTestsFromName( - testName, module) - except Exception: - exc_type, exc_value, exc_tb = sys.exc_info() - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr( - "<p>Unable to run test <b>{0}</b>.</p>" - "<p>{1}<br/>{2}</p>") - .format(self.testName, str(exc_type), - str(exc_value).replace("\n", "<br/>")) - ) - return - - # now set up the coverage stuff - if self.coverageCheckBox.isChecked(): - if discover: - covname = os.path.join(discoveryStart, "unittest") - elif testFileName: - covname = os.path.splitext( - os.path.abspath(testFileName))[0] - else: - covname = "unittest" - - from DebugClients.Python.coverage import coverage - cover = coverage(data_file="{0}.coverage".format(covname)) - if self.coverageEraseCheckBox.isChecked(): - cover.erase() - else: - cover = None - - self.testResult = QtTestResult( - self, self.failfastCheckBox.isChecked()) - self.totalTests = test.countTestCases() - if self.totalTests == 0: - EricMessageBox.warning( - self, - self.tr("Unittest"), - self.tr("""No unittest were found. Aborting...""")) - else: - self.__failedTests = set() - self.__setRunningMode() - if cover: - cover.start() - test.run(self.testResult) - if cover: - cover.stop() - cover.save() - self.__setStoppedMode() - sys.path = self.savedSysPath - - def __UTPrepared(self, nrTests, 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 nrTests number of tests contained in the test suite (integer) - @param exc_type type of exception occured during preparation (string) - @param exc_value value of exception occured during preparation (string) - """ - if nrTests == 0: - EricMessageBox.critical( - self, - self.tr("Unittest"), - self.tr( - "<p>Unable to run test <b>{0}</b>.</p>" - "<p>{1}<br/>{2}</p>") - .format(self.testName, exc_type, - exc_value.replace("\n", "<br/>")) - ) - return - - self.totalTests = nrTests - self.__setRunningMode() - self.__dbs.remoteUTRun(debug=self.debuggerCheckBox.isChecked(), - failfast=self.failfastCheckBox.isChecked()) - - @pyqtSlot() - def __stopTests(self): - """ - Private slot to stop the test. - """ - if self.__dbs: - self.__dbs.remoteUTStop() - elif self.testResult: - self.testResult.stop() - - def on_errorsListWidget_currentTextChanged(self, text): - """ - Private slot to handle the highlighted signal. - - @param text current text (string) - """ - if text: - for pattern in self.rxPatterns: - text = re.sub(pattern, "", text) - - foundItems = self.testsListWidget.findItems( - text, Qt.MatchFlag.MatchExactly) - if len(foundItems) > 0: - itm = foundItems[0] - self.testsListWidget.setCurrentItem(itm) - self.testsListWidget.scrollToItem(itm) - - def __setRunningMode(self): - """ - Private method to set the GUI in running mode. - """ - self.running = True - self.tabWidget.setCurrentIndex(1) - - # reset counters and error infos - self.runCount = 0 - self.failCount = 0 - self.errorCount = 0 - self.skippedCount = 0 - self.expectedFailureCount = 0 - self.unexpectedSuccessCount = 0 - self.remainingCount = self.totalTests - - # reset the GUI - self.progressCounterRunCount.setText(str(self.runCount)) - self.progressCounterRemCount.setText(str(self.remainingCount)) - self.progressCounterFailureCount.setText(str(self.failCount)) - self.progressCounterErrorCount.setText(str(self.errorCount)) - self.progressCounterSkippedCount.setText(str(self.skippedCount)) - self.progressCounterExpectedFailureCount.setText( - str(self.expectedFailureCount)) - self.progressCounterUnexpectedSuccessCount.setText( - str(self.unexpectedSuccessCount)) - - self.errorsListWidget.clear() - self.testsListWidget.clear() - - self.progressProgressBar.setRange(0, self.totalTests) - self.__setProgressColor("green") - self.progressProgressBar.reset() - - self.stopButton.setEnabled(True) - self.startButton.setEnabled(False) - self.startFailedButton.setEnabled(False) - self.stopButton.setDefault(True) - - self.sbLabel.setText(self.tr("Running")) - self.progressLed.on() - QApplication.processEvents() - - self.startTime = time.time() - - def __setStoppedMode(self): - """ - Private method to set the GUI in stopped mode. - """ - self.stopTime = time.time() - self.timeTaken = float(self.stopTime - self.startTime) - self.running = False - - failedAvailable = bool(self.__failedTests) - self.startButton.setEnabled(True) - self.startFailedButton.setEnabled(failedAvailable) - self.stopButton.setEnabled(False) - if failedAvailable: - self.startFailedButton.setDefault(True) - self.startButton.setDefault(False) - else: - self.startFailedButton.setDefault(False) - self.startButton.setDefault(True) - self.sbLabel.setText( - self.tr("Ran %n test(s) in {0:.3f}s", "", self.runCount) - .format(self.timeTaken)) - self.progressLed.off() - - self.unittestStopped.emit() - - self.raise_() - self.activateWindow() - - def testFailed(self, test, exc, testId): - """ - Public method called if a test fails. - - @param test name of the test (string) - @param exc string representation of the exception (string) - @param testId id of the test (string) - """ - self.failCount += 1 - self.progressCounterFailureCount.setText(str(self.failCount)) - itm = QListWidgetItem(self.tr("Failure: {0}").format(test)) - itm.setData(UnittestDialog.ErrorsInfoRole, (test, exc)) - self.errorsListWidget.insertItem(0, itm) - self.__failedTests.add(testId) - - def testErrored(self, test, exc, testId): - """ - Public method called if a test errors. - - @param test name of the test (string) - @param exc string representation of the exception (string) - @param testId id of the test (string) - """ - self.errorCount += 1 - self.progressCounterErrorCount.setText(str(self.errorCount)) - itm = QListWidgetItem(self.tr("Error: {0}").format(test)) - itm.setData(UnittestDialog.ErrorsInfoRole, (test, exc)) - self.errorsListWidget.insertItem(0, itm) - self.__failedTests.add(testId) - - def testSkipped(self, test, reason, testId): - """ - Public method called if a test was skipped. - - @param test name of the test (string) - @param reason reason for skipping the test (string) - @param testId id of the test (string) - """ - self.skippedCount += 1 - self.progressCounterSkippedCount.setText(str(self.skippedCount)) - itm = QListWidgetItem(self.tr(" Skipped: {0}").format(reason)) - if ericApp().usesDarkPalette(): - itm.setForeground(self.SkippedColorDarkTheme) - else: - itm.setForeground(self.SkippedColorLightTheme) - self.testsListWidget.insertItem(1, itm) - - def testFailedExpected(self, test, exc, testId): - """ - Public method called if a test fails as expected. - - @param test name of the test (string) - @param exc string representation of the exception (string) - @param testId id of the test (string) - """ - self.expectedFailureCount += 1 - self.progressCounterExpectedFailureCount.setText( - str(self.expectedFailureCount)) - itm = QListWidgetItem(self.tr(" Expected Failure")) - if ericApp().usesDarkPalette(): - itm.setForeground(self.FailedExpectedColorDarkTheme) - else: - itm.setForeground(self.FailedExpectedColorLightTheme) - self.testsListWidget.insertItem(1, itm) - - def testSucceededUnexpected(self, test, testId): - """ - Public method called if a test succeeds unexpectedly. - - @param test name of the test (string) - @param testId id of the test (string) - """ - self.unexpectedSuccessCount += 1 - self.progressCounterUnexpectedSuccessCount.setText( - str(self.unexpectedSuccessCount)) - itm = QListWidgetItem(self.tr(" Unexpected Success")) - if ericApp().usesDarkPalette(): - itm.setForeground(self.SucceededUnexpectedColorDarkTheme) - else: - itm.setForeground(self.SucceededUnexpectedColorLightTheme) - self.testsListWidget.insertItem(1, itm) - - def testStarted(self, test, doc): - """ - Public method called if a test is about to be run. - - @param test name of the started test (string) - @param doc documentation of the started test (string) - """ - if doc: - self.testsListWidget.insertItem(0, " {0}".format(doc)) - self.testsListWidget.insertItem(0, test) - if self.__dbs is None: - QApplication.processEvents() - - def testFinished(self): - """ - Public method called if a test has finished. - - <b>Note</b>: It is also called if it has already failed or errored. - """ - # update the counters - self.remainingCount -= 1 - self.runCount += 1 - self.progressCounterRunCount.setText(str(self.runCount)) - self.progressCounterRemCount.setText(str(self.remainingCount)) - - # update the progressbar - if self.errorCount: - self.__setProgressColor("red") - elif self.failCount: - self.__setProgressColor("orange") - self.progressProgressBar.setValue(self.runCount) - - def on_errorsListWidget_itemDoubleClicked(self, lbitem): - """ - Private slot called by doubleclicking an errorlist entry. - - It will popup a dialog showing the stacktrace. - If called from eric, an additional button is displayed - to show the python source in an eric source viewer (in - erics main window. - - @param lbitem the listbox item that was double clicked - """ - self.errListIndex = self.errorsListWidget.row(lbitem) - text = lbitem.text() - self.on_errorsListWidget_currentTextChanged(text) - - # get the error info - test, tracebackText = lbitem.data(UnittestDialog.ErrorsInfoRole) - - # now build the dialog - from .Ui_UnittestStacktraceDialog import Ui_UnittestStacktraceDialog - self.dlg = QDialog(self) - ui = Ui_UnittestStacktraceDialog() - ui.setupUi(self.dlg) - self.dlg.traceback = ui.traceback - - ui.showButton = ui.buttonBox.addButton( - self.tr("Show Source"), QDialogButtonBox.ButtonRole.ActionRole) - ui.showButton.clicked.connect(self.__showSource) - - ui.buttonBox.button( - QDialogButtonBox.StandardButton.Close).setDefault(True) - - self.dlg.setWindowTitle(text) - ui.testLabel.setText(test) - ui.traceback.setPlainText(tracebackText) - - # and now fire it up - self.dlg.show() - self.dlg.exec() - - def __showSource(self): - """ - Private slot to show the source of a traceback in an eric editor. - """ - # get the error info - tracebackLines = self.dlg.traceback.toPlainText().splitlines() - # find the last entry matching the pattern - for index in range(len(tracebackLines) - 1, -1, -1): - fmatch = re.search(r'File "(.*?)", line (\d*?),.*', - tracebackLines[index]) - if fmatch: - break - if fmatch: - fn, ln = fmatch.group(1, 2) - if self.__dbs: - # running as part of eric IDE - self.unittestFile.emit(fn, int(ln), True) - else: - self.__openEditor(fn, int(ln)) - - def hasFailedTests(self): - """ - Public method to check, if there are failed tests from the last run. - - @return flag indicating the presence of failed tests (boolean) - """ - return bool(self.__failedTests) - - def __openEditor(self, filename, linenumber): - """ - Private method to open an editor window for the given file. - - Note: This method opens an editor window when the unittest dialog - is called as a standalone application. - - @param filename path of the file to be opened - @type str - @param linenumber line number to place the cursor at - @type int - """ - from QScintilla.MiniEditor import MiniEditor - editor = MiniEditor(filename, "Python3", self) - editor.gotoLine(linenumber) - editor.show() - - self.__editors.append(editor) - - def closeEvent(self, event): - """ - Protected method to handle the close event. - - @param event close event - @type QCloseEvent - """ - event.accept() - - for editor in self.__editors: - with contextlib.suppress(Exception): - editor.close() - - -class QtTestResult(unittest.TestResult): - """ - A TestResult derivative to work with a graphical GUI. - - For more details see pyunit.py of the standard Python distribution. - """ - def __init__(self, parent, failfast): - """ - Constructor - - @param parent reference to the parent widget - @type UnittestDialog - @param failfast flag indicating to stop at the first error - @type bool - """ - super().__init__() - self.parent = parent - self.failfast = failfast - - def addFailure(self, test, err): - """ - Public method called if a test failed. - - @param test reference to the test object - @param err error traceback - """ - super().addFailure(test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.parent.testFailed(str(test), tracebackLines, test.id()) - - def addError(self, test, err): - """ - Public method called if a test errored. - - @param test reference to the test object - @param err error traceback - """ - super().addError(test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.parent.testErrored(str(test), tracebackLines, test.id()) - - def addSubTest(self, test, subtest, err): - """ - Public method called for each subtest to record its result. - - @param test reference to the test object - @param subtest reference to the subtest object - @param err error traceback - """ - if err is not None: - super().addSubTest(test, subtest, err) - tracebackLines = self._exc_info_to_string(err, test) - if issubclass(err[0], test.failureException): - self.parent.testFailed( - str(subtest), tracebackLines, test.id()) - else: - self.parent.testErrored( - str(subtest), tracebackLines, test.id()) - - def addSkip(self, test, reason): - """ - Public method called if a test was skipped. - - @param test reference to the test object - @param reason reason for skipping the test (string) - """ - super().addSkip(test, reason) - self.parent.testSkipped(str(test), reason, test.id()) - - def addExpectedFailure(self, test, err): - """ - Public method called if a test failed expected. - - @param test reference to the test object - @param err error traceback - """ - super().addExpectedFailure(test, err) - tracebackLines = self._exc_info_to_string(err, test) - self.parent.testFailedExpected(str(test), tracebackLines, test.id()) - - def addUnexpectedSuccess(self, test): - """ - Public method called if a test succeeded expectedly. - - @param test reference to the test object - """ - super().addUnexpectedSuccess(test) - self.parent.testSucceededUnexpected(str(test), test.id()) - - def startTest(self, test): - """ - Public method called at the start of a test. - - @param test Reference to the test object - """ - super().startTest(test) - self.parent.testStarted(str(test), test.shortDescription()) - - def stopTest(self, test): - """ - Public method called at the end of a test. - - @param test Reference to the test object - """ - super().stopTest(test) - self.parent.testFinished() - - -class UnittestWindow(EricMainWindow): - """ - Main window class for the standalone dialog. - """ - def __init__(self, prog=None, parent=None): - """ - Constructor - - @param prog filename of the program to open - @param parent reference to the parent widget (QWidget) - """ - super().__init__(parent) - self.cw = UnittestDialog(prog, parent=self) - self.cw.installEventFilter(self) - size = self.cw.size() - self.setCentralWidget(self.cw) - self.resize(size) - - self.setStyle(Preferences.getUI("Style"), - Preferences.getUI("StyleSheet")) - - self.cw.buttonBox.accepted.connect(self.close) - self.cw.buttonBox.rejected.connect(self.close) - - def eventFilter(self, obj, event): - """ - Public method to filter events. - - @param obj reference to the object the event is meant for (QObject) - @param event reference to the event object (QEvent) - @return flag indicating, whether the event was handled (boolean) - """ - if event.type() == QEvent.Type.Close: - QApplication.exit() - return True - - return False - - -def clearSavedHistories(self): - """ - Function to clear the saved history lists. - """ - Preferences.Prefs.rsettings.setValue( - recentNameTestDiscoverHistory, []) - Preferences.Prefs.rsettings.setValue( - recentNameTestFileHistory, []) - Preferences.Prefs.rsettings.setValue( - recentNameTestNameHistory, []) - - Preferences.Prefs.rsettings.sync()
--- a/eric7/PyUnit/UnittestDialog.ui Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,694 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>UnittestDialog</class> - <widget class="QWidget" name="UnittestDialog"> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>650</width> - <height>700</height> - </rect> - </property> - <property name="windowTitle"> - <string>Unittest</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_5"> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="parametersTab"> - <attribute name="title"> - <string>Parameters</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_6"> - <item> - <widget class="QGroupBox" name="groupBox"> - <property name="title"> - <string>Test Parameters</string> - </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0" colspan="2"> - <layout class="QHBoxLayout" name="horizontalLayout_4"> - <item> - <widget class="QCheckBox" name="discoverCheckBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select to discover tests automatically</string> - </property> - <property name="text"> - <string>&Discover tests (test modules must be importable)</string> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="clearHistoriesButton"> - <property name="toolTip"> - <string>Press to clear the various histories</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Discovery &Start:</string> - </property> - <property name="buddy"> - <cstring>discoveryPicker</cstring> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="EricComboPathPicker" name="discoveryPicker" native="true"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="focusPolicy"> - <enum>Qt::WheelFocus</enum> - </property> - <property name="toolTip"> - <string>Enter name of the directory at which to start the test file discovery</string> - </property> - <property name="whatsThis"> - <string><b>Discovery Start</b> -<p>Enter name of the directory at which to start the test file discovery. -Note that all test modules must be importable from this directory.</p></string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="testsuiteLabel"> - <property name="text"> - <string>Test &Filename:</string> - </property> - <property name="buddy"> - <cstring>testsuitePicker</cstring> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="EricComboPathPicker" name="testsuitePicker" native="true"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="focusPolicy"> - <enum>Qt::WheelFocus</enum> - </property> - <property name="toolTip"> - <string>Enter name of file defining the testsuite</string> - </property> - <property name="whatsThis"> - <string><b>Testsuite</b> -<p>Enter the name of the file defining the testsuite. -It should have a method with a name given below. If no name is given, the suite() method will be tried. If no such method can be -found, the module will be inspected for proper test -cases.</p></string> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>&Test Name:</string> - </property> - <property name="buddy"> - <cstring>testComboBox</cstring> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QComboBox" name="testComboBox"> - <property name="toolTip"> - <string>Enter the test name. Leave empty to use the default name "suite".</string> - </property> - <property name="whatsThis"> - <string><b>Testname</b><p>Enter the name of the test to be performed. This name must follow the rules given by Python's unittest module. If this field is empty, the default name of "suite" will be used.</p></string> - </property> - <property name="editable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="optionsGroup"> - <property name="title"> - <string>Run Parameters</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLabel" name="venvLabel"> - <property name="text"> - <string>&Virtual Environment:</string> - </property> - <property name="buddy"> - <cstring>venvComboBox</cstring> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="venvComboBox"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select the virtual environment to be used</string> - </property> - <property name="whatsThis"> - <string><b>Virtual Environment</b>\n<p>Enter the virtual environment to be used. Leave it empty to use the default environment, i.e. the one configured globally or per project.</p></string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QGridLayout" name="gridLayout_2"> - <item row="0" column="0"> - <widget class="QCheckBox" name="coverageCheckBox"> - <property name="toolTip"> - <string>Select whether coverage data should be collected</string> - </property> - <property name="text"> - <string>C&ollect coverage data</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QCheckBox" name="coverageEraseCheckBox"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="toolTip"> - <string>Select whether old coverage data should be erased</string> - </property> - <property name="text"> - <string>&Erase coverage data</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QCheckBox" name="failfastCheckBox"> - <property name="toolTip"> - <string>Select to stop the test run on the first error or failure</string> - </property> - <property name="text"> - <string>Stop on First Error or Failure</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QCheckBox" name="debuggerCheckBox"> - <property name="toolTip"> - <string>Select to run the unittest with debugger support enabled</string> - </property> - <property name="text"> - <string>Run with Debugger</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="discoveryGroup"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Discovery Results</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> - <item> - <widget class="QTreeWidget" name="discoveryList"> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <property name="headerHidden"> - <bool>true</bool> - </property> - <property name="expandsOnDoubleClick"> - <bool>false</bool> - </property> - <column> - <property name="text"> - <string notr="true">1</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="resultsTab"> - <attribute name="title"> - <string>Results</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_4"> - <item> - <widget class="QGroupBox" name="progressGroupBox"> - <property name="title"> - <string>Progress</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <layout class="QHBoxLayout" name="_8"> - <item> - <widget class="QLabel" name="progressTextLabel"> - <property name="text"> - <string>Progress:</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>371</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="EricLed" name="progressLed"/> - </item> - </layout> - </item> - <item> - <widget class="QProgressBar" name="progressProgressBar"> - <property name="value"> - <number>0</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="format"> - <string>%v/%m Tests</string> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <widget class="QLabel" name="progressCounterRunLabel"> - <property name="text"> - <string>Run:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterRunCount"> - <property name="toolTip"> - <string>Number of tests run</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterRemLabel"> - <property name="text"> - <string>Remaining:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterRemCount"> - <property name="toolTip"> - <string>Number of tests to be run</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="progressCounterFailureLabel"> - <property name="text"> - <string>Failures:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterFailureCount"> - <property name="toolTip"> - <string>Number of test failures</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterErrorLabel"> - <property name="text"> - <string>Errors:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterErrorCount"> - <property name="toolTip"> - <string>Number of test errors</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterSkippedLabel"> - <property name="text"> - <string>Skipped:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterSkippedCount"> - <property name="toolTip"> - <string>Number of tests skipped</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterExpectedFailureLabel"> - <property name="text"> - <string>Expected Failures:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterExpectedFailureCount"> - <property name="toolTip"> - <string>Number of tests with expected failure</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterUnexpectedSuccessLabel"> - <property name="text"> - <string>Unexpected Successes:</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="progressCounterUnexpectedSuccessCount"> - <property name="toolTip"> - <string>Number of tests with unexpected success</string> - </property> - <property name="text"> - <string notr="true">0</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QLabel" name="textLabel1"> - <property name="text"> - <string>Tests performed:</string> - </property> - </widget> - </item> - <item> - <widget class="QListWidget" name="testsListWidget"/> - </item> - <item> - <widget class="QLabel" name="listboxLabel"> - <property name="text"> - <string>Failures and errors:</string> - </property> - </widget> - </item> - <item> - <widget class="QListWidget" name="errorsListWidget"> - <property name="toolTip"> - <string>Failures and Errors list</string> - </property> - <property name="whatsThis"> - <string><b>Failures and Errors list</b> -<p>This list shows all failed and errored tests. -Double clicking on an entry will show the respective traceback.</p></string> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Close</set> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="_3"> - <item> - <widget class="QLabel" name="sbLabel"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Idle</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - <customwidgets> - <customwidget> - <class>EricComboPathPicker</class> - <extends>QWidget</extends> - <header>EricWidgets/EricPathPicker.h</header> - <container>1</container> - </customwidget> - <customwidget> - <class>EricLed</class> - <extends>QFrame</extends> - <header>EricWidgets/EricLed.h</header> - <container>1</container> - </customwidget> - </customwidgets> - <tabstops> - <tabstop>tabWidget</tabstop> - <tabstop>discoverCheckBox</tabstop> - <tabstop>clearHistoriesButton</tabstop> - <tabstop>discoveryPicker</tabstop> - <tabstop>testsuitePicker</tabstop> - <tabstop>testComboBox</tabstop> - <tabstop>venvComboBox</tabstop> - <tabstop>coverageCheckBox</tabstop> - <tabstop>coverageEraseCheckBox</tabstop> - <tabstop>failfastCheckBox</tabstop> - <tabstop>debuggerCheckBox</tabstop> - <tabstop>discoveryList</tabstop> - <tabstop>testsListWidget</tabstop> - <tabstop>errorsListWidget</tabstop> - </tabstops> - <resources/> - <connections> - <connection> - <sender>coverageCheckBox</sender> - <signal>toggled(bool)</signal> - <receiver>coverageEraseCheckBox</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>321</x> - <y>294</y> - </hint> - <hint type="destinationlabel"> - <x>616</x> - <y>294</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>UnittestDialog</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>67</x> - <y>662</y> - </hint> - <hint type="destinationlabel"> - <x>72</x> - <y>667</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>UnittestDialog</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>157</x> - <y>662</y> - </hint> - <hint type="destinationlabel"> - <x>148</x> - <y>668</y> - </hint> - </hints> - </connection> - <connection> - <sender>discoverCheckBox</sender> - <signal>toggled(bool)</signal> - <receiver>discoveryPicker</receiver> - <slot>setEnabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>209</x> - <y>93</y> - </hint> - <hint type="destinationlabel"> - <x>209</x> - <y>120</y> - </hint> - </hints> - </connection> - <connection> - <sender>discoverCheckBox</sender> - <signal>toggled(bool)</signal> - <receiver>testsuitePicker</receiver> - <slot>setDisabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>96</x> - <y>93</y> - </hint> - <hint type="destinationlabel"> - <x>150</x> - <y>143</y> - </hint> - </hints> - </connection> - <connection> - <sender>discoverCheckBox</sender> - <signal>toggled(bool)</signal> - <receiver>testComboBox</receiver> - <slot>setDisabled(bool)</slot> - <hints> - <hint type="sourcelabel"> - <x>321</x> - <y>97</y> - </hint> - <hint type="destinationlabel"> - <x>327</x> - <y>166</y> - </hint> - </hints> - </connection> - </connections> -</ui>
--- a/eric7/PyUnit/UnittestStacktraceDialog.ui Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -<ui version="4.0" > - <class>UnittestStacktraceDialog</class> - <widget class="QDialog" name="UnittestStacktraceDialog" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>600</width> - <height>250</height> - </rect> - </property> - <layout class="QVBoxLayout" > - <item> - <widget class="QLabel" name="testLabel" /> - </item> - <item> - <widget class="QTextEdit" name="traceback" > - <property name="readOnly" > - <bool>true</bool> - </property> - <property name="acceptRichText" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons" > - <set>QDialogButtonBox::Close</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>buttonBox</sender> - <signal>accepted()</signal> - <receiver>UnittestStacktraceDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel" > - <x>33</x> - <y>235</y> - </hint> - <hint type="destinationlabel" > - <x>33</x> - <y>249</y> - </hint> - </hints> - </connection> - <connection> - <sender>buttonBox</sender> - <signal>rejected()</signal> - <receiver>UnittestStacktraceDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel" > - <x>94</x> - <y>226</y> - </hint> - <hint type="destinationlabel" > - <x>95</x> - <y>249</y> - </hint> - </hints> - </connection> - </connections> -</ui>
--- a/eric7/PyUnit/__init__.py Wed May 18 09:19:09 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Package implementing an interface to the pyunit unittest package. - -The package consist of a single dialog, which may be called as a -standalone version using the eric7_unittest script or from within the eric -IDE. If it is called from within eric, it has the additional function to -open a source file that failed a test. -"""
--- a/eric7/Testing/Interfaces/__init__.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Testing/Interfaces/__init__.py Wed May 18 10:54:32 2022 +0200 @@ -15,7 +15,13 @@ PytestExecutor, ) -FrameworkNames = ( - UnittestExecutor.name, - PytestExecutor.name, -) +FrameworkNames = { + "MicroPython": ( + UnittestExecutor.name, + PytestExecutor.name, + ), + "Python3": ( + UnittestExecutor.name, + PytestExecutor.name, + ), +}
--- a/eric7/Testing/__init__.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/Testing/__init__.py Wed May 18 10:54:32 2022 +0200 @@ -7,3 +7,28 @@ Package implementing testing functionality and interface to various test frameworks. """ + +from .Interfaces import FrameworkNames + + +def supportedLanguages(): + """ + Function to get a list of supported programming languages. + + @return list of supported programming languages + @rtype list of str + """ + return list(FrameworkNames.keys()) + + +def isLanguageSupported(language): + """ + Function to check, if the given programming language is supported by any + testing framework. + + @param language programming language + @type str + @return flag indicating support + @rtype bool + """ + return language in FrameworkNames.keys()
--- a/eric7/UI/UserInterface.py Wed May 18 09:19:09 2022 +0200 +++ b/eric7/UI/UserInterface.py Wed May 18 10:54:32 2022 +0200 @@ -6835,7 +6835,7 @@ if testing: # clear the unit test histories if self.__testingWidget is None: - from Testing.UnittestWidget import clearSavedHistories + from Testing.TestingWidget import clearSavedHistories clearSavedHistories() else: self.__testingWidget.clearRecent() @@ -6858,12 +6858,12 @@ """ Private slot to handle the projectOpened signal. """ - from Debugger.DebugClientCapabilities import HasUnittest + import Testing self.__setWindowCaption(project=self.project.name) - cap = self.__debugServer.getClientCapabilities( + supported = Testing.isLanguageSupported( self.project.getProjectLanguage()) - self.testProjectAct.setEnabled(cap & HasUnittest) - self.__testingProjectOpen = cap & HasUnittest + self.testProjectAct.setEnabled(supported) + self.__testingProjectOpen = supported def __projectClosed(self): """ @@ -6912,17 +6912,10 @@ len(self.__menus["wizards"].actions()) > 0) if fn and str(fn) != "None": - dbs = self.__debugServer - for language in dbs.getSupportedLanguages(): - exts = dbs.getExtensions(language) - if fn.endswith(exts): - from Debugger.DebugClientCapabilities import HasUnittest - cap = dbs.getClientCapabilities(language) - self.testScriptAct.setEnabled(cap & HasUnittest) - self.__testingEditorOpen = cap & HasUnittest - return - - if self.viewmanager.getOpenEditor(fn).isPyFile(): + import Testing + if Testing.isLanguageSupported( + self.viewmanager.getOpenEditor(fn).getFileType() + ): self.testScriptAct.setEnabled(True) self.__testingEditorOpen = True @@ -6935,17 +6928,8 @@ fn = editor.getFileName() if editor else None if fn: - dbs = self.__debugServer - for language in dbs.getSupportedLanguages(): - exts = dbs.getExtensions(language) - if fn.endswith(exts): - from Debugger.DebugClientCapabilities import HasUnittest - cap = dbs.getClientCapabilities(language) - self.testScriptAct.setEnabled(cap & HasUnittest) - self.__testingEditorOpen = cap & HasUnittest - return - - if editor.isPyFile(): + import Testing + if Testing.isLanguageSupported(editor.getFileType()): self.testScriptAct.setEnabled(True) self.__testingEditorOpen = True return