Merged with branch 'eric7' in order to prepare a new release. eric7-maintenance release-22.06

Wed, 01 Jun 2022 13:48:49 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 01 Jun 2022 13:48:49 +0200
branch
eric7-maintenance
changeset 9111
4ac66b6c33a4
parent 9049
2b9bd8f97576
child 9112
9967ae9f0906

Merged with branch 'eric7' in order to prepare a new release.

Dictionaries/words.dic file | annotate | diff | comparison | revisions
docs/changelog file | annotate | diff | comparison | revisions
eric7.epj file | annotate | diff | comparison | revisions
eric7/APIs/Python3/eric7.api file | annotate | diff | comparison | revisions
eric7/APIs/Python3/eric7.bas file | annotate | diff | comparison | revisions
eric7/CondaInterface/Conda.py file | annotate | diff | comparison | revisions
eric7/DataViews/PyCoverageDialog.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/DebugClientBase.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/DebugClientCapabilities.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/cmdline.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/collector.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/config.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/control.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/debug.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/doc/CHANGES.rst file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/doc/CONTRIBUTORS.txt file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/doc/README.rst file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/html.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/htmlfiles/coverage_html.js file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/htmlfiles/index.html file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/htmlfiles/pyfile.html file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/htmlfiles/style.css file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/htmlfiles/style.scss file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/inorout.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/jsonreport.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/misc.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/parser.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/phystokens.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/python.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/results.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/sqldata.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/summary.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/tomlconfig.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/version.py file | annotate | diff | comparison | revisions
eric7/DebugClients/Python/coverage/xmlreport.py file | annotate | diff | comparison | revisions
eric7/Debugger/DebugClientCapabilities.py file | annotate | diff | comparison | revisions
eric7/Debugger/DebugServer.py file | annotate | diff | comparison | revisions
eric7/Debugger/DebuggerInterfaceNone.py file | annotate | diff | comparison | revisions
eric7/Debugger/DebuggerInterfacePython.py file | annotate | diff | comparison | revisions
eric7/Debugger/StartDialog.py file | annotate | diff | comparison | revisions
eric7/Documentation/Help/source.qch file | annotate | diff | comparison | revisions
eric7/Documentation/Help/source.qhp file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.DataViews.PyCoverageDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.DebugClients.Python.DebugClientBase.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.DebugClients.Python.DebugClientCapabilities.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Debugger.DebugClientCapabilities.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Debugger.DebugServer.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Debugger.DebuggerInterfaceNone.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Debugger.DebuggerInterfacePython.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.EricNetwork.EricJsonClient.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.EricNetwork.EricJsonServer.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.EricWidgets.EricPlainTextDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Globals.__init__.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.PipInterface.PipLicensesDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Project.Project.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Project.PropertiesDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.QScintilla.Editor.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Tools.TrayStarter.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.UI.Browser.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.UI.ClearPrivateDataDialog.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.UI.UserInterface.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/eric7.Utilities.__init__.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/index-eric7.DataViews.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/index-eric7.DebugClients.Python.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/index-eric7.EricNetwork.html file | annotate | diff | comparison | revisions
eric7/Documentation/Source/index-eric7.html file | annotate | diff | comparison | revisions
eric7/EricNetwork/EricJsonClient.py file | annotate | diff | comparison | revisions
eric7/EricNetwork/EricJsonServer.py file | annotate | diff | comparison | revisions
eric7/EricWidgets/EricPlainTextDialog.py file | annotate | diff | comparison | revisions
eric7/EricWidgets/EricPlainTextDialog.ui file | annotate | diff | comparison | revisions
eric7/Globals/__init__.py file | annotate | diff | comparison | revisions
eric7/JediInterface/JediServer.py file | annotate | diff | comparison | revisions
eric7/MicroPython/MicroPythonDevices.py file | annotate | diff | comparison | revisions
eric7/MicroPython/UF2FlashDialog.py file | annotate | diff | comparison | revisions
eric7/PipInterface/Pip.py file | annotate | diff | comparison | revisions
eric7/PipInterface/PipLicensesDialog.py file | annotate | diff | comparison | revisions
eric7/PipInterface/PipLicensesDialog.ui file | annotate | diff | comparison | revisions
eric7/PipInterface/PipPackagesWidget.py file | annotate | diff | comparison | revisions
eric7/PipInterface/PipVulnerabilityChecker.py file | annotate | diff | comparison | revisions
eric7/PipInterface/piplicenses.py file | annotate | diff | comparison | revisions
eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py file | annotate | diff | comparison | revisions
eric7/Plugins/PluginVcsMercurial.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.ui file | annotate | diff | comparison | revisions
eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py file | annotate | diff | comparison | revisions
eric7/Plugins/WizardPlugins/EricMessageBoxWizard/EricMessageBoxWizardDialog.ui file | annotate | diff | comparison | revisions
eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.py file | annotate | diff | comparison | revisions
eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.ui file | annotate | diff | comparison | revisions
eric7/Plugins/WizardPlugins/MessageBoxWizard/MessageBoxWizardDialog.ui file | annotate | diff | comparison | revisions
eric7/Project/CreateDialogCodeDialog.py file | annotate | diff | comparison | revisions
eric7/Project/Project.py file | annotate | diff | comparison | revisions
eric7/Project/ProjectSourcesBrowser.py file | annotate | diff | comparison | revisions
eric7/Project/PropertiesDialog.py file | annotate | diff | comparison | revisions
eric7/Project/PropertiesDialog.ui file | annotate | diff | comparison | revisions
eric7/QScintilla/Editor.py file | annotate | diff | comparison | revisions
eric7/Themes/dark_blue.ethj file | annotate | diff | comparison | revisions
eric7/Themes/dark_blue_with_stylesheet.ethj file | annotate | diff | comparison | revisions
eric7/Themes/dark_green.ethj file | annotate | diff | comparison | revisions
eric7/Themes/dark_green_with_stylesheet.ethj file | annotate | diff | comparison | revisions
eric7/Tools/TrayStarter.py file | annotate | diff | comparison | revisions
eric7/UI/Browser.py file | annotate | diff | comparison | revisions
eric7/UI/ClearPrivateDataDialog.py file | annotate | diff | comparison | revisions
eric7/UI/ClearPrivateDataDialog.ui file | annotate | diff | comparison | revisions
eric7/UI/UserInterface.py file | annotate | diff | comparison | revisions
eric7/Utilities/__init__.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/WebBrowserPage.py file | annotate | diff | comparison | revisions
eric7/i18n/eric7_cs.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_de.qm file | annotate | diff | comparison | revisions
eric7/i18n/eric7_de.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_empty.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_en.qm file | annotate | diff | comparison | revisions
eric7/i18n/eric7_en.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_es.qm file | annotate | diff | comparison | revisions
eric7/i18n/eric7_es.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_fr.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_it.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_pt.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_ru.qm file | annotate | diff | comparison | revisions
eric7/i18n/eric7_ru.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_tr.ts file | annotate | diff | comparison | revisions
eric7/i18n/eric7_zh_CN.ts file | annotate | diff | comparison | revisions
scripts/install-dependencies.py file | annotate | diff | comparison | revisions
scripts/install.py file | annotate | diff | comparison | revisions
scripts/uninstall.py file | annotate | diff | comparison | revisions
setup.py file | annotate | diff | comparison | revisions
--- a/Dictionaries/words.dic	Mon May 02 15:53:05 2022 +0200
+++ b/Dictionaries/words.dic	Wed Jun 01 13:48:49 2022 +0200
@@ -1,4 +1,4 @@
-Eric6
+Eric7
 IDE
 detlev
 offenbachs
--- a/docs/changelog	Mon May 02 15:53:05 2022 +0200
+++ b/docs/changelog	Wed Jun 01 13:48:49 2022 +0200
@@ -1,5 +1,33 @@
 Change Log
 ----------
+Version 22.6:
+- bug fixes
+- Dataview Coverage
+  -- added support to write coverage reports as HTML, JSON or LCOV files
+  -- removed the support for writing annotated sources
+     (deprecated in coverage.py)
+- Mercurial Interface
+  -- added configuration option to override the automatic search for the hg
+     executable
+- MicroPython
+  -- updated the list of known CircuitPython boards
+  -- updated the list of known UF2 capable boards
+- pip Interface
+  -- added a filter to the package licenses dialog
+- Syntax Checker
+  -- changed the TOML syntax checker to use 'tomlkit' because 'toml' is no
+     longer maintained
+- Testing
+  -- reworked the former unittest interface to allow to support testing
+     frameworks other than "unittest"
+  -- implemented support for the "unittest" and "pytest" frameworks
+- Wizards
+  -- extended the QInputDialog wizard to support the 'getMultiLineText()'
+     function
+- Third Party packages
+  -- upgraded pip-licenses to version 3.5.4
+  -- upgraded coverage to 6.4.0
+
 Version 22.5:
 - bug fixes
 - General
@@ -123,7 +151,3 @@
   -- upgraded pycodestyle to version 2.8.0
   -- upgraded mccabe to version 0.6.1
   -- upgraded pyflakes to version 2.4.0
-
-Version 21.11:
-- bug fixes
-- last formal eric6 release
--- a/eric7.epj	Mon May 02 15:53:05 2022 +0200
+++ b/eric7.epj	Wed Jun 01 13:48:49 2022 +0200
@@ -277,6 +277,8 @@
       "eric7/Cooperation/ChatWidget.ui",
       "eric7/DataViews/CodeMetricsDialog.ui",
       "eric7/DataViews/PyCoverageDialog.ui",
+      "eric7/DataViews/PyCoverageHtmlReportDialog.ui",
+      "eric7/DataViews/PyCoverageJsonReportDialog.ui",
       "eric7/DataViews/PyProfileDialog.ui",
       "eric7/Debugger/CallTraceViewer.ui",
       "eric7/Debugger/EditBreakpointDialog.ui",
@@ -623,8 +625,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",
@@ -643,6 +643,7 @@
       "eric7/Tasks/TaskPropertiesDialog.ui",
       "eric7/Templates/TemplatePropertiesDialog.ui",
       "eric7/Templates/TemplateSingleVariableDialog.ui",
+      "eric7/Testing/TestingWidget.ui",
       "eric7/UI/AuthenticationDialog.ui",
       "eric7/UI/ClearPrivateDataDialog.ui",
       "eric7/UI/CompareDialog.ui",
@@ -989,11 +990,12 @@
       "eric7/DataViews/CodeMetrics.py",
       "eric7/DataViews/CodeMetricsDialog.py",
       "eric7/DataViews/PyCoverageDialog.py",
+      "eric7/DataViews/PyCoverageHtmlReportDialog.py",
+      "eric7/DataViews/PyCoverageJsonReportDialog.py",
       "eric7/DataViews/PyProfileDialog.py",
       "eric7/DataViews/__init__.py",
       "eric7/DebugClients/Python/AsyncFile.py",
       "eric7/DebugClients/Python/BreakpointWatch.py",
-      "eric7/DebugClients/Python/DCTestResult.py",
       "eric7/DebugClients/Python/DebugBase.py",
       "eric7/DebugClients/Python/DebugClient.py",
       "eric7/DebugClients/Python/DebugClientBase.py",
@@ -1094,6 +1096,8 @@
       "eric7/EricNetwork/EricGoogleMailHelpers.py",
       "eric7/EricNetwork/EricJsonClient.py",
       "eric7/EricNetwork/EricJsonServer.py",
+      "eric7/EricNetwork/EricJsonStreamReader.py",
+      "eric7/EricNetwork/EricJsonStreamWriter.py",
       "eric7/EricNetwork/EricNetworkIcon.py",
       "eric7/EricNetwork/EricNetworkProxyFactory.py",
       "eric7/EricNetwork/EricSslCertificateSelectionDialog.py",
@@ -1816,8 +1820,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",
@@ -1937,6 +1939,16 @@
       "eric7/Templates/TemplateViewer.py",
       "eric7/Templates/TemplatesFile.py",
       "eric7/Templates/__init__.py",
+      "eric7/Testing/Interfaces/PytestExecutor.py",
+      "eric7/Testing/Interfaces/PytestRunner.py",
+      "eric7/Testing/Interfaces/TestExecutorBase.py",
+      "eric7/Testing/Interfaces/TestFrameworkRegistry.py",
+      "eric7/Testing/Interfaces/UnittestExecutor.py",
+      "eric7/Testing/Interfaces/UnittestRunner.py",
+      "eric7/Testing/Interfaces/__init__.py",
+      "eric7/Testing/TestResultsTree.py",
+      "eric7/Testing/TestingWidget.py",
+      "eric7/Testing/__init__.py",
       "eric7/ThirdParty/Jasy/__init__.py",
       "eric7/ThirdParty/Jasy/jasy/__init__.py",
       "eric7/ThirdParty/Jasy/jasy/core/Console.py",
@@ -2307,14 +2319,14 @@
       "eric7/eric7_snap.pyw",
       "eric7/eric7_sqlbrowser.py",
       "eric7/eric7_sqlbrowser.pyw",
+      "eric7/eric7_testing.py",
+      "eric7/eric7_testing.pyw",
       "eric7/eric7_tray.py",
       "eric7/eric7_tray.pyw",
       "eric7/eric7_trpreviewer.py",
       "eric7/eric7_trpreviewer.pyw",
       "eric7/eric7_uipreviewer.py",
       "eric7/eric7_uipreviewer.pyw",
-      "eric7/eric7_unittest.py",
-      "eric7/eric7_unittest.pyw",
       "eric7/eric7_virtualenv.py",
       "eric7/eric7_virtualenv.pyw",
       "eric7/eric7config.py",
--- a/eric7/APIs/Python3/eric7.api	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/APIs/Python3/eric7.api	Wed Jun 01 13:48:49 2022 +0200
@@ -192,9 +192,16 @@
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog.on_buttonBox_clicked?4(button)
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog.on_reloadButton_clicked?4()
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog.on_resultList_itemActivated?4(item, column)
+eric7.DataViews.PyCoverageDialog.PyCoverageDialog.openFile?7
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog.start?4(cfn, fn)
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog.stringify?4()
 eric7.DataViews.PyCoverageDialog.PyCoverageDialog?1(parent=None)
+eric7.DataViews.PyCoverageHtmlReportDialog.PyCoverageHtmlReportDialog.getData?4()
+eric7.DataViews.PyCoverageHtmlReportDialog.PyCoverageHtmlReportDialog.on_outputDirectoryPicker_textChanged?4(directory)
+eric7.DataViews.PyCoverageHtmlReportDialog.PyCoverageHtmlReportDialog?1(defaultDirectory, parent=None)
+eric7.DataViews.PyCoverageJsonReportDialog.PyCoverageJsonReportDialog.getData?4()
+eric7.DataViews.PyCoverageJsonReportDialog.PyCoverageJsonReportDialog.on_outputFilePicker_textChanged?4(filename)
+eric7.DataViews.PyCoverageJsonReportDialog.PyCoverageJsonReportDialog?1(defaultDirectory, parent=None)
 eric7.DataViews.PyProfileDialog.PyProfileDialog.on_buttonBox_clicked?4(button)
 eric7.DataViews.PyProfileDialog.PyProfileDialog.start?4(pfn, fn=None)
 eric7.DataViews.PyProfileDialog.PyProfileDialog?1(parent=None)
@@ -243,15 +250,6 @@
 eric7.DebugClients.Python.BreakpointWatch.Watch.get_watch?4()
 eric7.DebugClients.Python.BreakpointWatch.Watch.watches?7
 eric7.DebugClients.Python.BreakpointWatch.Watch?1(cond, compiledCond, flag, temporary=False)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addError?4(test, err)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addExpectedFailure?4(test, err)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addFailure?4(test, err)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addSkip?4(test, reason)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addSubTest?4(test, subtest, err)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.addUnexpectedSuccess?4(test)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.startTest?4(test)
-eric7.DebugClients.Python.DCTestResult.DCTestResult.stopTest?4(test)
-eric7.DebugClients.Python.DCTestResult.DCTestResult?1(dbgClient, failfast)
 eric7.DebugClients.Python.DebugBase.DebugBase._fnCache?8
 eric7.DebugClients.Python.DebugBase.DebugBase._set_stopinfo?5(stopframe, returnframe, stoplineno=0)
 eric7.DebugClients.Python.DebugBase.DebugBase.bootstrap?4(target, args, kwargs)
@@ -332,7 +330,6 @@
 eric7.DebugClients.Python.DebugClientCapabilities.HasInterpreter?7
 eric7.DebugClients.Python.DebugClientCapabilities.HasProfiler?7
 eric7.DebugClients.Python.DebugClientCapabilities.HasShell?7
-eric7.DebugClients.Python.DebugClientCapabilities.HasUnittest?7
 eric7.DebugClients.Python.DebugConfig.BatchSize?7
 eric7.DebugClients.Python.DebugConfig.ConfigKnownQtTypes?7
 eric7.DebugClients.Python.DebugConfig.ConfigQtNames?7
@@ -535,7 +532,6 @@
 eric7.Debugger.DebugClientCapabilities.HasInterpreter?7
 eric7.Debugger.DebugClientCapabilities.HasProfiler?7
 eric7.Debugger.DebugClientCapabilities.HasShell?7
-eric7.Debugger.DebugClientCapabilities.HasUnittest?7
 eric7.Debugger.DebugServer.DebugServer.appendStdout?7
 eric7.Debugger.DebugServer.DebugServer.callTraceInfo?7
 eric7.Debugger.DebugServer.DebugServer.clientBanner?7
@@ -563,16 +559,6 @@
 eric7.Debugger.DebugServer.DebugServer.clientSyntaxError?7
 eric7.Debugger.DebugServer.DebugServer.clientThreadList?7
 eric7.Debugger.DebugServer.DebugServer.clientThreadSet?7
-eric7.Debugger.DebugServer.DebugServer.clientUtDiscovered?4(testCases, exceptionType, exceptionValue)
-eric7.Debugger.DebugServer.DebugServer.clientUtFinished?4(status)
-eric7.Debugger.DebugServer.DebugServer.clientUtPrepared?4(result, exceptionType, exceptionValue)
-eric7.Debugger.DebugServer.DebugServer.clientUtStartTest?4(testname, doc)
-eric7.Debugger.DebugServer.DebugServer.clientUtStopTest?4()
-eric7.Debugger.DebugServer.DebugServer.clientUtTestErrored?4(testname, traceback, testId)
-eric7.Debugger.DebugServer.DebugServer.clientUtTestFailed?4(testname, traceback, testId)
-eric7.Debugger.DebugServer.DebugServer.clientUtTestFailedExpected?4(testname, traceback, testId)
-eric7.Debugger.DebugServer.DebugServer.clientUtTestSkipped?4(testname, reason, testId)
-eric7.Debugger.DebugServer.DebugServer.clientUtTestSucceededUnexpected?4(testname, testId)
 eric7.Debugger.DebugServer.DebugServer.clientVariable?7
 eric7.Debugger.DebugServer.DebugServer.clientVariables?7
 eric7.Debugger.DebugServer.DebugServer.clientWatchConditionError?7
@@ -621,10 +607,6 @@
 eric7.Debugger.DebugServer.DebugServer.remoteStepOver?4(debuggerId)
 eric7.Debugger.DebugServer.DebugServer.remoteStepQuit?4(debuggerId)
 eric7.Debugger.DebugServer.DebugServer.remoteThreadList?4(debuggerId)
-eric7.Debugger.DebugServer.DebugServer.remoteUTDiscover?4(clientType, forProject, venvName, syspath, workdir, discoveryStart)
-eric7.Debugger.DebugServer.DebugServer.remoteUTPrepare?4(fn, tn, tfn, failed, cov, covname, coverase, clientType="", forProject=False, venvName="", syspath=None, workdir="", discover=False, discoveryStart="", testCases=None, debug=False)
-eric7.Debugger.DebugServer.DebugServer.remoteUTRun?4(debug=False, failfast=False)
-eric7.Debugger.DebugServer.DebugServer.remoteUTStop?4()
 eric7.Debugger.DebugServer.DebugServer.setCallTraceEnabled?4(debuggerId, on)
 eric7.Debugger.DebugServer.DebugServer.setDebugging?4(on)
 eric7.Debugger.DebugServer.DebugServer.shutdownServer?4()
@@ -656,16 +638,6 @@
 eric7.Debugger.DebugServer.DebugServer.signalMainClientExit?4()
 eric7.Debugger.DebugServer.DebugServer.startClient?4(unplanned=True, clType=None, forProject=False, runInConsole=False, venvName="", workingDir=None, configOverride=None)
 eric7.Debugger.DebugServer.DebugServer.unregisterDebuggerInterface?4(interfaceName)
-eric7.Debugger.DebugServer.DebugServer.utDiscovered?7
-eric7.Debugger.DebugServer.DebugServer.utFinished?7
-eric7.Debugger.DebugServer.DebugServer.utPrepared?7
-eric7.Debugger.DebugServer.DebugServer.utStartTest?7
-eric7.Debugger.DebugServer.DebugServer.utStopTest?7
-eric7.Debugger.DebugServer.DebugServer.utTestErrored?7
-eric7.Debugger.DebugServer.DebugServer.utTestFailed?7
-eric7.Debugger.DebugServer.DebugServer.utTestFailedExpected?7
-eric7.Debugger.DebugServer.DebugServer.utTestSkipped?7
-eric7.Debugger.DebugServer.DebugServer.utTestSucceededUnexpected?7
 eric7.Debugger.DebugServer.DebugServer?1(originalPathString, preventPassiveDebugging=False, project=None, parent=None)
 eric7.Debugger.DebugServer.DebuggerInterfaces?7
 eric7.Debugger.DebugUI.DebugUI.appendStdout?7
@@ -766,10 +738,6 @@
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteStepOver?4(debuggerId)
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteStepQuit?4(debuggerId)
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteThreadList?4(debuggerId)
-eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteUTDiscover?4(syspath, workdir, discoveryStart)
-eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteUTPrepare?4(fn, tn, tfn, failed, cov, covname, coverase, syspath, workdir, discover, discoveryStart, testCases, debug)
-eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteUTRun?4(debug, failfast)
-eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteUTStop?4()
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteWatchpoint?4(debuggerId, cond, setWatch, temp=False)
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteWatchpointEnable?4(debuggerId, cond, enable)
 eric7.Debugger.DebuggerInterfaceNone.DebuggerInterfaceNone.remoteWatchpointIgnore?4(debuggerId, cond, count)
@@ -813,10 +781,6 @@
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteStepOver?4(debuggerId)
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteStepQuit?4(debuggerId)
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteThreadList?4(debuggerId)
-eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteUTDiscover?4(syspath, workdir, discoveryStart)
-eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteUTPrepare?4(fn, tn, tfn, failed, cov, covname, coverase, syspath, workdir, discover, discoveryStart, testCases, debug)
-eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteUTRun?4(debug, failfast)
-eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteUTStop?4()
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteWatchpoint?4(debuggerId, cond, setWatch, temp=False)
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteWatchpointEnable?4(debuggerId, cond, enable)
 eric7.Debugger.DebuggerInterfacePython.DebuggerInterfacePython.remoteWatchpointIgnore?4(debuggerId, cond, count)
@@ -1081,6 +1045,14 @@
 eric7.EricNetwork.EricJsonServer.EricJsonServer.stopAllClients?4()
 eric7.EricNetwork.EricJsonServer.EricJsonServer.stopClient?4(idString="")
 eric7.EricNetwork.EricJsonServer.EricJsonServer?1(name="", multiplex=False, parent=None)
+eric7.EricNetwork.EricJsonStreamReader.EricJsonReader.address?4()
+eric7.EricNetwork.EricJsonStreamReader.EricJsonReader.dataReceived?7
+eric7.EricNetwork.EricJsonStreamReader.EricJsonReader.handleNewConnection?4()
+eric7.EricNetwork.EricJsonStreamReader.EricJsonReader.port?4()
+eric7.EricNetwork.EricJsonStreamReader.EricJsonReader?1(name="", ip=None, parent=None)
+eric7.EricNetwork.EricJsonStreamWriter.EricJsonWriter.close?4()
+eric7.EricNetwork.EricJsonStreamWriter.EricJsonWriter.write?4(data)
+eric7.EricNetwork.EricJsonStreamWriter.EricJsonWriter?1(host, port)
 eric7.EricNetwork.EricNetworkIcon.EricNetworkIcon.isOnline?4()
 eric7.EricNetwork.EricNetworkIcon.EricNetworkIcon.onlineStateChanged?7
 eric7.EricNetwork.EricNetworkIcon.EricNetworkIcon.reachabilityStateChanged?7
@@ -1560,7 +1532,8 @@
 eric7.EricWidgets.EricPathPickerDialog.EricPathPickerDialog?1(parent=None)
 eric7.EricWidgets.EricPathPickerDialog.getPath?4(parent, title, label, mode=EricPathPickerModes.OPEN_FILE_MODE, path="", defaultDirectory="", filters=None)
 eric7.EricWidgets.EricPlainTextDialog.EricPlainTextDialog.on_copyButton_clicked?4()
-eric7.EricWidgets.EricPlainTextDialog.EricPlainTextDialog?1(title="", text="", parent=None)
+eric7.EricWidgets.EricPlainTextDialog.EricPlainTextDialog.toPlainText?4()
+eric7.EricWidgets.EricPlainTextDialog.EricPlainTextDialog?1(title="", text="", readOnly=True, parent=None)
 eric7.EricWidgets.EricProcessDialog.EricProcessDialog.keyPressEvent?4(evt)
 eric7.EricWidgets.EricProcessDialog.EricProcessDialog.normalExit?4()
 eric7.EricWidgets.EricProcessDialog.EricProcessDialog.normalExitWithoutErrors?4()
@@ -1916,9 +1889,11 @@
 eric7.Globals.recentNameHosts?7
 eric7.Globals.recentNameMultiProject?7
 eric7.Globals.recentNameProject?7
-eric7.Globals.recentNameUnittestDiscoverHistory?7
-eric7.Globals.recentNameUnittestFileHistory?7
-eric7.Globals.recentNameUnittestTestnameHistory?7
+eric7.Globals.recentNameTestDiscoverHistory?7
+eric7.Globals.recentNameTestEnvironment?7
+eric7.Globals.recentNameTestFileHistory?7
+eric7.Globals.recentNameTestFramework?7
+eric7.Globals.recentNameTestNameHistory?7
 eric7.Globals.sessionType?4()
 eric7.Globals.setConfigDir?4(d)
 eric7.Globals.settingsNameGlobal?7
@@ -6534,7 +6509,6 @@
 eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.InputDialogWizardDialog.getCode?4(indLevel, indString)
 eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.InputDialogWizardDialog.on_bTest_clicked?4()
 eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.InputDialogWizardDialog.on_buttonBox_clicked?4(button)
-eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.InputDialogWizardDialog.on_rItem_toggled?4(checked)
 eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.InputDialogWizardDialog?1(parent=None)
 eric7.Plugins.WizardPlugins.MessageBoxWizard.MessageBoxWizardDialog.MessageBoxWizardDialog.getCode?4(indLevel, indString)
 eric7.Plugins.WizardPlugins.MessageBoxWizard.MessageBoxWizardDialog.MessageBoxWizardDialog.on_bTest_clicked?4()
@@ -7475,15 +7449,19 @@
 eric7.Project.Project.Project.getProjectAuthorEmail?4()
 eric7.Project.Project.Project.getProjectDescription?4()
 eric7.Project.Project.Project.getProjectDictionaries?4()
+eric7.Project.Project.Project.getProjectExecPath?4()
 eric7.Project.Project.Project.getProjectFile?4()
 eric7.Project.Project.Project.getProjectFiles?4(fileType, normalized=False)
+eric7.Project.Project.Project.getProjectInterpreter?4(resolveGlobal=True)
 eric7.Project.Project.Project.getProjectLanguage?4()
 eric7.Project.Project.Project.getProjectManagementDir?4()
 eric7.Project.Project.Project.getProjectName?4()
 eric7.Project.Project.Project.getProjectPath?4()
 eric7.Project.Project.Project.getProjectSpellLanguage?4()
+eric7.Project.Project.Project.getProjectTestingFramework?4()
 eric7.Project.Project.Project.getProjectType?4()
 eric7.Project.Project.Project.getProjectTypes?4(progLanguage="")
+eric7.Project.Project.Project.getProjectVenv?4(resolveDebugger=True)
 eric7.Project.Project.Project.getProjectVersion?4()
 eric7.Project.Project.Project.getRelativePath?4(path)
 eric7.Project.Project.Project.getRelativeUniversalPath?4(path)
@@ -7773,7 +7751,7 @@
 eric7.Project.PropertiesDialog.PropertiesDialog.getPPath?4()
 eric7.Project.PropertiesDialog.PropertiesDialog.getProjectType?4()
 eric7.Project.PropertiesDialog.PropertiesDialog.on_dirPicker_textChanged?4(txt)
-eric7.Project.PropertiesDialog.PropertiesDialog.on_languageComboBox_currentIndexChanged?4(index)
+eric7.Project.PropertiesDialog.PropertiesDialog.on_languageComboBox_currentTextChanged?4(language)
 eric7.Project.PropertiesDialog.PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog?4()
 eric7.Project.PropertiesDialog.PropertiesDialog.on_mainscriptPicker_pathSelected?4(script)
 eric7.Project.PropertiesDialog.PropertiesDialog.on_makeButton_clicked?4()
@@ -7825,55 +7803,6 @@
 eric7.Project.UserProjectFile.UserProjectFile?1(project: Project, parent: QObject = None)
 eric7.Project.UserPropertiesDialog.UserPropertiesDialog.storeData?4()
 eric7.Project.UserPropertiesDialog.UserPropertiesDialog?1(project, parent=None, name=None)
-eric7.PyUnit.UnittestDialog.QtTestResult.addError?4(test, err)
-eric7.PyUnit.UnittestDialog.QtTestResult.addExpectedFailure?4(test, err)
-eric7.PyUnit.UnittestDialog.QtTestResult.addFailure?4(test, err)
-eric7.PyUnit.UnittestDialog.QtTestResult.addSkip?4(test, reason)
-eric7.PyUnit.UnittestDialog.QtTestResult.addSubTest?4(test, subtest, err)
-eric7.PyUnit.UnittestDialog.QtTestResult.addUnexpectedSuccess?4(test)
-eric7.PyUnit.UnittestDialog.QtTestResult.startTest?4(test)
-eric7.PyUnit.UnittestDialog.QtTestResult.stopTest?4(test)
-eric7.PyUnit.UnittestDialog.QtTestResult?1(parent, failfast)
-eric7.PyUnit.UnittestDialog.UnittestDialog.ErrorsInfoRole?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.FailedExpectedColorDarkTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.FailedExpectedColorLightTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.SkippedColorDarkTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.SkippedColorLightTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.SucceededUnexpectedColorDarkTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.SucceededUnexpectedColorLightTheme?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.TestCaseFileRole?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.TestCaseNameRole?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.clearRecent?4()
-eric7.PyUnit.UnittestDialog.UnittestDialog.closeEvent?4(event)
-eric7.PyUnit.UnittestDialog.UnittestDialog.hasFailedTests?4()
-eric7.PyUnit.UnittestDialog.UnittestDialog.insertDiscovery?4(start)
-eric7.PyUnit.UnittestDialog.UnittestDialog.insertProg?4(prog)
-eric7.PyUnit.UnittestDialog.UnittestDialog.insertTestName?4(testName)
-eric7.PyUnit.UnittestDialog.UnittestDialog.keyPressEvent?4(evt)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_buttonBox_clicked?4(button)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_discoverCheckBox_toggled?4(checked)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_discoveryList_itemChanged?4(item, column)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_discoveryList_itemDoubleClicked?4(item, column)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_errorsListWidget_currentTextChanged?4(text)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_errorsListWidget_itemDoubleClicked?4(lbitem)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog?4()
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_testsuitePicker_editTextChanged?4(path)
-eric7.PyUnit.UnittestDialog.UnittestDialog.on_testsuitePicker_pathSelected?4(suite)
-eric7.PyUnit.UnittestDialog.UnittestDialog.setProjectMode?4(forProject)
-eric7.PyUnit.UnittestDialog.UnittestDialog.startTests?4(failedOnly=False)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testErrored?4(test, exc, testId)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testFailed?4(test, exc, testId)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testFailedExpected?4(test, exc, testId)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testFinished?4()
-eric7.PyUnit.UnittestDialog.UnittestDialog.testSkipped?4(test, reason, testId)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testStarted?4(test, doc)
-eric7.PyUnit.UnittestDialog.UnittestDialog.testSucceededUnexpected?4(test, testId)
-eric7.PyUnit.UnittestDialog.UnittestDialog.unittestFile?7
-eric7.PyUnit.UnittestDialog.UnittestDialog.unittestStopped?7
-eric7.PyUnit.UnittestDialog.UnittestDialog?1(prog=None, dbs=None, ui=None, parent=None, name=None)
-eric7.PyUnit.UnittestDialog.UnittestWindow.eventFilter?4(obj, event)
-eric7.PyUnit.UnittestDialog.UnittestWindow?1(prog=None, parent=None)
-eric7.PyUnit.UnittestDialog.clearSavedHistories?4(self)
 eric7.QScintilla.APIsManager.APIs.apiPreparationCancelled?7
 eric7.QScintilla.APIsManager.APIs.apiPreparationFinished?7
 eric7.QScintilla.APIsManager.APIs.apiPreparationStarted?7
@@ -7973,7 +7902,7 @@
 eric7.QScintilla.Editor.Editor.clearWarnings?4()
 eric7.QScintilla.Editor.Editor.close?4(alsoDelete=False)
 eric7.QScintilla.Editor.Editor.closeIt?4()
-eric7.QScintilla.Editor.Editor.codeCoverageShowAnnotations?4(silent=False)
+eric7.QScintilla.Editor.Editor.codeCoverageShowAnnotations?4(silent=False, coverageFile=None)
 eric7.QScintilla.Editor.Editor.collapseFoldWithChildren?4(line=-1)
 eric7.QScintilla.Editor.Editor.commentLine?4()
 eric7.QScintilla.Editor.Editor.commentLineOrSelection?4()
@@ -9246,6 +9175,136 @@
 eric7.Templates.TemplatesFile.TemplatesFile.readFile?4(filename: str)
 eric7.Templates.TemplatesFile.TemplatesFile.writeFile?4(filename: str)
 eric7.Templates.TemplatesFile.TemplatesFile?1(viewer: TemplateViewer, parent: QObject = None)
+eric7.Testing.Interfaces.FrameworkNames?7
+eric7.Testing.Interfaces.Frameworks?7
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.createArguments?4(config)
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.finished?4()
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.getVersions?4(interpreter)
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.hasCoverage?4(interpreter)
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.module?7
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.name?7
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.runner?7
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor.start?4(config, pythonpath)
+eric7.Testing.Interfaces.PytestExecutor.PytestExecutor?1(testWidget)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_collectreport?4(report)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_itemcollected?4(item)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_report_header?4(config, startdir)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_runtest_logfinish?4(nodeid, location)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_runtest_logreport?4(report)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_runtest_logstart?4(nodeid, location)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_sessionfinish?4(session, exitstatus)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin.pytest_sessionstart?4(session)
+eric7.Testing.Interfaces.PytestRunner.EricPlugin?1(writer)
+eric7.Testing.Interfaces.PytestRunner.GetPluginVersionsPlugin.getVersions?4()
+eric7.Testing.Interfaces.PytestRunner.GetPluginVersionsPlugin.pytest_cmdline_main?4(config)
+eric7.Testing.Interfaces.PytestRunner.GetPluginVersionsPlugin?1()
+eric7.Testing.Interfaces.PytestRunner.getVersions?4()
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase._prepareProcess?5(workDir, pythonpath)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.collectError?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.collected?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.coverageDataSaved?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.createArguments?4(config)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.finished?4()
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.getVersions?4(interpreter)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.hasCoverage?4(interpreter)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.isInstalled?4(interpreter)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.module?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.name?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.readAllOutput?4(process=None)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.runner?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.start?4(config, pythonpath)
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.startTest?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.stop?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.stopIfRunning?4()
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.testFinished?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.testResult?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.testRunAboutToBeStarted?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase.testRunFinished?7
+eric7.Testing.Interfaces.TestExecutorBase.TestExecutorBase?1(testWidget)
+eric7.Testing.Interfaces.TestExecutorBase.TestResultCategory.FAIL?7
+eric7.Testing.Interfaces.TestExecutorBase.TestResultCategory.OK?7
+eric7.Testing.Interfaces.TestExecutorBase.TestResultCategory.PENDING?7
+eric7.Testing.Interfaces.TestExecutorBase.TestResultCategory.RUNNING?7
+eric7.Testing.Interfaces.TestExecutorBase.TestResultCategory.SKIP?7
+eric7.Testing.Interfaces.TestFrameworkRegistry.TestFrameworkRegistry.createExecutor?4(framework, widget)
+eric7.Testing.Interfaces.TestFrameworkRegistry.TestFrameworkRegistry.getFrameworks?4()
+eric7.Testing.Interfaces.TestFrameworkRegistry.TestFrameworkRegistry.register?4(executorClass)
+eric7.Testing.Interfaces.TestFrameworkRegistry.TestFrameworkRegistry?1()
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.createArguments?4(config)
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.finished?4()
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.getVersions?4(interpreter)
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.hasCoverage?4(interpreter)
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.module?7
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.name?7
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.runner?7
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor.start?4(config, pythonpath)
+eric7.Testing.Interfaces.UnittestExecutor.UnittestExecutor?1(testWidget)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addError?4(test, err)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addExpectedFailure?4(test, err)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addFailure?4(test, err)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addSkip?4(test, reason)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addSubTest?4(test, subtest, err)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.addUnexpectedSuccess?4(test)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.startTest?4(test)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.startTestRun?4()
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.stopTest?4(test)
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult.stopTestRun?4()
+eric7.Testing.Interfaces.UnittestRunner.EricTestResult?1(writer, failfast)
+eric7.Testing.Interfaces.UnittestRunner._assembleTestCasesList?5(suite)
+eric7.Testing.Interfaces.UnittestRunner.runtest?4(argv)
+eric7.Testing.TestResultsTree.TestResultsModel.DurationColumn?7
+eric7.Testing.TestResultsTree.TestResultsModel.Headers?7
+eric7.Testing.TestResultsTree.TestResultsModel.MessageColumn?7
+eric7.Testing.TestResultsTree.TestResultsModel.NameColumn?7
+eric7.Testing.TestResultsTree.TestResultsModel.StatusColumn?7
+eric7.Testing.TestResultsTree.TestResultsModel.addTestResults?4(testResults)
+eric7.Testing.TestResultsTree.TestResultsModel.clear?4()
+eric7.Testing.TestResultsTree.TestResultsModel.columnCount?4(parent=QModelIndex())
+eric7.Testing.TestResultsTree.TestResultsModel.data?4(index, role)
+eric7.Testing.TestResultsTree.TestResultsModel.durationKey?4()
+eric7.Testing.TestResultsTree.TestResultsModel.getFailedTests?4()
+eric7.Testing.TestResultsTree.TestResultsModel.getTestResults?4()
+eric7.Testing.TestResultsTree.TestResultsModel.headerData?4(section, orientation, role=Qt.ItemDataRole.DisplayRole)
+eric7.Testing.TestResultsTree.TestResultsModel.index?4(row, column, parent=QModelIndex())
+eric7.Testing.TestResultsTree.TestResultsModel.parent?4(index)
+eric7.Testing.TestResultsTree.TestResultsModel.rowCount?4(parent=QModelIndex())
+eric7.Testing.TestResultsTree.TestResultsModel.setTestResults?4(testResults)
+eric7.Testing.TestResultsTree.TestResultsModel.sort?4(column, order)
+eric7.Testing.TestResultsTree.TestResultsModel.summary?7
+eric7.Testing.TestResultsTree.TestResultsModel.updateTestResults?4(testResults)
+eric7.Testing.TestResultsTree.TestResultsModel?1(parent=None)
+eric7.Testing.TestResultsTree.TestResultsTreeView.dataChanged?4(topLeft, bottomRight, roles=[])
+eric7.Testing.TestResultsTree.TestResultsTreeView.goto?7
+eric7.Testing.TestResultsTree.TestResultsTreeView.reset?4()
+eric7.Testing.TestResultsTree.TestResultsTreeView.resizeColumns?4()
+eric7.Testing.TestResultsTree.TestResultsTreeView.rowsInserted?4(parent, startRow, endRow)
+eric7.Testing.TestResultsTree.TestResultsTreeView.spanFirstColumn?4(startRow, endRow)
+eric7.Testing.TestResultsTree.TestResultsTreeView?1(parent=None)
+eric7.Testing.TestResultsTree.TopLevelId?7
+eric7.Testing.TestingWidget.TestingWidget.clearRecent?4()
+eric7.Testing.TestingWidget.TestingWidget.closeEvent?4(event)
+eric7.Testing.TestingWidget.TestingWidget.getFailedTests?4()
+eric7.Testing.TestingWidget.TestingWidget.getResultsModel?4()
+eric7.Testing.TestingWidget.TestingWidget.hasFailedTests?4()
+eric7.Testing.TestingWidget.TestingWidget.on_buttonBox_clicked?4(button)
+eric7.Testing.TestingWidget.TestingWidget.on_discoverCheckBox_toggled?4(checked)
+eric7.Testing.TestingWidget.TestingWidget.on_frameworkComboBox_currentIndexChanged?4(index)
+eric7.Testing.TestingWidget.TestingWidget.on_testsuitePicker_aboutToShowPathPickerDialog?4()
+eric7.Testing.TestingWidget.TestingWidget.on_venvComboBox_currentIndexChanged?4(index)
+eric7.Testing.TestingWidget.TestingWidget.on_versionsButton_clicked?4()
+eric7.Testing.TestingWidget.TestingWidget.setTestFile?4(testFile, forProject=False)
+eric7.Testing.TestingWidget.TestingWidget.startTests?4(failedOnly=False)
+eric7.Testing.TestingWidget.TestingWidget.testFile?7
+eric7.Testing.TestingWidget.TestingWidget.testRunStopped?7
+eric7.Testing.TestingWidget.TestingWidget?1(testfile=None, parent=None)
+eric7.Testing.TestingWidget.TestingWidgetModes.IDLE?7
+eric7.Testing.TestingWidget.TestingWidgetModes.RUNNING?7
+eric7.Testing.TestingWidget.TestingWidgetModes.STOPPED?7
+eric7.Testing.TestingWidget.TestingWindow.eventFilter?4(obj, event)
+eric7.Testing.TestingWidget.TestingWindow?1(testfile=None, parent=None)
+eric7.Testing.TestingWidget.clearSavedHistories?4(self)
+eric7.Testing.isLanguageSupported?4(language)
+eric7.Testing.supportedLanguages?4()
 eric7.Toolbox.SingleApplication.SingleApplicationClient.connect?4(timeout=10000)
 eric7.Toolbox.SingleApplication.SingleApplicationClient.disconnect?4()
 eric7.Toolbox.SingleApplication.SingleApplicationClient.errstr?4()
@@ -9336,7 +9395,7 @@
 eric7.UI.Browser.Browser.handleInterpreterChanged?4(interpreter)
 eric7.UI.Browser.Browser.handlePreferencesChanged?4()
 eric7.UI.Browser.Browser.handleProgramChange?4(fn)
-eric7.UI.Browser.Browser.handleUnittest?4()
+eric7.UI.Browser.Browser.handleTesting?4()
 eric7.UI.Browser.Browser.keyboardSearch?4(search)
 eric7.UI.Browser.Browser.layoutDisplay?4()
 eric7.UI.Browser.Browser.linguistFile?7
@@ -9348,9 +9407,9 @@
 eric7.UI.Browser.Browser.saveToplevelDirs?4()
 eric7.UI.Browser.Browser.sourceFile?7
 eric7.UI.Browser.Browser.svgFile?7
+eric7.UI.Browser.Browser.testFile?7
 eric7.UI.Browser.Browser.trpreview?7
 eric7.UI.Browser.Browser.umlFile?7
-eric7.UI.Browser.Browser.unittestOpen?7
 eric7.UI.Browser.Browser.wantedItem?4(itm, filterList=None)
 eric7.UI.Browser.Browser?1(parent=None)
 eric7.UI.BrowserModel.BrowserClassAttributeItem.attributeObject?4()
@@ -10136,6 +10195,8 @@
 eric7.Utilities.generatePySideToolPath?4(toolname, variant=2)
 eric7.Utilities.generateQtToolName?4(toolname)
 eric7.Utilities.generateVersionInfo?4(linesep='\n')
+eric7.Utilities.getCoverageFileName?4(fn, mustExist=True)
+eric7.Utilities.getCoverageFileNames?4(fn)
 eric7.Utilities.getDirs?4(path, excludeDirs)
 eric7.Utilities.getEnvironmentEntry?4(key, default=None)
 eric7.Utilities.getExecutablePath?4(file)
@@ -10143,12 +10204,14 @@
 eric7.Utilities.getHomeDir?4()
 eric7.Utilities.getPercentReplacement?4(code)
 eric7.Utilities.getPercentReplacementHelp?4()
+eric7.Utilities.getProfileFileName?4(fn, mustExist=True)
+eric7.Utilities.getProfileFileNames?4(fn)
 eric7.Utilities.getPythonLibPath?4()
 eric7.Utilities.getPythonVersion?4()
 eric7.Utilities.getQtMacBundle?4(toolname)
 eric7.Utilities.getRealName?4()
 eric7.Utilities.getSysPath?4(interpreter)
-eric7.Utilities.getTestFileName?4(fn)
+eric7.Utilities.getTestFileNames?4(fn)
 eric7.Utilities.getUserName?4()
 eric7.Utilities.getVolumeName?4(diskName)
 eric7.Utilities.getWindowsExecutablePath?4(file)
@@ -12462,6 +12525,8 @@
 eric7.eric7_snap.main?4()
 eric7.eric7_sqlbrowser.createMainWidget?4(argv)
 eric7.eric7_sqlbrowser.main?4()
+eric7.eric7_testing.createMainWidget?4(argv)
+eric7.eric7_testing.main?4()
 eric7.eric7_tray.SettingsDir?7
 eric7.eric7_tray.createMainWidget?4(argv)
 eric7.eric7_tray.main?4()
@@ -12470,8 +12535,6 @@
 eric7.eric7_trpreviewer.main?4()
 eric7.eric7_uipreviewer.createMainWidget?4(argv)
 eric7.eric7_uipreviewer.main?4()
-eric7.eric7_unittest.createMainWidget?4(argv)
-eric7.eric7_unittest.main?4()
 eric7.eric7_virtualenv.createMainWidget?4(argv)
 eric7.eric7_virtualenv.main?4()
 eric7.eric7config._pkg_config?8
--- a/eric7/APIs/Python3/eric7.bas	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/APIs/Python3/eric7.bas	Wed Jun 01 13:48:49 2022 +0200
@@ -130,7 +130,6 @@
 CreateDialogCodeDialog QDialog Ui_CreateDialogCodeDialog
 CustomHelpFormatter argparse.HelpFormatter
 CustomNamespace argparse.Namespace
-DCTestResult TestResult
 DateTimeVisitor ast.NodeVisitor
 DebugClient DebugBase DebugClientBase ThreadExtension
 DebugServer QTcpServer
@@ -231,6 +230,7 @@
 EricGraphicsView QGraphicsView
 EricHorizontalToolBox EricTabWidget
 EricIconBar QWidget
+EricJsonReader QTcpServer
 EricJsonServer QTcpServer
 EricLed QWidget
 EricLedType enum.Enum
@@ -285,6 +285,7 @@
 EricStringListEditWidget QWidget Ui_EricStringListEditWidget
 EricTabWidget QTabWidget
 EricTableView QTableView
+EricTestResult unittest.TestResult
 EricTextEditSearchWidget QWidget
 EricTextEditType enum.Enum
 EricTextInputDialog QDialog
@@ -780,6 +781,8 @@
 PurgeProjectHelper HgExtensionProjectHelper
 PyBoardDevice MicroPythonDevice
 PyCoverageDialog QDialog Ui_PyCoverageDialog
+PyCoverageHtmlReportDialog QDialog Ui_PyCoverageHtmlReportDialog
+PyCoverageJsonReportDialog QDialog Ui_PyCoverageJsonReportDialog
 PyDocstringGenerator BaseDocstringGenerator
 PyFunctionInfo FunctionInfo
 PyProfile profile.Profile
@@ -792,6 +795,7 @@
 PyRegExpWizardWindow EricMainWindow
 PySvnProjectHelper VcsProjectHelper
 PypiSearchResultsParser html.parser.HTMLParser
+PytestExecutor TestExecutorBase
 PythonAstViewer QWidget
 PythonDisViewer QWidget Ui_PythonDisViewer
 PythonDisViewerModes enum.Enum
@@ -813,7 +817,6 @@
 QtHelpSchemeReply QIODevice
 QtPage ConfigurationPageBase Ui_QtPage
 QtResolver BaseResolver
-QtTestResult unittest.TestResult
 Queues HgExtension
 QueuesProjectHelper HgExtensionProjectHelper
 QuickFindFileDialog QWidget Ui_QuickFindFile
@@ -979,6 +982,13 @@
 TemplatesFile QObject
 TemplatesPage ConfigurationPageBase Ui_TemplatesPage
 TemplatesReader XMLStreamReaderBase
+TestExecutorBase QObject
+TestResultCategory IntEnum
+TestResultsModel QAbstractItemModel
+TestResultsTreeView QTreeView
+TestingWidget QWidget Ui_TestingWidget
+TestingWidgetModes enum.Enum
+TestingWindow EricMainWindow
 TextVisitor ast.NodeVisitor
 ThemeManager QObject
 ThreadWrapper module.Thread
@@ -1006,8 +1016,7 @@
 UMLItem QGraphicsRectItem
 UMLSceneSizeDialog QDialog Ui_UMLSceneSizeDialog
 UicCompilerOptionsDialog QDialog Ui_UicCompilerOptionsDialog
-UnittestDialog QWidget Ui_UnittestDialog
-UnittestWindow EricMainWindow
+UnittestExecutor TestExecutorBase
 UnknownDevicesDialog QDialog Ui_UnknownDevicesDialog
 UrlBar EricClearableLineEdit
 UrlInterceptor QObject
--- a/eric7/CondaInterface/Conda.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/CondaInterface/Conda.py	Wed Jun 01 13:48:49 2022 +0200
@@ -705,7 +705,7 @@
                 process.kill()
                 process.waitForFinished(3000)
                 return False, self.tr("conda did not finish within"
-                                      " 30 seconds.")
+                                      " 3 seconds.")
         
         return False, self.tr("conda could not be started.")
     
--- a/eric7/DataViews/PyCoverageDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DataViews/PyCoverageDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -7,11 +7,11 @@
 Module implementing a Python code coverage dialog.
 """
 
-import contextlib
 import os
 import time
 
-from PyQt6.QtCore import pyqtSlot, Qt
+from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl
+from PyQt6.QtGui import QDesktopServices
 from PyQt6.QtWidgets import (
     QDialog, QDialogButtonBox, QMenu, QHeaderView, QTreeWidgetItem,
     QApplication
@@ -19,7 +19,6 @@
 
 from EricWidgets import EricMessageBox
 from EricWidgets.EricApplication import ericApp
-from EricWidgets.EricProgressDialog import EricProgressDialog
 
 from .Ui_PyCoverageDialog import Ui_PyCoverageDialog
 
@@ -31,12 +30,17 @@
 class PyCoverageDialog(QDialog, Ui_PyCoverageDialog):
     """
     Class implementing a dialog to display the collected code coverage data.
+    
+    @signal openFile(str) emitted to open the given file in an editor
     """
+    openFile = pyqtSignal(str)
+    
     def __init__(self, parent=None):
         """
         Constructor
         
-        @param parent parent widget (QWidget)
+        @param parent parent widget
+        @type QWidget
         """
         super().__init__(parent)
         self.setupUi(self)
@@ -57,16 +61,18 @@
         
         self.excludeList = ['# *pragma[: ]*[nN][oO] *[cC][oO][vV][eE][rR]']
         
+        self.__reportsMenu = QMenu(self.tr("Create Report"), self)
+        self.__reportsMenu.addAction(self.tr("HTML Report"), self.__htmlReport)
+        self.__reportsMenu.addSeparator()
+        self.__reportsMenu.addAction(self.tr("JSON Report"), self.__jsonReport)
+        self.__reportsMenu.addAction(self.tr("LCOV Report"), self.__lcovReport)
+        
         self.__menu = QMenu(self)
         self.__menu.addSeparator()
         self.openAct = self.__menu.addAction(
             self.tr("Open"), self.__openFile)
         self.__menu.addSeparator()
-        self.annotate = self.__menu.addAction(
-            self.tr('Annotate'), self.__annotate)
-        self.__menu.addAction(self.tr('Annotate all'), self.__annotateAll)
-        self.__menu.addAction(
-            self.tr('Delete annotated files'), self.__deleteAnnotated)
+        self.__menu.addMenu(self.__reportsMenu)
         self.__menu.addSeparator()
         self.__menu.addAction(self.tr('Erase Coverage Info'), self.__erase)
         self.resultList.setContextMenuPolicy(
@@ -80,7 +86,9 @@
         groups.
         
         @param lines list of integers
+        @type list of int
         @return string representing the list
+        @rtype str
         """
         pairs = []
         lines.sort()
@@ -110,6 +118,9 @@
             pair.
             
             @param pair pair of integers
+            @type tuple of (int, int
+            @return representation of the pair
+            @rtype str
             """
             start, end = pair
             if start == end:
@@ -124,12 +135,18 @@
         """
         Private method to create an entry in the result list.
         
-        @param file filename of file (string)
-        @param statements amount of statements (integer)
-        @param executed amount of executed statements (integer)
-        @param coverage percent of coverage (integer)
-        @param excluded list of excluded lines (string)
-        @param missing list of lines without coverage (string)
+        @param file filename of file
+        @type str
+        @param statements number of statements
+        @type int
+        @param executed number of executed statements
+        @type int
+        @param coverage percent of coverage
+        @type int
+        @param excluded list of excluded lines
+        @type str
+        @param missing list of lines without coverage
+        @type str
         """
         itm = QTreeWidgetItem(self.resultList, [
             file,
@@ -146,21 +163,35 @@
             font.setBold(True)
             for col in range(itm.columnCount()):
                 itm.setFont(col, font)
-        
+    
     def start(self, cfn, fn):
         """
         Public slot to start the coverage data evaluation.
         
-        @param cfn basename of the coverage file (string)
+        @param cfn basename of the coverage file
+        @type str
         @param fn file or list of files or directory to be checked
-                (string or list of strings)
+        @type str or list of str
         """
+        # initialize the dialog
+        self.resultList.clear()
+        self.summaryList.clear()
+        self.cancelled = False
+        self.buttonBox.button(
+            QDialogButtonBox.StandardButton.Close).setEnabled(False)
+        self.buttonBox.button(
+            QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
+        self.buttonBox.button(
+            QDialogButtonBox.StandardButton.Cancel).setDefault(True)
+        
         self.__cfn = cfn
         self.__fn = fn
         
-        self.basename = os.path.splitext(cfn)[0]
-        
-        self.cfn = "{0}.coverage".format(self.basename)
+        self.cfn = (
+            cfn
+            if cfn.endswith(".coverage") else
+            "{0}.coverage".format(os.path.splitext(cfn)[0])
+        )
         
         if isinstance(fn, list):
             files = fn
@@ -251,7 +282,7 @@
                         total_exceptions))
         
         self.__finish()
-        
+    
     def __finish(self):
         """
         Private slot called when the action finished or the user pressed the
@@ -271,12 +302,13 @@
         self.summaryList.header().resizeSections(
             QHeaderView.ResizeMode.ResizeToContents)
         self.summaryList.header().setStretchLastSection(True)
-        
+    
     def on_buttonBox_clicked(self, button):
         """
         Private slot called by a button of the button box clicked.
         
-        @param button button that was clicked (QAbstractButton)
+        @param button button that was clicked
+        @type QAbstractButton
         """
         if button == self.buttonBox.button(
             QDialogButtonBox.StandardButton.Close
@@ -286,88 +318,122 @@
             QDialogButtonBox.StandardButton.Cancel
         ):
             self.__finish()
-        
+    
     def __showContextMenu(self, coord):
         """
         Private slot to show the context menu of the listview.
         
-        @param coord the position of the mouse pointer (QPoint)
+        @param coord position of the mouse pointer
+        @type QPoint
         """
         itm = self.resultList.itemAt(coord)
         if itm:
-            self.annotate.setEnabled(True)
             self.openAct.setEnabled(True)
         else:
-            self.annotate.setEnabled(False)
             self.openAct.setEnabled(False)
+        self.__reportsMenu.setEnabled(
+            bool(self.resultList.topLevelItemCount()))
         self.__menu.popup(self.mapToGlobal(coord))
-        
+    
     def __openFile(self, itm=None):
         """
         Private slot to open the selected file.
         
-        @param itm reference to the item to be opened (QTreeWidgetItem)
+        @param itm reference to the item to be opened
+        @type QTreeWidgetItem
         """
         if itm is None:
             itm = self.resultList.currentItem()
         fn = itm.text(0)
         
-        vm = ericApp().getObject("ViewManager")
-        vm.openSourceFile(fn)
-        editor = vm.getOpenEditor(fn)
-        editor.codeCoverageShowAnnotations()
-        
-    def __annotate(self):
+        try:
+            vm = ericApp().getObject("ViewManager")
+            vm.openSourceFile(fn)
+            editor = vm.getOpenEditor(fn)
+            editor.codeCoverageShowAnnotations(coverageFile=self.cfn)
+        except KeyError:
+            self.openFile.emit(fn)
+    
+    def __prepareReportGeneration(self):
         """
-        Private slot to handle the annotate context menu action.
-        
-        This method produce an annotated coverage file of the
-        selected file.
-        """
-        itm = self.resultList.currentItem()
-        fn = itm.text(0)
+        Private method to prepare a report generation.
         
-        cover = Coverage(data_file=self.cfn)
-        cover.exclude(self.excludeList[0])
-        cover.load()
-        cover.annotate([fn], None, True)
-        
-    def __annotateAll(self):
+        @return tuple containing a reference to the Coverage object and the
+            list of files to report
+        @rtype tuple of (Coverage, list of str)
         """
-        Private slot to handle the annotate all context menu action.
-        
-        This method produce an annotated coverage file of every
-        file listed in the listview.
-        """
-        amount = self.resultList.topLevelItemCount()
-        if amount == 0:
-            return
+        count = self.resultList.topLevelItemCount()
+        if count == 0:
+            return None, []
         
         # get list of all filenames
-        files = []
-        for index in range(amount):
-            itm = self.resultList.topLevelItem(index)
-            files.append(itm.text(0))
+        files = [
+            self.resultList.topLevelItem(index).text(0)
+            for index in range(count)
+        ]
         
         cover = Coverage(data_file=self.cfn)
         cover.exclude(self.excludeList[0])
         cover.load()
         
-        # now process them
-        progress = EricProgressDialog(
-            self.tr("Annotating files..."), self.tr("Abort"),
-            0, len(files), self.tr("%v/%m Files"), self)
-        progress.setMinimumDuration(0)
-        progress.setWindowTitle(self.tr("Coverage"))
+        return cover, files
+    
+    @pyqtSlot()
+    def __htmlReport(self):
+        """
+        Private slot to generate a HTML report of the shown data.
+        """
+        from .PyCoverageHtmlReportDialog import PyCoverageHtmlReportDialog
+        
+        dlg = PyCoverageHtmlReportDialog(os.path.dirname(self.cfn), self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            title, outputDirectory, extraCSS, openReport = dlg.getData()
+            
+            cover, files = self.__prepareReportGeneration()
+            cover.html_report(morfs=files, directory=outputDirectory,
+                              ignore_errors=True, extra_css=extraCSS,
+                              title=title)
+            
+            if openReport:
+                QDesktopServices.openUrl(QUrl.fromLocalFile(os.path.join(
+                    outputDirectory, "index.html")))
+    
+    @pyqtSlot()
+    def __jsonReport(self):
+        """
+        Private slot to generate a JSON report of the shown data.
+        """
+        from .PyCoverageJsonReportDialog import PyCoverageJsonReportDialog
         
-        for count, file in enumerate(files):
-            progress.setValue(count)
-            if progress.wasCanceled():
-                break
-            cover.annotate([file], None)  # , True)
+        dlg = PyCoverageJsonReportDialog(os.path.dirname(self.cfn), self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            filename, compact = dlg.getData()
+            cover, files = self.__prepareReportGeneration()
+            cover.json_report(morfs=files, outfile=filename,
+                              ignore_errors=True, pretty_print=not compact)
+    
+    @pyqtSlot()
+    def __lcovReport(self):
+        """
+        Private slot to generate a LCOV report of the shown data.
+        """
+        from EricWidgets import EricPathPickerDialog
+        from EricWidgets.EricPathPicker import EricPathPickerModes
         
-        progress.setValue(len(files))
-        
+        filename, ok = EricPathPickerDialog.getPath(
+            self,
+            self.tr("LCOV Report"),
+            self.tr("Enter the path of the output file:"),
+            mode=EricPathPickerModes.SAVE_FILE_ENSURE_EXTENSION_MODE,
+            path=os.path.join(os.path.dirname(self.cfn), "coverage.lcov"),
+            defaultDirectory=os.path.dirname(self.cfn),
+            filters=self.tr("LCOV Files (*.lcov);;All Files (*)")
+        )
+        if ok:
+            cover, files = self.__prepareReportGeneration()
+            cover.lcov_report(morfs=files, outfile=filename,
+                              ignore_errors=True)
+    
     def __erase(self):
         """
         Private slot to handle the erase context menu action.
@@ -382,38 +448,17 @@
         self.reloadButton.setEnabled(False)
         self.resultList.clear()
         self.summaryList.clear()
-        
-    def __deleteAnnotated(self):
-        """
-        Private slot to handle the delete annotated context menu action.
-        
-        This method deletes all annotated files. These are files
-        ending with ',cover'.
-        """
-        files = Utilities.direntries(self.path, True, '*,cover', False)
-        for file in files:
-            with contextlib.suppress(OSError):
-                os.remove(file)
-
+    
     @pyqtSlot()
     def on_reloadButton_clicked(self):
         """
         Private slot to reload the coverage info.
         """
-        self.resultList.clear()
-        self.summaryList.clear()
         self.reload = True
         excludePattern = self.excludeCombo.currentText()
         if excludePattern in self.excludeList:
             self.excludeList.remove(excludePattern)
         self.excludeList.insert(0, excludePattern)
-        self.cancelled = False
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setDefault(True)
         self.start(self.__cfn, self.__fn)
     
     @pyqtSlot(QTreeWidgetItem, int)
--- a/eric7/DebugClients/Python/DebugClientBase.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/DebugClientBase.py	Wed Jun 01 13:48:49 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	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/DebugClientCapabilities.py	Wed Jun 01 13:48:49 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/DebugClients/Python/coverage/cmdline.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/cmdline.py	Wed Jun 01 13:48:49 2022 +0200
@@ -232,9 +232,7 @@
     """
 
     def __init__(self, *args, **kwargs):
-        super().__init__(
-            add_help_option=False, *args, **kwargs
-            )
+        super().__init__(add_help_option=False, *args, **kwargs)
         self.set_defaults(
             # Keep these arguments alphabetized by their names.
             action=None,
@@ -267,7 +265,7 @@
             timid=None,
             title=None,
             version=None,
-            )
+        )
 
         self.disable_interspersed_args()
 
@@ -352,7 +350,7 @@
     Opts.debug,
     Opts.help,
     Opts.rcfile,
-    ]
+]
 
 COMMANDS = {
     'annotate': CmdOptionParser(
@@ -473,7 +471,7 @@
             Opts.output_lcov,
             Opts.omit,
             Opts.quiet,
-        ] + GLOBAL_ARGS,
+            ] + GLOBAL_ARGS,
         usage="[options] [modules]",
         description="Generate an LCOV report of coverage results.",
     ),
@@ -648,7 +646,7 @@
             check_preimported=True,
             context=options.context,
             messages=not options.quiet,
-            )
+        )
 
         if options.action == "debug":
             return self.do_debug(args)
@@ -675,7 +673,7 @@
             omit=omit,
             include=include,
             contexts=contexts,
-            )
+        )
 
         # We need to be able to import from the current directory, because
         # plugins may try to, for example, to read Django settings.
@@ -692,7 +690,7 @@
                 skip_empty=options.skip_empty,
                 sort=options.sort,
                 **report_args
-                )
+            )
         elif options.action == "annotate":
             self.coverage.annotate(directory=options.directory, **report_args)
         elif options.action == "html":
@@ -704,25 +702,25 @@
                 show_contexts=options.show_contexts,
                 title=options.title,
                 **report_args
-                )
+            )
         elif options.action == "xml":
             total = self.coverage.xml_report(
                 outfile=options.outfile,
                 skip_empty=options.skip_empty,
                 **report_args
-                )
+            )
         elif options.action == "json":
             total = self.coverage.json_report(
                 outfile=options.outfile,
                 pretty_print=options.pretty_print,
                 show_contexts=options.show_contexts,
                 **report_args
-                )
+            )
         elif options.action == "lcov":
             total = self.coverage.lcov_report(
                 outfile=options.outfile,
                 **report_args
-                )
+            )
         else:
             # There are no other possible actions.
             raise AssertionError
--- a/eric7/DebugClients/Python/coverage/collector.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/collector.py	Wed Jun 01 13:48:49 2022 +0200
@@ -145,6 +145,7 @@
             raise ConfigError(f"Conflicting concurrency settings: {show}")
         do_threading = False
 
+        tried = "nothing"  # to satisfy pylint
         try:
             if "greenlet" in concurrencies:
                 tried = "greenlet"
@@ -327,8 +328,7 @@
         self._collectors.append(self)
 
         # Replay all the events from fullcoverage into the new trace function.
-        for args in traces0:
-            (frame, event, arg), lineno = args
+        for (frame, event, arg), lineno in traces0:
             try:
                 fn(frame, event, arg, lineno=lineno)
             except TypeError as ex:
--- a/eric7/DebugClients/Python/coverage/config.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/config.py	Wed Jun 01 13:48:49 2022 +0200
@@ -190,6 +190,7 @@
         self.relative_files = False
         self.run_include = None
         self.run_omit = None
+        self.sigterm = False
         self.source = None
         self.source_pkgs = []
         self.timid = False
@@ -364,6 +365,7 @@
         ('relative_files', 'run:relative_files', 'boolean'),
         ('run_include', 'run:include', 'list'),
         ('run_omit', 'run:omit', 'list'),
+        ('sigterm', 'run:sigterm', 'boolean'),
         ('source', 'run:source', 'list'),
         ('source_pkgs', 'run:source_pkgs', 'list'),
         ('timid', 'run:timid', 'boolean'),
@@ -499,7 +501,7 @@
         """Make a list of (name, value) pairs for writing debug info."""
         return human_sorted_items(
             (k, v) for k, v in self.__dict__.items() if not k.startswith("_")
-            )
+        )
 
 
 def config_files_to_try(config_file):
--- a/eric7/DebugClients/Python/coverage/control.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/control.py	Wed Jun 01 13:48:49 2022 +0200
@@ -250,7 +250,7 @@
             source=source, source_pkgs=source_pkgs, run_omit=omit, run_include=include, debug=debug,
             report_omit=omit, report_include=include,
             concurrency=concurrency, context=context,
-            )
+        )
 
         # If we have sub-process measurement happening automatically, then we
         # want any explicit creation of a Coverage object to mean, this process
@@ -489,7 +489,7 @@
             branch=self.config.branch,
             warn=self._warn,
             concurrency=concurrency,
-            )
+        )
 
         suffix = self._data_suffix_specified
         if suffix:
@@ -515,10 +515,10 @@
                     ", ".join(
                         plugin._coverage_plugin_name
                             for plugin in self._plugins.file_tracers
-                        ),
+                    ),
                     self._collector.tracer_name(),
-                    )
                 )
+            )
             for plugin in self._plugins.file_tracers:
                 plugin._coverage_enabled = False
 
@@ -536,12 +536,13 @@
 
         # Register our clean-up handlers.
         atexit.register(self._atexit)
-        is_main = (threading.current_thread() == threading.main_thread())
-        if is_main and not env.WINDOWS:
-            # The Python docs seem to imply that SIGTERM works uniformly even
-            # on Windows, but that's not my experience, and this agrees:
-            # https://stackoverflow.com/questions/35772001/x/35792192#35792192
-            self._old_sigterm = signal.signal(signal.SIGTERM, self._on_sigterm)
+        if self.config.sigterm:
+            is_main = (threading.current_thread() == threading.main_thread())
+            if is_main and not env.WINDOWS:
+                # The Python docs seem to imply that SIGTERM works uniformly even
+                # on Windows, but that's not my experience, and this agrees:
+                # https://stackoverflow.com/questions/35772001/x/35792192#35792192
+                self._old_sigterm = signal.signal(signal.SIGTERM, self._on_sigterm)
 
     def _init_data(self, suffix):
         """Create a data file if we don't have one yet."""
@@ -835,7 +836,7 @@
             sorted(analysis.excluded),
             sorted(analysis.missing),
             analysis.missing_formatted(),
-            )
+        )
 
     def _analyze(self, it):
         """Analyze a single morf or code unit.
@@ -1146,7 +1147,7 @@
                 )
             )),
             ('command_line', " ".join(getattr(sys, 'argv', ['-none-']))),
-            ]
+        ]
 
         if self._inorout:
             info.extend(self._inorout.sys_info())
--- a/eric7/DebugClients/Python/coverage/debug.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/debug.py	Wed Jun 01 13:48:49 2022 +0200
@@ -211,7 +211,7 @@
             klass=self.__class__.__name__,
             id=id(self),
             attrs=" ".join(f"{k}={v!r}" for k, v in show_attrs),
-            )
+        )
 
 
 def simplify(v):                                            # pragma: debugging
--- a/eric7/DebugClients/Python/coverage/doc/CHANGES.rst	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/doc/CHANGES.rst	Wed Jun 01 13:48:49 2022 +0200
@@ -17,6 +17,59 @@
     ..  Version 9.8.1 — 2027-07-27
     ..  --------------------------
 
+.. _changes_64:
+
+Version 6.4 — 2022-05-22
+------------------------
+
+- A new setting, :ref:`config_run_sigterm`, controls whether a SIGTERM signal
+  handler is used.  In 6.3, the signal handler was always installed, to capture
+  data at unusual process ends.  Unfortunately, this introduced other problems
+  (see `issue 1310`_).  Now the signal handler is only used if you opt-in by
+  setting ``[run] sigterm = true``.
+
+- Small changes to the HTML report:
+
+  - Added links to next and previous file, and more keyboard shortcuts: ``[``
+    and ``]`` for next file and previous file; ``u`` for up to the index; and
+    ``?`` to open/close the help panel.  Thanks, `J. M. F. Tsang
+    <pull 1364_>`_.
+
+  - The timestamp and version are displayed at the top of the report.  Thanks,
+    `Ammar Askar <pull 1354_>`_. Closes `issue 1351`_.
+
+- A new debug option ``debug=sqldata`` adds more detail to ``debug=sql``,
+  logging all the data being written to the database.
+
+- Previously, running ``coverage report`` (or any of the reporting commands) in
+  an empty directory would create a .coverage data file.  Now they do not,
+  fixing `issue 1328`_.
+
+- On Python 3.11, the ``[toml]`` extra no longer installs tomli, instead using
+  tomllib from the standard library.  Thanks `Shantanu <pull 1359_>`_.
+
+- In-memory CoverageData objects now properly update(), closing `issue 1323`_.
+
+.. _issue 1310: https://github.com/nedbat/coveragepy/issues/1310
+.. _issue 1323: https://github.com/nedbat/coveragepy/issues/1323
+.. _issue 1328: https://github.com/nedbat/coveragepy/issues/1328
+.. _issue 1351: https://github.com/nedbat/coveragepy/issues/1351
+.. _pull 1354: https://github.com/nedbat/coveragepy/pull/1354
+.. _pull 1359: https://github.com/nedbat/coveragepy/pull/1359
+.. _pull 1364: https://github.com/nedbat/coveragepy/pull/1364
+
+
+.. _changes_633:
+
+Version 6.3.3 — 2022-05-12
+--------------------------
+
+- Fix: Coverage.py now builds successfully on CPython 3.11 (3.11.0b1) again.
+  Closes `issue 1367`_.  Some results for generators may have changed.
+
+.. _issue 1367: https://github.com/nedbat/coveragepy/issues/1367
+
+
 .. _changes_632:
 
 Version 6.3.2 — 2022-02-20
--- a/eric7/DebugClients/Python/coverage/doc/CONTRIBUTORS.txt	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/doc/CONTRIBUTORS.txt	Wed Jun 01 13:48:49 2022 +0200
@@ -14,6 +14,7 @@
 Alex Sandro
 Alexander Todorov
 Alexander Walters
+Ammar Askar
 Andrew Hoos
 Anthony Sottile
 Arcadiy Ivanov
@@ -75,6 +76,7 @@
 Ilia Meerovich
 Imri Goldberg
 Ionel Cristian Mărieș
+J. M. F. Tsang
 JT Olds
 Jerin Peter George
 Jessamyn Smith
@@ -137,6 +139,7 @@
 Stefan Behnel
 Stephan Richter
 Stephen Finucane
+Steve Dower
 Steve Leonard
 Steve Peak
 S. Y. Lee
--- a/eric7/DebugClients/Python/coverage/doc/README.rst	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/doc/README.rst	Wed Jun 01 13:48:49 2022 +0200
@@ -7,11 +7,17 @@
 
 Code coverage testing for Python.
 
+.. image:: https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg
+    :target: https://vshymanskyy.github.io/StandWithUkraine
+    :alt: Stand with Ukraine
+
+-------------
+
 |  |license| |versions| |status|
 |  |test-status| |quality-status| |docs| |metacov|
 |  |kit| |downloads| |format| |repos|
 |  |stars| |forks| |contributors|
-|  |tidelift| |twitter-coveragepy| |twitter-nedbat|
+|  |tidelift| |sponsor| |twitter-coveragepy| |twitter-nedbat|
 
 Coverage.py measures code coverage, typically during test execution. It uses
 the code analysis tools and tracing hooks provided in the Python standard
@@ -21,7 +27,7 @@
 
 .. PYVERSIONS
 
-* CPython 3.7 through 3.11.0a4.
+* CPython 3.7 through 3.11.0b1.
 * PyPy3 7.3.8.
 
 Documentation is on `Read the Docs`_.  Code repository and issue tracker are on
@@ -148,3 +154,6 @@
 .. |twitter-nedbat| image:: https://img.shields.io/twitter/follow/nedbat.svg?label=nedbat&style=flat&logo=twitter&logoColor=4FADFF
     :target: https://twitter.com/nedbat
     :alt: nedbat on Twitter
+.. |sponsor| image:: https://img.shields.io/badge/%E2%9D%A4-Sponsor%20me-brightgreen?style=flat&logo=GitHub
+    :target: https://github.com/sponsors/nedbat
+    :alt: Sponsor me on GitHub
--- a/eric7/DebugClients/Python/coverage/html.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/html.py	Wed Jun 01 13:48:49 2022 +0200
@@ -122,6 +122,15 @@
         return file_data
 
 
+class FileToReport:
+    """A file we're considering reporting."""
+    def __init__(self, fr, analysis):
+        self.fr = fr
+        self.analysis = analysis
+        self.rootname = flat_rootname(fr.relative_filename())
+        self.html_filename = self.rootname + ".html"
+
+
 class HtmlReporter:
     """HTML reporting."""
 
@@ -165,6 +174,8 @@
         self.datagen = HtmlDataGeneration(self.coverage)
         self.totals = Numbers(precision=self.config.precision)
         self.directory_was_empty = False
+        self.first_fr = None
+        self.final_fr = None
 
         self.template_globals = {
             # Functions available in the templates.
@@ -188,7 +199,7 @@
                 'mis': 'mis show_mis',
                 'par': 'par run show_par',
                 'run': 'run',
-            }
+            },
         }
         self.pyfile_html_source = read_data("pyfile.html")
         self.source_tmpl = Templite(self.pyfile_html_source, self.template_globals)
@@ -204,9 +215,28 @@
         self.incr.read()
         self.incr.check_global_data(self.config, self.pyfile_html_source)
 
-        # Process all the files.
+        # Process all the files. For each page we need to supply a link
+        # to the next and previous page.
+        files_to_report = []
+
         for fr, analysis in get_analysis_to_report(self.coverage, morfs):
-            self.html_file(fr, analysis)
+            ftr = FileToReport(fr, analysis)
+            should = self.should_report_file(ftr)
+            if should:
+                files_to_report.append(ftr)
+            else:
+                file_be_gone(os.path.join(self.directory, ftr.html_filename))
+
+        for i, ftr in enumerate(files_to_report):
+            if i == 0:
+                prev_html = "index.html"
+            else:
+                prev_html = files_to_report[i - 1].html_filename
+            if i == len(files_to_report) - 1:
+                next_html = "index.html"
+            else:
+                next_html = files_to_report[i + 1].html_filename
+            self.write_html_file(ftr, prev_html, next_html)
 
         if not self.all_files_nums:
             raise NoDataError("No data to report.")
@@ -214,11 +244,22 @@
         self.totals = sum(self.all_files_nums)
 
         # Write the index file.
-        self.index_file()
+        if files_to_report:
+            first_html = files_to_report[0].html_filename
+            final_html = files_to_report[-1].html_filename
+        else:
+            first_html = final_html = "index.html"
+        self.index_file(first_html, final_html)
 
         self.make_local_static_report_files()
         return self.totals.n_statements and self.totals.pc_covered
 
+    def make_directory(self):
+        """Make sure our htmlcov directory exists."""
+        ensure_dir(self.directory)
+        if not os.listdir(self.directory):
+            self.directory_was_empty = True
+
     def make_local_static_report_files(self):
         """Make local instances of static files for HTML report."""
         # The files we provide must always be copied.
@@ -236,17 +277,10 @@
         if self.extra_css:
             shutil.copyfile(self.config.extra_css, os.path.join(self.directory, self.extra_css))
 
-    def html_file(self, fr, analysis):
-        """Generate an HTML file for one source file."""
-        rootname = flat_rootname(fr.relative_filename())
-        html_filename = rootname + ".html"
-        ensure_dir(self.directory)
-        if not os.listdir(self.directory):
-            self.directory_was_empty = True
-        html_path = os.path.join(self.directory, html_filename)
-
+    def should_report_file(self, ftr):
+        """Determine if we'll report this file."""
         # Get the numbers for this file.
-        nums = analysis.numbers
+        nums = ftr.analysis.numbers
         self.all_files_nums.append(nums)
 
         if self.skip_covered:
@@ -255,24 +289,28 @@
             no_missing_branches = (nums.n_partial_branches == 0)
             if no_missing_lines and no_missing_branches:
                 # If there's an existing file, remove it.
-                file_be_gone(html_path)
                 self.skipped_covered_count += 1
-                return
+                return False
 
         if self.skip_empty:
             # Don't report on empty files.
             if nums.n_statements == 0:
-                file_be_gone(html_path)
                 self.skipped_empty_count += 1
-                return
+                return False
+
+        return True
+
+    def write_html_file(self, ftr, prev_html, next_html):
+        """Generate an HTML file for one source file."""
+        self.make_directory()
 
         # Find out if the file on disk is already correct.
-        if self.incr.can_skip_file(self.data, fr, rootname):
-            self.file_summaries.append(self.incr.index_info(rootname))
+        if self.incr.can_skip_file(self.data, ftr.fr, ftr.rootname):
+            self.file_summaries.append(self.incr.index_info(ftr.rootname))
             return
 
         # Write the HTML page for this file.
-        file_data = self.datagen.data_for_file(fr, analysis)
+        file_data = self.datagen.data_for_file(ftr.fr, ftr.analysis)
         for ldata in file_data.lines:
             # Build the HTML for the line.
             html = []
@@ -292,7 +330,7 @@
                 ldata.annotate = ",&nbsp;&nbsp; ".join(
                     f"{ldata.number}&#x202F;&#x219B;&#x202F;{d}"
                     for d in ldata.short_annotations
-                    )
+                )
             else:
                 ldata.annotate = None
 
@@ -306,7 +344,7 @@
                         ", ".join(
                             f"{num:d}) {ann_long}"
                             for num, ann_long in enumerate(longs, start=1)
-                            ),
+                        ),
                     )
             else:
                 ldata.annotate_long = None
@@ -316,20 +354,26 @@
                 css_classes.append(self.template_globals['category'][ldata.category])
             ldata.css_class = ' '.join(css_classes) or "pln"
 
-        html = self.source_tmpl.render(file_data.__dict__)
+        html_path = os.path.join(self.directory, ftr.html_filename)
+        html = self.source_tmpl.render({
+            **file_data.__dict__,
+            'prev_html': prev_html,
+            'next_html': next_html,
+        })
         write_html(html_path, html)
 
         # Save this file's information for the index file.
         index_info = {
-            'nums': nums,
-            'html_filename': html_filename,
-            'relative_filename': fr.relative_filename(),
+            'nums': ftr.analysis.numbers,
+            'html_filename': ftr.html_filename,
+            'relative_filename': ftr.fr.relative_filename(),
         }
         self.file_summaries.append(index_info)
-        self.incr.set_index_info(rootname, index_info)
+        self.incr.set_index_info(ftr.rootname, index_info)
 
-    def index_file(self):
+    def index_file(self, first_html, final_html):
         """Write the index.html file for this report."""
+        self.make_directory()
         index_tmpl = Templite(read_data("index.html"), self.template_globals)
 
         skipped_covered_msg = skipped_empty_msg = ""
@@ -345,6 +389,8 @@
             'totals': self.totals,
             'skipped_covered_msg': skipped_covered_msg,
             'skipped_empty_msg': skipped_empty_msg,
+            'first_html': first_html,
+            'final_html': final_html,
         })
 
         index_file = os.path.join(self.directory, "index.html")
--- a/eric7/DebugClients/Python/coverage/htmlfiles/coverage_html.js	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/htmlfiles/coverage_html.js	Wed Jun 01 13:48:49 2022 +0200
@@ -25,6 +25,13 @@
     return !(rect.bottom < viewTop || rect.top >= viewBottom);
 }
 
+function on_click(sel, fn) {
+    const elt = document.querySelector(sel);
+    if (elt) {
+        elt.addEventListener("click", fn);
+    }
+}
+
 // Helpers for table sorting
 function getCellValue(row, column = 0) {
     const cell = row.cells[column]
@@ -193,6 +200,11 @@
             direction: th.getAttribute("aria-sort"),
         }));
     });
+
+    on_click(".button_prev_file", coverage.to_prev_file);
+    on_click(".button_next_file", coverage.to_next_file);
+
+    on_click(".button_show_hide_help", coverage.show_hide_help);
 };
 
 // -- pyfile stuff --
@@ -209,12 +221,6 @@
         coverage.set_sel(0);
     }
 
-    const on_click = function(sel, fn) {
-        const elt = document.querySelector(sel);
-        if (elt) {
-            elt.addEventListener("click", fn);
-        }
-    }
     on_click(".button_toggle_run", coverage.toggle_lines);
     on_click(".button_toggle_mis", coverage.toggle_lines);
     on_click(".button_toggle_exc", coverage.toggle_lines);
@@ -225,6 +231,12 @@
     on_click(".button_top_of_page", coverage.to_top);
     on_click(".button_first_chunk", coverage.to_first_chunk);
 
+    on_click(".button_prev_file", coverage.to_prev_file);
+    on_click(".button_next_file", coverage.to_next_file);
+    on_click(".button_to_index", coverage.to_index);
+
+    on_click(".button_show_hide_help", coverage.show_hide_help);
+
     coverage.filters = undefined;
     try {
         coverage.filters = localStorage.getItem(coverage.LINE_FILTERS_STORAGE);
@@ -299,6 +311,23 @@
     coverage.to_next_chunk();
 };
 
+coverage.to_prev_file = function () {
+    window.location = document.getElementById("prevFileLink").href;
+}
+
+coverage.to_next_file = function () {
+    window.location = document.getElementById("nextFileLink").href;
+}
+
+coverage.to_index = function () {
+    location.href = document.getElementById("indexLink").href;
+}
+
+coverage.show_hide_help = function () {
+    const helpCheck = document.getElementById("help_panel_state")
+    helpCheck.checked = !helpCheck.checked;
+}
+
 // Return a string indicating what kind of chunk this line belongs to,
 // or null if not a chunk.
 coverage.chunk_indicator = function (line_elt) {
--- a/eric7/DebugClients/Python/coverage/htmlfiles/index.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/htmlfiles/index.html	Wed Jun 01 13:48:49 2022 +0200
@@ -21,15 +21,15 @@
             <span class="pc_cov">{{totals.pc_covered_str}}%</span>
         </h1>
 
-        <div id="help_panel_wrapper">
+        <aside id="help_panel_wrapper">
             <input id="help_panel_state" type="checkbox">
             <label for="help_panel_state">
                 <img id="keyboard_icon" src="keybd_closed.png" alt="Show/hide keyboard shortcuts" />
             </label>
             <div id="help_panel">
                 <p class="legend">Shortcuts on this page</p>
-                <div>
-                    <p class="keyhelp">
+                <div class="keyhelp">
+                    <p>
                         <kbd>n</kbd>
                         <kbd>s</kbd>
                         <kbd>m</kbd>
@@ -38,15 +38,29 @@
                         <kbd>b</kbd>
                         <kbd>p</kbd>
                         {% endif %}
-                        <kbd>c</kbd> &nbsp; change column sorting
+                        <kbd>c</kbd>
+                        &nbsp; change column sorting
+                    </p>
+                    <p>
+                        <kbd>[</kbd>
+                        <kbd>]</kbd>
+                        &nbsp; prev/next file
+                    </p>
+                    <p>
+                        <kbd>?</kbd> &nbsp; show/hide this help
                     </p>
                 </div>
             </div>
-        </div>
+        </aside>
 
         <form id="filter_container">
             <input id="filter" type="text" value="" placeholder="filter..." />
         </form>
+
+        <p class="text">
+            <a class="nav" href="{{__url__}}">coverage.py v{{__version__}}</a>,
+            created at {{ time_stamp }}
+        </p>
     </div>
 </header>
 
@@ -115,6 +129,13 @@
             created at {{ time_stamp }}
         </p>
     </div>
+    <aside class="hidden">
+        <a id="prevFileLink" class="nav" href="{{ final_html }}"/>
+        <a id="nextFileLink" class="nav" href="{{ first_html }}"/>
+        <button type="button" class="button_prev_file" data-shortcut="["/>
+        <button type="button" class="button_next_file" data-shortcut="]"/>
+        <button type="button" class="button_show_hide_help" data-shortcut="?"/>
+    </aside>
 </footer>
 
 </body>
--- a/eric7/DebugClients/Python/coverage/htmlfiles/pyfile.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/htmlfiles/pyfile.html	Wed Jun 01 13:48:49 2022 +0200
@@ -5,9 +5,6 @@
 <html>
 <head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    {# IE8 rounds line-height incorrectly, and adding this emulateIE7 line makes it right! #}
-    {# http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/7684445e-f080-4d8f-8529-132763348e21 #}
-    <meta http-equiv="X-UA-Compatible" content="IE=emulateIE7" />
     <title>Coverage for {{relative_filename|escape}}: {{nums.pc_covered_str}}%</title>
     <link rel="icon" sizes="32x32" href="favicon_32.png">
     <link rel="stylesheet" href="style.css" type="text/css">
@@ -25,15 +22,15 @@
             <span class="pc_cov">{{nums.pc_covered_str}}%</span>
         </h1>
 
-        <div id="help_panel_wrapper">
+        <aside id="help_panel_wrapper">
             <input id="help_panel_state" type="checkbox">
             <label for="help_panel_state">
                 <img id="keyboard_icon" src="keybd_closed.png" alt="Show/hide keyboard shortcuts" />
             </label>
             <div id="help_panel">
                 <p class="legend">Shortcuts on this page</p>
-                <div>
-                    <p class="keyhelp">
+                <div class="keyhelp">
+                    <p>
                         <kbd>r</kbd>
                         <kbd>m</kbd>
                         <kbd>x</kbd>
@@ -42,19 +39,31 @@
                         {% endif %}
                         &nbsp; toggle line displays
                     </p>
-                    <p class="keyhelp">
+                    <p>
                         <kbd>j</kbd>
-                        <kbd>k</kbd> &nbsp; next/prev highlighted chunk
+                        <kbd>k</kbd>
+                        &nbsp; next/prev highlighted chunk
                     </p>
-                    <p class="keyhelp">
+                    <p>
                         <kbd>0</kbd> &nbsp; (zero) top of page
                     </p>
-                    <p class="keyhelp">
+                    <p>
                         <kbd>1</kbd> &nbsp; (one) first highlighted chunk
                     </p>
+                    <p>
+                        <kbd>[</kbd>
+                        <kbd>]</kbd>
+                        &nbsp; prev/next file
+                    </p>
+                    <p>
+                        <kbd>u</kbd> &nbsp; up to the index
+                    </p>
+                    <p>
+                        <kbd>?</kbd> &nbsp; show/hide this help
+                    </p>
                 </div>
             </div>
-        </div>
+        </aside>
 
         <h2>
             <span class="text">{{nums.n_statements}} statements &nbsp;</span>
@@ -66,12 +75,25 @@
             {% endif %}
         </h2>
 
-        <div style="display: none;">
-            <button type="button" class="button_next_chunk" data-shortcut="j">Next highlighted chunk</button>
-            <button type="button" class="button_prev_chunk" data-shortcut="k">Previous highlighted chunk</button>
-            <button type="button" class="button_top_of_page" data-shortcut="0">Goto top of page</button>
-            <button type="button" class="button_first_chunk" data-shortcut="1">Goto first highlighted chunk</button>
-        </div>
+        <p class="text">
+            <a id="prevFileLink" class="nav" href="{{ prev_html }}">&#xab; prev</a> &nbsp; &nbsp;
+            <a id="indexLink" class="nav" href="index.html">&Hat; index</a> &nbsp; &nbsp;
+            <a id="nextFileLink" class="nav" href="{{ next_html }}">&#xbb; next</a>
+            &nbsp; &nbsp; &nbsp;
+            <a class="nav" href="{{__url__}}">coverage.py v{{__version__}}</a>,
+            created at {{ time_stamp }}
+        </p>
+
+        <aside class="hidden">
+            <button type="button" class="button_next_chunk" data-shortcut="j"/>
+            <button type="button" class="button_prev_chunk" data-shortcut="k"/>
+            <button type="button" class="button_top_of_page" data-shortcut="0"/>
+            <button type="button" class="button_first_chunk" data-shortcut="1"/>
+            <button type="button" class="button_prev_file" data-shortcut="["/>
+            <button type="button" class="button_next_file" data-shortcut="]"/>
+            <button type="button" class="button_to_index" data-shortcut="u"/>
+            <button type="button" class="button_show_hide_help" data-shortcut="?"/>
+        </aside>
     </div>
 </header>
 
@@ -110,7 +132,11 @@
 <footer>
     <div class="content">
         <p>
-            <a class="nav" href="index.html">&#xab; index</a> &nbsp; &nbsp; <a class="nav" href="{{__url__}}">coverage.py v{{__version__}}</a>,
+            <a id="prevFileLink" class="nav" href="{{ prev_html }}">&#xab; prev</a> &nbsp; &nbsp;
+            <a id="indexLink" class="nav" href="index.html">&Hat; index</a> &nbsp; &nbsp;
+            <a id="nextFileLink" class="nav" href="{{ next_html }}">&#xbb; next</a>
+            &nbsp; &nbsp; &nbsp;
+            <a class="nav" href="{{__url__}}">coverage.py v{{__version__}}</a>,
             created at {{ time_stamp }}
         </p>
     </div>
--- a/eric7/DebugClients/Python/coverage/htmlfiles/style.css	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/htmlfiles/style.css	Wed Jun 01 13:48:49 2022 +0200
@@ -28,6 +28,8 @@
 
 a.nav:hover { text-decoration: underline; color: inherit; }
 
+.hidden { display: none; }
+
 header { background: #f8f8f8; width: 100%; z-index: 2; border-bottom: 1px solid #ccc; }
 
 @media (prefers-color-scheme: dark) { header { background: black; } }
@@ -38,6 +40,10 @@
 
 header h2 { margin-top: .5em; font-size: 1em; }
 
+header p.text { margin: .5em 0 -.5em; color: #666; font-style: italic; }
+
+@media (prefers-color-scheme: dark) { header p.text { color: #aaa; } }
+
 header.sticky { position: fixed; left: 0; right: 0; height: 2.5em; }
 
 header.sticky .text { display: none; }
@@ -52,9 +58,7 @@
 
 main { position: relative; z-index: 1; }
 
-.indexfile footer { margin: 1rem 3.5rem; }
-
-.pyfile footer { margin: 1rem 1rem; }
+footer { margin: 1rem 3.5rem; }
 
 footer .content { padding: 0; color: #666; font-style: italic; }
 
@@ -124,7 +128,9 @@
 
 #help_panel_state { display: none; }
 
-#help_panel { top: 25px; right: 0; padding: .75em; border: 1px solid #883; }
+#help_panel { top: 25px; right: 0; padding: .75em; border: 1px solid #883; color: #333; }
+
+#help_panel .keyhelp p { margin-top: .75em; }
 
 #help_panel .legend { font-style: italic; margin-bottom: 1em; }
 
@@ -134,8 +140,6 @@
 
 #help_panel_state:checked ~ #help_panel { display: block; }
 
-.keyhelp { margin-top: .75em; }
-
 kbd { border: 1px solid black; border-color: #888 #333 #333 #888; padding: .1em .35em; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; font-weight: bold; background: #eee; border-radius: 3px; }
 
 #source { padding: 1em 0 1em 3.5rem; font-family: SFMono-Regular, Menlo, Monaco, Consolas, monospace; }
--- a/eric7/DebugClients/Python/coverage/htmlfiles/style.scss	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/htmlfiles/style.scss	Wed Jun 01 13:48:49 2022 +0200
@@ -156,6 +156,10 @@
     }
 }
 
+.hidden {
+    display: none;
+}
+
 // Page structure
 header {
     background: $light-gray1;
@@ -174,6 +178,13 @@
         font-size: 1em;
     }
 
+    p.text {
+        margin: .5em 0 -.5em;
+        color: $light-gray5;
+        @include color-dark($dark-gray5);
+        font-style: italic;
+    }
+
     &.sticky {
         position: fixed;
         left: 0;
@@ -208,19 +219,15 @@
     z-index: 1;
 }
 
-.indexfile footer {
+footer {
     margin: 1rem $left-gutter;
-}
 
-.pyfile footer {
-    margin: 1rem 1rem;
-}
-
-footer .content {
-    padding: 0;
-    color: $light-gray5;
-    @include color-dark($dark-gray5);
-    font-style: italic;
+    .content {
+        padding: 0;
+        color: $light-gray5;
+        @include color-dark($dark-gray5);
+        font-style: italic;
+    }
 }
 
 #index {
@@ -351,6 +358,12 @@
     padding: .75em;
     border: 1px solid #883;
 
+    color: #333;
+
+    .keyhelp p {
+        margin-top: .75em;
+    }
+
     .legend {
         font-style: italic;
         margin-bottom: 1em;
@@ -358,12 +371,10 @@
 
     .indexfile & {
         width: 25em;
-        //min-height: 4em;
     }
 
     .pyfile & {
         width: 18em;
-        //min-height: 8em;
     }
 
     #help_panel_state:checked ~ & {
@@ -371,10 +382,6 @@
     }
 }
 
-.keyhelp {
-    margin-top: .75em;
-}
-
 kbd {
     border: 1px solid black;
     border-color: #888 #333 #333 #888;
--- a/eric7/DebugClients/Python/coverage/inorout.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/inorout.py	Wed Jun 01 13:48:49 2022 +0200
@@ -591,7 +591,7 @@
             'source_match', 'source_pkgs_match',
             'include_match', 'omit_match',
             'cover_match', 'pylib_match', 'third_match',
-            ]
+        ]
 
         for matcher_name in matcher_names:
             matcher = getattr(self, matcher_name)
--- a/eric7/DebugClients/Python/coverage/jsonreport.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/jsonreport.py	Wed Jun 01 13:48:49 2022 +0200
@@ -70,7 +70,7 @@
         json.dump(
             self.report_data,
             outfile,
-            indent=4 if self.config.json_pretty_print else None
+            indent=(4 if self.config.json_pretty_print else None),
         )
 
         return self.total.n_statements and self.total.pc_covered
--- a/eric7/DebugClients/Python/coverage/misc.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/misc.py	Wed Jun 01 13:48:49 2022 +0200
@@ -272,7 +272,7 @@
 
     raise NotImplementedError(
         f"{thing} {name!r} needs to implement {func_name}()"
-        )
+    )
 
 
 class DefaultValue:
--- a/eric7/DebugClients/Python/coverage/parser.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/parser.py	Wed Jun 01 13:48:49 2022 +0200
@@ -1231,15 +1231,15 @@
             if with_block.break_from:
                 self.process_break_exits(
                     self._combine_finally_starts(with_block.break_from, with_exit)
-                    )
+                )
             if with_block.continue_from:
                 self.process_continue_exits(
                     self._combine_finally_starts(with_block.continue_from, with_exit)
-                    )
+                )
             if with_block.return_from:
                 self.process_return_exits(
                     self._combine_finally_starts(with_block.return_from, with_exit)
-                    )
+                )
         return exits
 
     _handle__AsyncWith = _handle__With
@@ -1287,6 +1287,7 @@
             self.add_arc(start, -start, None, f"didn't finish the {noun} on line {start}")
         return _code_object__expression_callable
 
+    # pylint: disable=too-many-function-args
     _code_object__Lambda = _make_expression_code_method("lambda")
     _code_object__GeneratorExp = _make_expression_code_method("generator expression")
     _code_object__DictComp = _make_expression_code_method("dictionary comprehension")
--- a/eric7/DebugClients/Python/coverage/phystokens.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/phystokens.py	Wed Jun 01 13:48:49 2022 +0200
@@ -60,7 +60,7 @@
                         99999, "\\\n",
                         (slineno, ccol), (slineno, ccol+2),
                         last_line
-                        )
+                    )
             last_line = ltext
         if ttype not in (tokenize.NEWLINE, tokenize.NL):
             last_ttext = ttext
--- a/eric7/DebugClients/Python/coverage/python.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/python.py	Wed Jun 01 13:48:49 2022 +0200
@@ -202,8 +202,8 @@
     def no_branch_lines(self):
         no_branch = self.parser.lines_matching(
             join_regex(self.coverage.config.partial_list),
-            join_regex(self.coverage.config.partial_always_list)
-            )
+            join_regex(self.coverage.config.partial_always_list),
+        )
         return no_branch
 
     @expensive
--- a/eric7/DebugClients/Python/coverage/results.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/results.py	Wed Jun 01 13:48:49 2022 +0200
@@ -271,10 +271,10 @@
         nums.n_branches = self.n_branches + other.n_branches
         nums.n_partial_branches = (
             self.n_partial_branches + other.n_partial_branches
-            )
+        )
         nums.n_missing_branches = (
             self.n_missing_branches + other.n_missing_branches
-            )
+        )
         return nums
 
     def __radd__(self, other):
--- a/eric7/DebugClients/Python/coverage/sqldata.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/sqldata.py	Wed Jun 01 13:48:49 2022 +0200
@@ -1,10 +1,7 @@
 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt
 
-"""Sqlite coverage data."""
-
-# TODO: factor out dataop debugging to a wrapper class?
-# TODO: make sure all dataop debugging is in place somehow
+"""SQLite coverage data."""
 
 import collections
 import datetime
@@ -17,6 +14,7 @@
 import socket
 import sqlite3
 import sys
+import textwrap
 import threading
 import zlib
 
@@ -30,7 +28,7 @@
 os = isolate_module(os)
 
 # If you change the schema, increment the SCHEMA_VERSION, and update the
-# docs in docs/dbschema.rst also.
+# docs in docs/dbschema.rst by running "make cogdoc".
 
 SCHEMA_VERSION = 7
 
@@ -252,10 +250,10 @@
 
     def _reset(self):
         """Reset our attributes."""
-        if self._dbs:
+        if not self._no_disk:
             for db in self._dbs.values():
                 db.close()
-        self._dbs = {}
+            self._dbs = {}
         self._file_map = {}
         self._have_used = False
         self._current_context_id = None
@@ -293,7 +291,7 @@
                 self._has_arcs = bool(int(row[0]))
                 self._has_lines = not self._has_arcs
 
-            for path, file_id in db.execute("select path, id from file"):
+            for file_id, path in db.execute("select id, path from file"):
                 self._file_map[path] = file_id
 
     def _init_db(self, db):
@@ -389,8 +387,10 @@
         if filename not in self._file_map:
             if add:
                 with self._connect() as con:
-                    cur = con.execute("insert or replace into file (path) values (?)", (filename,))
-                    self._file_map[filename] = cur.lastrowid
+                    self._file_map[filename] = con.execute_for_rowid(
+                        "insert or replace into file (path) values (?)",
+                        (filename,)
+                    )
         return self._file_map.get(filename)
 
     def _context_id(self, context):
@@ -427,8 +427,10 @@
             self._current_context_id = context_id
         else:
             with self._connect() as con:
-                cur = con.execute("insert into context (context) values (?)", (context,))
-                self._current_context_id = cur.lastrowid
+                self._current_context_id = con.execute_for_rowid(
+                    "insert into context (context) values (?)",
+                    (context,)
+                )
 
     def base_filename(self):
         """The base filename for storing data.
@@ -501,9 +503,6 @@
             self._set_context_id()
             for filename, arcs in arc_data.items():
                 file_id = self._file_id(filename, add=True)
-                from coverage import env
-                if env.PYVERSION == (3, 11, 0, "alpha", 4, 0):
-                    arcs = [(a, b) for a, b in arcs if a is not None and b is not None]
                 data = [(file_id, self._current_context_id, fromno, tono) for fromno, tono in arcs]
                 con.executemany(
                     "insert or ignore into arc " +
@@ -616,19 +615,19 @@
 
         # Collector for all arcs, lines and tracers
         other_data.read()
-        with other_data._connect() as conn:
+        with other_data._connect() as con:
             # Get files data.
-            cur = conn.execute("select path from file")
+            cur = con.execute("select path from file")
             files = {path: aliases.map(path) for (path,) in cur}
             cur.close()
 
             # Get contexts data.
-            cur = conn.execute("select context from context")
+            cur = con.execute("select context from context")
             contexts = [context for (context,) in cur]
             cur.close()
 
             # Get arc data.
-            cur = conn.execute(
+            cur = con.execute(
                 "select file.path, context.context, arc.fromno, arc.tono " +
                 "from arc " +
                 "inner join file on file.id = arc.file_id " +
@@ -638,17 +637,17 @@
             cur.close()
 
             # Get line data.
-            cur = conn.execute(
+            cur = con.execute(
                 "select file.path, context.context, line_bits.numbits " +
                 "from line_bits " +
                 "inner join file on file.id = line_bits.file_id " +
                 "inner join context on context.id = line_bits.context_id"
-                )
+            )
             lines = {(files[path], context): numbits for (path, context, numbits) in cur}
             cur.close()
 
             # Get tracer data.
-            cur = conn.execute(
+            cur = con.execute(
                 "select file.path, tracer " +
                 "from tracer " +
                 "inner join file on file.id = tracer.file_id"
@@ -656,38 +655,39 @@
             tracers = {files[path]: tracer for (path, tracer) in cur}
             cur.close()
 
-        with self._connect() as conn:
-            conn.con.isolation_level = "IMMEDIATE"
+        with self._connect() as con:
+            con.con.isolation_level = "IMMEDIATE"
 
             # Get all tracers in the DB. Files not in the tracers are assumed
             # to have an empty string tracer. Since Sqlite does not support
             # full outer joins, we have to make two queries to fill the
             # dictionary.
-            this_tracers = {path: "" for path, in conn.execute("select path from file")}
+            this_tracers = {path: "" for path, in con.execute("select path from file")}
             this_tracers.update({
                 aliases.map(path): tracer
-                for path, tracer in conn.execute(
+                for path, tracer in con.execute(
                     "select file.path, tracer from tracer " +
                     "inner join file on file.id = tracer.file_id"
                 )
             })
 
             # Create all file and context rows in the DB.
-            conn.executemany(
+            con.executemany(
                 "insert or ignore into file (path) values (?)",
                 ((file,) for file in files.values())
             )
             file_ids = {
                 path: id
-                for id, path in conn.execute("select id, path from file")
+                for id, path in con.execute("select id, path from file")
             }
-            conn.executemany(
+            self._file_map.update(file_ids)
+            con.executemany(
                 "insert or ignore into context (context) values (?)",
                 ((context,) for context in contexts)
             )
             context_ids = {
                 context: id
-                for id, context in conn.execute("select id, context from context")
+                for id, context in con.execute("select id, context from context")
             }
 
             # Prepare tracers and fail, if a conflict is found.
@@ -715,12 +715,12 @@
             )
 
             # Get line data.
-            cur = conn.execute(
+            cur = con.execute(
                 "select file.path, context.context, line_bits.numbits " +
                 "from line_bits " +
                 "inner join file on file.id = line_bits.file_id " +
                 "inner join context on context.id = line_bits.context_id"
-                )
+            )
             for path, context, numbits in cur:
                 key = (aliases.map(path), context)
                 if key in lines:
@@ -732,7 +732,7 @@
                 self._choose_lines_or_arcs(arcs=True)
 
                 # Write the combined data.
-                conn.executemany(
+                con.executemany(
                     "insert or ignore into arc " +
                     "(file_id, context_id, fromno, tono) values (?, ?, ?, ?)",
                     arc_rows
@@ -740,8 +740,8 @@
 
             if lines:
                 self._choose_lines_or_arcs(lines=True)
-                conn.execute("delete from line_bits")
-                conn.executemany(
+                con.execute("delete from line_bits")
+                con.executemany(
                     "insert into line_bits " +
                     "(file_id, context_id, numbits) values (?, ?, ?)",
                     [
@@ -749,14 +749,15 @@
                         for (file, context), numbits in lines.items()
                     ]
                 )
-            conn.executemany(
+            con.executemany(
                 "insert or ignore into tracer (file_id, tracer) values (?, ?)",
                 ((file_ids[filename], tracer) for filename, tracer in tracer_map.items())
             )
 
-        # Update all internal cache data.
-        self._reset()
-        self.read()
+        if not self._no_disk:
+            # Update all internal cache data.
+            self._reset()
+            self.read()
 
     def erase(self, parallel=False):
         """Erase the data in this object.
@@ -782,8 +783,9 @@
 
     def read(self):
         """Start using an existing data file."""
-        with self._connect():       # TODO: doesn't look right
-            self._have_used = True
+        if os.path.exists(self._filename):
+            with self._connect():
+                self._have_used = True
 
     def write(self):
         """Ensure the data is written to the data file."""
@@ -977,7 +979,7 @@
                     "select l.numbits, c.context from line_bits l, context c " +
                     "where l.context_id = c.id " +
                     "and file_id = ?"
-                    )
+                )
                 data = [file_id]
                 if self._query_context_ids is not None:
                     ids_array = ", ".join("?" * len(self._query_context_ids))
@@ -999,9 +1001,7 @@
         with SqliteDb(":memory:", debug=NoDebugging()) as db:
             temp_store = [row[0] for row in db.execute("pragma temp_store")]
             copts = [row[0] for row in db.execute("pragma compile_options")]
-            # Yes, this is overkill. I don't like the long list of options
-            # at the end of "debug sys", but I don't want to omit information.
-            copts = ["; ".join(copts[i:i + 3]) for i in range(0, len(copts), 3)]
+            copts = textwrap.wrap(", ".join(copts), width=75)
 
         return [
             ("sqlite3_version", sqlite3.version),
@@ -1042,7 +1042,7 @@
 
     """
     def __init__(self, filename, debug):
-        self.debug = debug if debug.should("sql") else None
+        self.debug = debug
         self.filename = filename
         self.nest = 0
         self.con = None
@@ -1057,7 +1057,7 @@
         # effectively causing a nested context. However, given the idempotent
         # nature of the tracer operations, sharing a connection among threads
         # is not a problem.
-        if self.debug:
+        if self.debug.should("sql"):
             self.debug.write(f"Connecting to {self.filename!r}")
         try:
             self.con = sqlite3.connect(self.filename, check_same_thread=False)
@@ -1093,13 +1093,13 @@
                 self.con.__exit__(exc_type, exc_value, traceback)
                 self.close()
             except Exception as exc:
-                if self.debug:
+                if self.debug.should("sql"):
                     self.debug.write(f"EXCEPTION from __exit__: {exc}")
                 raise DataError(f"Couldn't end data file {self.filename!r}: {exc}") from exc
 
     def execute(self, sql, parameters=()):
         """Same as :meth:`python:sqlite3.Connection.execute`."""
-        if self.debug:
+        if self.debug.should("sql"):
             tail = f" with {parameters!r}" if parameters else ""
             self.debug.write(f"Executing {sql!r}{tail}")
         try:
@@ -1124,10 +1124,18 @@
                         )
             except Exception:   # pragma: cant happen
                 pass
-            if self.debug:
+            if self.debug.should("sql"):
                 self.debug.write(f"EXCEPTION from execute: {msg}")
             raise DataError(f"Couldn't use data file {self.filename!r}: {msg}") from exc
 
+    def execute_for_rowid(self, sql, parameters=()):
+        """Like execute, but returns the lastrowid."""
+        con = self.execute(sql, parameters)
+        rowid = con.lastrowid
+        if self.debug.should("sqldata"):
+            self.debug.write(f"Row id result: {rowid!r}")
+        return rowid
+
     def execute_one(self, sql, parameters=()):
         """Execute a statement and return the one row that results.
 
@@ -1147,9 +1155,13 @@
 
     def executemany(self, sql, data):
         """Same as :meth:`python:sqlite3.Connection.executemany`."""
-        if self.debug:
+        if self.debug.should("sql"):
             data = list(data)
-            self.debug.write(f"Executing many {sql!r} with {len(data)} rows")
+            final = ":" if self.debug.should("sqldata") else ""
+            self.debug.write(f"Executing many {sql!r} with {len(data)} rows{final}")
+            if self.debug.should("sqldata"):
+                for i, row in enumerate(data):
+                    self.debug.write(f"{i:4d}: {row!r}")
         try:
             return self.con.executemany(sql, data)
         except Exception:   # pragma: cant happen
@@ -1160,7 +1172,7 @@
 
     def executescript(self, script):
         """Same as :meth:`python:sqlite3.Connection.executescript`."""
-        if self.debug:
+        if self.debug.should("sql"):
             self.debug.write("Executing script with {} chars: {}".format(
                 len(script), clipped_repr(script, 100),
             ))
--- a/eric7/DebugClients/Python/coverage/summary.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/summary.py	Wed Jun 01 13:48:49 2022 +0200
@@ -127,11 +127,11 @@
         if self.config.skip_covered and self.skipped_count:
             self.writeout(
                 fmt_skip_covered % (self.skipped_count, 's' if self.skipped_count > 1 else '')
-                )
+            )
         if self.config.skip_empty and self.empty_count:
             self.writeout(
                 fmt_skip_empty % (self.empty_count, 's' if self.empty_count > 1 else '')
-                )
+            )
 
         return self.total.n_statements and self.total.pc_covered
 
--- a/eric7/DebugClients/Python/coverage/tomlconfig.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/tomlconfig.py	Wed Jun 01 13:48:49 2022 +0200
@@ -7,15 +7,21 @@
 import os
 import re
 
+from coverage import env
 from coverage.exceptions import ConfigError
 from coverage.misc import import_third_party, substitute_variables
 
-# TOML support is an install-time extra option. (Import typing is here because
-# import_third_party will unload any module that wasn't already imported.
-# tomli imports typing, and if we unload it, later it's imported again, and on
-# Python 3.6, this causes infinite recursion.)
-import typing   # pylint: disable=unused-import, wrong-import-order
-tomli = import_third_party("tomli")
+
+if env.PYVERSION >= (3, 11):
+    import tomllib      # pylint: disable=import-error
+else:
+    # TOML support on Python 3.10 and below is an install-time extra option.
+    # (Import typing is here because import_third_party will unload any module
+    # that wasn't already imported. tomli imports typing, and if we unload it,
+    # later it's imported again, and on Python 3.6, this causes infinite
+    # recursion.)
+    import typing   # pylint: disable=unused-import
+    tomllib = import_third_party("tomli")
 
 
 class TomlDecodeError(Exception):
@@ -45,11 +51,11 @@
                 toml_text = fp.read()
         except OSError:
             return []
-        if tomli is not None:
+        if tomllib is not None:
             toml_text = substitute_variables(toml_text, os.environ)
             try:
-                self.data = tomli.loads(toml_text)
-            except tomli.TOMLDecodeError as err:
+                self.data = tomllib.loads(toml_text)
+            except tomllib.TOMLDecodeError as err:
                 raise TomlDecodeError(str(err)) from err
             return [filename]
         else:
--- a/eric7/DebugClients/Python/coverage/version.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/version.py	Wed Jun 01 13:48:49 2022 +0200
@@ -5,7 +5,7 @@
 # This file is exec'ed in setup.py, don't import anything!
 
 # Same semantics as sys.version_info.
-version_info = (6, 3, 2, "final", 0)
+version_info = (6, 4, 0, "final", 0)
 
 
 def _make_version(major, minor, micro, releaselevel, serial):
--- a/eric7/DebugClients/Python/coverage/xmlreport.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/DebugClients/Python/coverage/xmlreport.py	Wed Jun 01 13:48:49 2022 +0200
@@ -68,7 +68,7 @@
         xcoverage.setAttribute("timestamp", str(int(time.time()*1000)))
         xcoverage.appendChild(self.xml_out.createComment(
             f" Generated by coverage.py: {__url__} "
-            ))
+        ))
         xcoverage.appendChild(self.xml_out.createComment(f" Based on {DTD_URL} "))
 
         # Call xml_file for each file in the data.
@@ -193,7 +193,7 @@
                     xline.setAttribute(
                         "condition-coverage",
                         "%d%% (%d/%d)" % (100*taken//total, taken, total)
-                        )
+                    )
                 if line in missing_branch_arcs:
                     annlines = ["exit" if b < 0 else str(b) for b in missing_branch_arcs[line]]
                     xline.setAttribute("missing-branches", ",".join(annlines))
--- a/eric7/Debugger/DebugClientCapabilities.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Debugger/DebugClientCapabilities.py	Wed Jun 01 13:48:49 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	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Debugger/DebugServer.py	Wed Jun 01 13:48:49 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)
@@ -526,9 +497,12 @@
         # only start the client, if we are not in passive mode
         if not self.passive:
             if self.clientProcess:
-                self.clientProcess.kill()
-                self.clientProcess.waitForFinished(1000)
-                self.clientProcess.deleteLater()
+                with contextlib.suppress(RuntimeError):
+                    # Workaround: The wrapped C/C++ object of type QProcess
+                    # gets deleted prematurely sometimes.
+                    self.clientProcess.kill()
+                    self.clientProcess.waitForFinished(1000)
+                    self.clientProcess.deleteLater()
                 self.clientProcess = None
             
             self.__forProject = forProject
@@ -1539,137 +1513,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 +1879,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	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Debugger/DebuggerInterfaceNone.py	Wed Jun 01 13:48:49 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	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Debugger/DebuggerInterfacePython.py	Wed Jun 01 13:48:49 2022 +0200
@@ -366,10 +366,6 @@
         
         # start debugger with project specific settings
         debugClient = project.getDebugProperty("DEBUGCLIENT")
-        if not venvName:
-            venvName = project.getDebugProperty("VIRTUALENV")
-        if not venvName and project.getProjectLanguage() == "Python3":
-            venvName = Preferences.getDebugger("Python3VirtualEnv")
         
         redirect = (
             str(configOverride["redirect"])
@@ -384,14 +380,8 @@
             else ''
         )
         
-        venvManager = ericApp().getObject("VirtualEnvManager")
-        interpreter = venvManager.getVirtualenvInterpreter(venvName)
-        execPath = venvManager.getVirtualenvExecPath(venvName)
-        if (
-            interpreter == "" and
-            project.getProjectLanguage().startswith("Python")
-        ):
-            interpreter = Globals.getPythonExecutable()
+        execPath = project.getProjectExecPath()
+        interpreter = project.getProjectInterpreter()
         if interpreter == "":
             EricMessageBox.critical(
                 None,
@@ -1215,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.
@@ -1519,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/StartDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Debugger/StartDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -322,11 +322,11 @@
         histories = [
             "",
             self.tr("Script Name"),
-            self.tr("Command Line"),
+            self.tr("Script Parameters"),
             self.tr("Working Directory"),
             self.tr("Environment"),
         ]
-        combos = [
+        widgets = [
             None,
             self.ui.scriptnamePicker,
             self.ui.cmdlineCombo,
@@ -335,7 +335,7 @@
         ]
         if self.dialogType == 0:
             histories.append(self.tr("No Debug Programs"))
-            combos.append(self.ui.multiprocessNoDebugCombo)
+            widgets.append(self.ui.multiprocessNoDebugCombo)
         historyKind, ok = QInputDialog.getItem(
             self,
             self.tr("Edit History"),
@@ -345,22 +345,22 @@
         if ok and historyKind:
             history = []
             historiesIndex = histories.index(historyKind)
-            if historiesIndex == 1:
-                history = self.ui.scriptnamePicker.getPathItems()
-            elif historiesIndex == 3:
-                history = self.ui.workdirPicker.getPathItems()
+            if historiesIndex in (1, 3):
+                picker = widgets[historiesIndex]
+                history = picker.getPathItems()
             else:
-                combo = combos[historiesIndex]
+                combo = widgets[historiesIndex]
                 if combo:
-                    for index in range(combo.count()):
-                        history.append(combo.itemText(index))
+                    history = [
+                        combo.itemText(idx) for idx in range(combo.count())
+                    ]
             
             if history:
                 from .StartHistoryEditDialog import StartHistoryEditDialog
                 dlg = StartHistoryEditDialog(history, self)
             if dlg.exec() == QDialog.DialogCode.Accepted:
                 history = dlg.getHistory()
-                combo = combos[historiesIndex]
+                combo = widgets[historiesIndex]
                 if combo:
                     combo.clear()
                     combo.addItems(history)
@@ -403,7 +403,7 @@
             None
         )
         return (
-            self.ui.scriptnamePicker.getPathNames(),
+            self.ui.scriptnamePicker.getPathItems(),
             [self.ui.cmdlineCombo.itemText(index) for index in range(
                 self.ui.cmdlineCombo.count())],
             self.ui.workdirPicker.getPathItems(),
Binary file eric7/Documentation/Help/source.qch has changed
--- a/eric7/Documentation/Help/source.qhp	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Help/source.qhp	Wed Jun 01 13:48:49 2022 +0200
@@ -32,13 +32,14 @@
             <section title="eric7.DataViews.CodeMetrics" ref="eric7.DataViews.CodeMetrics.html" />
             <section title="eric7.DataViews.CodeMetricsDialog" ref="eric7.DataViews.CodeMetricsDialog.html" />
             <section title="eric7.DataViews.PyCoverageDialog" ref="eric7.DataViews.PyCoverageDialog.html" />
+            <section title="eric7.DataViews.PyCoverageHtmlReportDialog" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html" />
+            <section title="eric7.DataViews.PyCoverageJsonReportDialog" ref="eric7.DataViews.PyCoverageJsonReportDialog.html" />
             <section title="eric7.DataViews.PyProfileDialog" ref="eric7.DataViews.PyProfileDialog.html" />
           </section>
           <section title="eric7.DebugClients" ref="index-eric7.DebugClients.html">
             <section title="eric7.DebugClients.Python" ref="index-eric7.DebugClients.Python.html">
               <section title="eric7.DebugClients.Python.AsyncFile" ref="eric7.DebugClients.Python.AsyncFile.html" />
               <section title="eric7.DebugClients.Python.BreakpointWatch" ref="eric7.DebugClients.Python.BreakpointWatch.html" />
-              <section title="eric7.DebugClients.Python.DCTestResult" ref="eric7.DebugClients.Python.DCTestResult.html" />
               <section title="eric7.DebugClients.Python.DebugBase" ref="eric7.DebugClients.Python.DebugBase.html" />
               <section title="eric7.DebugClients.Python.DebugClient" ref="eric7.DebugClients.Python.DebugClient.html" />
               <section title="eric7.DebugClients.Python.DebugClientBase" ref="eric7.DebugClients.Python.DebugClientBase.html" />
@@ -110,6 +111,8 @@
             <section title="eric7.EricNetwork.EricGoogleMailHelpers" ref="eric7.EricNetwork.EricGoogleMailHelpers.html" />
             <section title="eric7.EricNetwork.EricJsonClient" ref="eric7.EricNetwork.EricJsonClient.html" />
             <section title="eric7.EricNetwork.EricJsonServer" ref="eric7.EricNetwork.EricJsonServer.html" />
+            <section title="eric7.EricNetwork.EricJsonStreamReader" ref="eric7.EricNetwork.EricJsonStreamReader.html" />
+            <section title="eric7.EricNetwork.EricJsonStreamWriter" ref="eric7.EricNetwork.EricJsonStreamWriter.html" />
             <section title="eric7.EricNetwork.EricNetworkIcon" ref="eric7.EricNetwork.EricNetworkIcon.html" />
             <section title="eric7.EricNetwork.EricNetworkProxyFactory" ref="eric7.EricNetwork.EricNetworkProxyFactory.html" />
             <section title="eric7.EricNetwork.EricSslCertificateSelectionDialog" ref="eric7.EricNetwork.EricSslCertificateSelectionDialog.html" />
@@ -907,9 +910,6 @@
             <section title="eric7.Project.UserProjectFile" ref="eric7.Project.UserProjectFile.html" />
             <section title="eric7.Project.UserPropertiesDialog" ref="eric7.Project.UserPropertiesDialog.html" />
           </section>
-          <section title="eric7.PyUnit" ref="index-eric7.PyUnit.html">
-            <section title="eric7.PyUnit.UnittestDialog" ref="eric7.PyUnit.UnittestDialog.html" />
-          </section>
           <section title="eric7.QScintilla" ref="index-eric7.QScintilla.html">
             <section title="eric7.QScintilla.DocstringGenerator" ref="index-eric7.QScintilla.DocstringGenerator.html">
               <section title="eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator" ref="eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator.html" />
@@ -1045,6 +1045,19 @@
             <section title="eric7.Templates.TemplateViewer" ref="eric7.Templates.TemplateViewer.html" />
             <section title="eric7.Templates.TemplatesFile" ref="eric7.Templates.TemplatesFile.html" />
           </section>
+          <section title="eric7.Testing" ref="index-eric7.Testing.html">
+            <section title="eric7.Testing.Interfaces" ref="index-eric7.Testing.Interfaces.html">
+              <section title="eric7.Testing.Interfaces.PytestExecutor" ref="eric7.Testing.Interfaces.PytestExecutor.html" />
+              <section title="eric7.Testing.Interfaces.PytestRunner" ref="eric7.Testing.Interfaces.PytestRunner.html" />
+              <section title="eric7.Testing.Interfaces.TestExecutorBase" ref="eric7.Testing.Interfaces.TestExecutorBase.html" />
+              <section title="eric7.Testing.Interfaces.TestFrameworkRegistry" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html" />
+              <section title="eric7.Testing.Interfaces.UnittestExecutor" ref="eric7.Testing.Interfaces.UnittestExecutor.html" />
+              <section title="eric7.Testing.Interfaces.UnittestRunner" ref="eric7.Testing.Interfaces.UnittestRunner.html" />
+            </section>
+            <section title="eric7.Testing.TestResultsTree" ref="eric7.Testing.TestResultsTree.html" />
+            <section title="eric7.Testing.TestingWidget" ref="eric7.Testing.TestingWidget.html" />
+            <section title="eric7.Testing.__init__" ref="eric7.Testing.__init__.html" />
+          </section>
           <section title="eric7.Toolbox" ref="index-eric7.Toolbox.html">
             <section title="eric7.Toolbox.SingleApplication" ref="eric7.Toolbox.SingleApplication.html" />
             <section title="eric7.Toolbox.Startup" ref="eric7.Toolbox.Startup.html" />
@@ -1428,10 +1441,10 @@
           <section title="eric7.eric7_shell" ref="eric7.eric7_shell.html" />
           <section title="eric7.eric7_snap" ref="eric7.eric7_snap.html" />
           <section title="eric7.eric7_sqlbrowser" ref="eric7.eric7_sqlbrowser.html" />
+          <section title="eric7.eric7_testing" ref="eric7.eric7_testing.html" />
           <section title="eric7.eric7_tray" ref="eric7.eric7_tray.html" />
           <section title="eric7.eric7_trpreviewer" ref="eric7.eric7_trpreviewer.html" />
           <section title="eric7.eric7_uipreviewer" ref="eric7.eric7_uipreviewer.html" />
-          <section title="eric7.eric7_unittest" ref="eric7.eric7_unittest.html" />
           <section title="eric7.eric7_virtualenv" ref="eric7.eric7_virtualenv.html" />
           <section title="eric7.eric7config" ref="eric7.eric7config.html" />
         </section>
@@ -2285,7 +2298,7 @@
       <keyword name="Browser.handleInterpreterChanged" id="Browser.handleInterpreterChanged" ref="eric7.UI.Browser.html#Browser.handleInterpreterChanged" />
       <keyword name="Browser.handlePreferencesChanged" id="Browser.handlePreferencesChanged" ref="eric7.UI.Browser.html#Browser.handlePreferencesChanged" />
       <keyword name="Browser.handleProgramChange" id="Browser.handleProgramChange" ref="eric7.UI.Browser.html#Browser.handleProgramChange" />
-      <keyword name="Browser.handleUnittest" id="Browser.handleUnittest" ref="eric7.UI.Browser.html#Browser.handleUnittest" />
+      <keyword name="Browser.handleTesting" id="Browser.handleTesting" ref="eric7.UI.Browser.html#Browser.handleTesting" />
       <keyword name="Browser.keyboardSearch" id="Browser.keyboardSearch" ref="eric7.UI.Browser.html#Browser.keyboardSearch" />
       <keyword name="Browser.layoutDisplay" id="Browser.layoutDisplay" ref="eric7.UI.Browser.html#Browser.layoutDisplay" />
       <keyword name="Browser.mouseDoubleClickEvent" id="Browser.mouseDoubleClickEvent" ref="eric7.UI.Browser.html#Browser.mouseDoubleClickEvent" />
@@ -3274,17 +3287,6 @@
       <keyword name="CustomHelpFormatter._format_action" id="CustomHelpFormatter._format_action" ref="eric7.PipInterface.piplicenses.html#CustomHelpFormatter._format_action" />
       <keyword name="CustomHelpFormatter._split_lines" id="CustomHelpFormatter._split_lines" ref="eric7.PipInterface.piplicenses.html#CustomHelpFormatter._split_lines" />
       <keyword name="CustomNamespace" id="CustomNamespace" ref="eric7.PipInterface.piplicenses.html#CustomNamespace" />
-      <keyword name="DCTestResult" id="DCTestResult" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult" />
-      <keyword name="DCTestResult (Constructor)" id="DCTestResult (Constructor)" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.__init__" />
-      <keyword name="DCTestResult (Module)" id="DCTestResult (Module)" ref="eric7.DebugClients.Python.DCTestResult.html" />
-      <keyword name="DCTestResult.addError" id="DCTestResult.addError" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addError" />
-      <keyword name="DCTestResult.addExpectedFailure" id="DCTestResult.addExpectedFailure" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addExpectedFailure" />
-      <keyword name="DCTestResult.addFailure" id="DCTestResult.addFailure" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addFailure" />
-      <keyword name="DCTestResult.addSkip" id="DCTestResult.addSkip" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addSkip" />
-      <keyword name="DCTestResult.addSubTest" id="DCTestResult.addSubTest" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addSubTest" />
-      <keyword name="DCTestResult.addUnexpectedSuccess" id="DCTestResult.addUnexpectedSuccess" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.addUnexpectedSuccess" />
-      <keyword name="DCTestResult.startTest" id="DCTestResult.startTest" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.startTest" />
-      <keyword name="DCTestResult.stopTest" id="DCTestResult.stopTest" ref="eric7.DebugClients.Python.DCTestResult.html#DCTestResult.stopTest" />
       <keyword name="DataViews (Package)" id="DataViews (Package)" ref="index-eric7.DataViews.html" />
       <keyword name="DateTimeVisitor" id="DateTimeVisitor" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DateTimeVisitor" />
       <keyword name="DateTimeVisitor (Constructor)" id="DateTimeVisitor (Constructor)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#DateTimeVisitor.__init__" />
@@ -3337,7 +3339,6 @@
       <keyword name="DebugClientBase" id="DebugClientBase" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase" />
       <keyword name="DebugClientBase (Constructor)" id="DebugClientBase (Constructor)" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase.__init__" />
       <keyword name="DebugClientBase (Module)" id="DebugClientBase (Module)" ref="eric7.DebugClients.Python.DebugClientBase.html" />
-      <keyword name="DebugClientBase.__assembleTestCasesList" id="DebugClientBase.__assembleTestCasesList" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase.__assembleTestCasesList" />
       <keyword name="DebugClientBase.__clientCapabilities" id="DebugClientBase.__clientCapabilities" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase.__clientCapabilities" />
       <keyword name="DebugClientBase.__compileCommand" id="DebugClientBase.__compileCommand" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase.__compileCommand" />
       <keyword name="DebugClientBase.__compileFileSource" id="DebugClientBase.__compileFileSource" ref="eric7.DebugClients.Python.DebugClientBase.html#DebugClientBase.__compileFileSource" />
@@ -3421,16 +3422,6 @@
       <keyword name="DebugServer.__setClientType" id="DebugServer.__setClientType" ref="eric7.Debugger.DebugServer.html#DebugServer.__setClientType" />
       <keyword name="DebugServer.__splitWatchCondition" id="DebugServer.__splitWatchCondition" ref="eric7.Debugger.DebugServer.html#DebugServer.__splitWatchCondition" />
       <keyword name="DebugServer.__watchPointDataAboutToBeChanged" id="DebugServer.__watchPointDataAboutToBeChanged" ref="eric7.Debugger.DebugServer.html#DebugServer.__watchPointDataAboutToBeChanged" />
-      <keyword name="DebugServer.clientUtDiscovered" id="DebugServer.clientUtDiscovered" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtDiscovered" />
-      <keyword name="DebugServer.clientUtFinished" id="DebugServer.clientUtFinished" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtFinished" />
-      <keyword name="DebugServer.clientUtPrepared" id="DebugServer.clientUtPrepared" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtPrepared" />
-      <keyword name="DebugServer.clientUtStartTest" id="DebugServer.clientUtStartTest" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtStartTest" />
-      <keyword name="DebugServer.clientUtStopTest" id="DebugServer.clientUtStopTest" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtStopTest" />
-      <keyword name="DebugServer.clientUtTestErrored" id="DebugServer.clientUtTestErrored" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtTestErrored" />
-      <keyword name="DebugServer.clientUtTestFailed" id="DebugServer.clientUtTestFailed" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtTestFailed" />
-      <keyword name="DebugServer.clientUtTestFailedExpected" id="DebugServer.clientUtTestFailedExpected" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtTestFailedExpected" />
-      <keyword name="DebugServer.clientUtTestSkipped" id="DebugServer.clientUtTestSkipped" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtTestSkipped" />
-      <keyword name="DebugServer.clientUtTestSucceededUnexpected" id="DebugServer.clientUtTestSucceededUnexpected" ref="eric7.Debugger.DebugServer.html#DebugServer.clientUtTestSucceededUnexpected" />
       <keyword name="DebugServer.getBreakPointModel" id="DebugServer.getBreakPointModel" ref="eric7.Debugger.DebugServer.html#DebugServer.getBreakPointModel" />
       <keyword name="DebugServer.getClientCapabilities" id="DebugServer.getClientCapabilities" ref="eric7.Debugger.DebugServer.html#DebugServer.getClientCapabilities" />
       <keyword name="DebugServer.getClientInterpreter" id="DebugServer.getClientInterpreter" ref="eric7.Debugger.DebugServer.html#DebugServer.getClientInterpreter" />
@@ -3473,10 +3464,6 @@
       <keyword name="DebugServer.remoteStepOver" id="DebugServer.remoteStepOver" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteStepOver" />
       <keyword name="DebugServer.remoteStepQuit" id="DebugServer.remoteStepQuit" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteStepQuit" />
       <keyword name="DebugServer.remoteThreadList" id="DebugServer.remoteThreadList" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteThreadList" />
-      <keyword name="DebugServer.remoteUTDiscover" id="DebugServer.remoteUTDiscover" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteUTDiscover" />
-      <keyword name="DebugServer.remoteUTPrepare" id="DebugServer.remoteUTPrepare" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteUTPrepare" />
-      <keyword name="DebugServer.remoteUTRun" id="DebugServer.remoteUTRun" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteUTRun" />
-      <keyword name="DebugServer.remoteUTStop" id="DebugServer.remoteUTStop" ref="eric7.Debugger.DebugServer.html#DebugServer.remoteUTStop" />
       <keyword name="DebugServer.setCallTraceEnabled" id="DebugServer.setCallTraceEnabled" ref="eric7.Debugger.DebugServer.html#DebugServer.setCallTraceEnabled" />
       <keyword name="DebugServer.setDebugging" id="DebugServer.setDebugging" ref="eric7.Debugger.DebugServer.html#DebugServer.setDebugging" />
       <keyword name="DebugServer.shutdownServer" id="DebugServer.shutdownServer" ref="eric7.Debugger.DebugServer.html#DebugServer.shutdownServer" />
@@ -3679,10 +3666,6 @@
       <keyword name="DebuggerInterfaceNone.remoteStepOver" id="DebuggerInterfaceNone.remoteStepOver" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteStepOver" />
       <keyword name="DebuggerInterfaceNone.remoteStepQuit" id="DebuggerInterfaceNone.remoteStepQuit" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteStepQuit" />
       <keyword name="DebuggerInterfaceNone.remoteThreadList" id="DebuggerInterfaceNone.remoteThreadList" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteThreadList" />
-      <keyword name="DebuggerInterfaceNone.remoteUTDiscover" id="DebuggerInterfaceNone.remoteUTDiscover" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteUTDiscover" />
-      <keyword name="DebuggerInterfaceNone.remoteUTPrepare" id="DebuggerInterfaceNone.remoteUTPrepare" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteUTPrepare" />
-      <keyword name="DebuggerInterfaceNone.remoteUTRun" id="DebuggerInterfaceNone.remoteUTRun" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteUTRun" />
-      <keyword name="DebuggerInterfaceNone.remoteUTStop" id="DebuggerInterfaceNone.remoteUTStop" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteUTStop" />
       <keyword name="DebuggerInterfaceNone.remoteWatchpoint" id="DebuggerInterfaceNone.remoteWatchpoint" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteWatchpoint" />
       <keyword name="DebuggerInterfaceNone.remoteWatchpointEnable" id="DebuggerInterfaceNone.remoteWatchpointEnable" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteWatchpointEnable" />
       <keyword name="DebuggerInterfaceNone.remoteWatchpointIgnore" id="DebuggerInterfaceNone.remoteWatchpointIgnore" ref="eric7.Debugger.DebuggerInterfaceNone.html#DebuggerInterfaceNone.remoteWatchpointIgnore" />
@@ -3736,10 +3719,6 @@
       <keyword name="DebuggerInterfacePython.remoteStepOver" id="DebuggerInterfacePython.remoteStepOver" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteStepOver" />
       <keyword name="DebuggerInterfacePython.remoteStepQuit" id="DebuggerInterfacePython.remoteStepQuit" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteStepQuit" />
       <keyword name="DebuggerInterfacePython.remoteThreadList" id="DebuggerInterfacePython.remoteThreadList" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteThreadList" />
-      <keyword name="DebuggerInterfacePython.remoteUTDiscover" id="DebuggerInterfacePython.remoteUTDiscover" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteUTDiscover" />
-      <keyword name="DebuggerInterfacePython.remoteUTPrepare" id="DebuggerInterfacePython.remoteUTPrepare" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteUTPrepare" />
-      <keyword name="DebuggerInterfacePython.remoteUTRun" id="DebuggerInterfacePython.remoteUTRun" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteUTRun" />
-      <keyword name="DebuggerInterfacePython.remoteUTStop" id="DebuggerInterfacePython.remoteUTStop" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteUTStop" />
       <keyword name="DebuggerInterfacePython.remoteWatchpoint" id="DebuggerInterfacePython.remoteWatchpoint" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteWatchpoint" />
       <keyword name="DebuggerInterfacePython.remoteWatchpointEnable" id="DebuggerInterfacePython.remoteWatchpointEnable" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteWatchpointEnable" />
       <keyword name="DebuggerInterfacePython.remoteWatchpointIgnore" id="DebuggerInterfacePython.remoteWatchpointIgnore" ref="eric7.Debugger.DebuggerInterfacePython.html#DebuggerInterfacePython.remoteWatchpointIgnore" />
@@ -5005,6 +4984,13 @@
       <keyword name="EricJsonClient.poll" id="EricJsonClient.poll" ref="eric7.EricNetwork.EricJsonClient.html#EricJsonClient.poll" />
       <keyword name="EricJsonClient.run" id="EricJsonClient.run" ref="eric7.EricNetwork.EricJsonClient.html#EricJsonClient.run" />
       <keyword name="EricJsonClient.sendJson" id="EricJsonClient.sendJson" ref="eric7.EricNetwork.EricJsonClient.html#EricJsonClient.sendJson" />
+      <keyword name="EricJsonReader" id="EricJsonReader" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader" />
+      <keyword name="EricJsonReader (Constructor)" id="EricJsonReader (Constructor)" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.__init__" />
+      <keyword name="EricJsonReader.__handleDisconnect" id="EricJsonReader.__handleDisconnect" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.__handleDisconnect" />
+      <keyword name="EricJsonReader.__receiveJson" id="EricJsonReader.__receiveJson" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.__receiveJson" />
+      <keyword name="EricJsonReader.address" id="EricJsonReader.address" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.address" />
+      <keyword name="EricJsonReader.handleNewConnection" id="EricJsonReader.handleNewConnection" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.handleNewConnection" />
+      <keyword name="EricJsonReader.port" id="EricJsonReader.port" ref="eric7.EricNetwork.EricJsonStreamReader.html#EricJsonReader.port" />
       <keyword name="EricJsonServer" id="EricJsonServer" ref="eric7.EricNetwork.EricJsonServer.html#EricJsonServer" />
       <keyword name="EricJsonServer (Constructor)" id="EricJsonServer (Constructor)" ref="eric7.EricNetwork.EricJsonServer.html#EricJsonServer.__init__" />
       <keyword name="EricJsonServer (Module)" id="EricJsonServer (Module)" ref="eric7.EricNetwork.EricJsonServer.html" />
@@ -5017,6 +5003,12 @@
       <keyword name="EricJsonServer.startClient" id="EricJsonServer.startClient" ref="eric7.EricNetwork.EricJsonServer.html#EricJsonServer.startClient" />
       <keyword name="EricJsonServer.stopAllClients" id="EricJsonServer.stopAllClients" ref="eric7.EricNetwork.EricJsonServer.html#EricJsonServer.stopAllClients" />
       <keyword name="EricJsonServer.stopClient" id="EricJsonServer.stopClient" ref="eric7.EricNetwork.EricJsonServer.html#EricJsonServer.stopClient" />
+      <keyword name="EricJsonStreamReader (Module)" id="EricJsonStreamReader (Module)" ref="eric7.EricNetwork.EricJsonStreamReader.html" />
+      <keyword name="EricJsonStreamWriter (Module)" id="EricJsonStreamWriter (Module)" ref="eric7.EricNetwork.EricJsonStreamWriter.html" />
+      <keyword name="EricJsonWriter" id="EricJsonWriter" ref="eric7.EricNetwork.EricJsonStreamWriter.html#EricJsonWriter" />
+      <keyword name="EricJsonWriter (Constructor)" id="EricJsonWriter (Constructor)" ref="eric7.EricNetwork.EricJsonStreamWriter.html#EricJsonWriter.__init__" />
+      <keyword name="EricJsonWriter.close" id="EricJsonWriter.close" ref="eric7.EricNetwork.EricJsonStreamWriter.html#EricJsonWriter.close" />
+      <keyword name="EricJsonWriter.write" id="EricJsonWriter.write" ref="eric7.EricNetwork.EricJsonStreamWriter.html#EricJsonWriter.write" />
       <keyword name="EricLed" id="EricLed" ref="eric7.EricWidgets.EricLed.html#EricLed" />
       <keyword name="EricLed (Constructor)" id="EricLed (Constructor)" ref="eric7.EricWidgets.EricLed.html#EricLed.__init__" />
       <keyword name="EricLed (Module)" id="EricLed (Module)" ref="eric7.EricWidgets.EricLed.html" />
@@ -5305,6 +5297,18 @@
       <keyword name="EricPlainTextDialog (Constructor)" id="EricPlainTextDialog (Constructor)" ref="eric7.EricWidgets.EricPlainTextDialog.html#EricPlainTextDialog.__init__" />
       <keyword name="EricPlainTextDialog (Module)" id="EricPlainTextDialog (Module)" ref="eric7.EricWidgets.EricPlainTextDialog.html" />
       <keyword name="EricPlainTextDialog.on_copyButton_clicked" id="EricPlainTextDialog.on_copyButton_clicked" ref="eric7.EricWidgets.EricPlainTextDialog.html#EricPlainTextDialog.on_copyButton_clicked" />
+      <keyword name="EricPlainTextDialog.toPlainText" id="EricPlainTextDialog.toPlainText" ref="eric7.EricWidgets.EricPlainTextDialog.html#EricPlainTextDialog.toPlainText" />
+      <keyword name="EricPlugin" id="EricPlugin" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin" />
+      <keyword name="EricPlugin (Constructor)" id="EricPlugin (Constructor)" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.__init__" />
+      <keyword name="EricPlugin.__initializeReportData" id="EricPlugin.__initializeReportData" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.__initializeReportData" />
+      <keyword name="EricPlugin.pytest_collectreport" id="EricPlugin.pytest_collectreport" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_collectreport" />
+      <keyword name="EricPlugin.pytest_itemcollected" id="EricPlugin.pytest_itemcollected" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_itemcollected" />
+      <keyword name="EricPlugin.pytest_report_header" id="EricPlugin.pytest_report_header" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_report_header" />
+      <keyword name="EricPlugin.pytest_runtest_logfinish" id="EricPlugin.pytest_runtest_logfinish" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_runtest_logfinish" />
+      <keyword name="EricPlugin.pytest_runtest_logreport" id="EricPlugin.pytest_runtest_logreport" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_runtest_logreport" />
+      <keyword name="EricPlugin.pytest_runtest_logstart" id="EricPlugin.pytest_runtest_logstart" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_runtest_logstart" />
+      <keyword name="EricPlugin.pytest_sessionfinish" id="EricPlugin.pytest_sessionfinish" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_sessionfinish" />
+      <keyword name="EricPlugin.pytest_sessionstart" id="EricPlugin.pytest_sessionstart" ref="eric7.Testing.Interfaces.PytestRunner.html#EricPlugin.pytest_sessionstart" />
       <keyword name="EricPluginWizard (Package)" id="EricPluginWizard (Package)" ref="index-eric7.Plugins.WizardPlugins.EricPluginWizard.html" />
       <keyword name="EricProcessDialog" id="EricProcessDialog" ref="eric7.EricWidgets.EricProcessDialog.html#EricProcessDialog" />
       <keyword name="EricProcessDialog (Constructor)" id="EricProcessDialog (Constructor)" ref="eric7.EricWidgets.EricProcessDialog.html#EricProcessDialog.__init__" />
@@ -5497,6 +5501,18 @@
       <keyword name="EricTableView.keyPressEvent" id="EricTableView.keyPressEvent" ref="eric7.EricWidgets.EricTableView.html#EricTableView.keyPressEvent" />
       <keyword name="EricTableView.removeAll" id="EricTableView.removeAll" ref="eric7.EricWidgets.EricTableView.html#EricTableView.removeAll" />
       <keyword name="EricTableView.removeSelected" id="EricTableView.removeSelected" ref="eric7.EricWidgets.EricTableView.html#EricTableView.removeSelected" />
+      <keyword name="EricTestResult" id="EricTestResult" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult" />
+      <keyword name="EricTestResult (Constructor)" id="EricTestResult (Constructor)" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.__init__" />
+      <keyword name="EricTestResult.addError" id="EricTestResult.addError" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addError" />
+      <keyword name="EricTestResult.addExpectedFailure" id="EricTestResult.addExpectedFailure" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addExpectedFailure" />
+      <keyword name="EricTestResult.addFailure" id="EricTestResult.addFailure" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addFailure" />
+      <keyword name="EricTestResult.addSkip" id="EricTestResult.addSkip" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addSkip" />
+      <keyword name="EricTestResult.addSubTest" id="EricTestResult.addSubTest" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addSubTest" />
+      <keyword name="EricTestResult.addUnexpectedSuccess" id="EricTestResult.addUnexpectedSuccess" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.addUnexpectedSuccess" />
+      <keyword name="EricTestResult.startTest" id="EricTestResult.startTest" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.startTest" />
+      <keyword name="EricTestResult.startTestRun" id="EricTestResult.startTestRun" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.startTestRun" />
+      <keyword name="EricTestResult.stopTest" id="EricTestResult.stopTest" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.stopTest" />
+      <keyword name="EricTestResult.stopTestRun" id="EricTestResult.stopTestRun" ref="eric7.Testing.Interfaces.UnittestRunner.html#EricTestResult.stopTestRun" />
       <keyword name="EricTextEditSearchWidget" id="EricTextEditSearchWidget" ref="eric7.EricWidgets.EricTextEditSearchWidget.html#EricTextEditSearchWidget" />
       <keyword name="EricTextEditSearchWidget (Constructor)" id="EricTextEditSearchWidget (Constructor)" ref="eric7.EricWidgets.EricTextEditSearchWidget.html#EricTextEditSearchWidget.__init__" />
       <keyword name="EricTextEditSearchWidget (Module)" id="EricTextEditSearchWidget (Module)" ref="eric7.EricWidgets.EricTextEditSearchWidget.html" />
@@ -6193,6 +6209,10 @@
       <keyword name="GenericMicroPythonDevice.setButtons" id="GenericMicroPythonDevice.setButtons" ref="eric7.MicroPython.GenericMicroPythonDevices.html#GenericMicroPythonDevice.setButtons" />
       <keyword name="GenericMicroPythonDevice.supportsLocalFileAccess" id="GenericMicroPythonDevice.supportsLocalFileAccess" ref="eric7.MicroPython.GenericMicroPythonDevices.html#GenericMicroPythonDevice.supportsLocalFileAccess" />
       <keyword name="GenericMicroPythonDevices (Module)" id="GenericMicroPythonDevices (Module)" ref="eric7.MicroPython.GenericMicroPythonDevices.html" />
+      <keyword name="GetPluginVersionsPlugin" id="GetPluginVersionsPlugin" ref="eric7.Testing.Interfaces.PytestRunner.html#GetPluginVersionsPlugin" />
+      <keyword name="GetPluginVersionsPlugin (Constructor)" id="GetPluginVersionsPlugin (Constructor)" ref="eric7.Testing.Interfaces.PytestRunner.html#GetPluginVersionsPlugin.__init__" />
+      <keyword name="GetPluginVersionsPlugin.getVersions" id="GetPluginVersionsPlugin.getVersions" ref="eric7.Testing.Interfaces.PytestRunner.html#GetPluginVersionsPlugin.getVersions" />
+      <keyword name="GetPluginVersionsPlugin.pytest_cmdline_main" id="GetPluginVersionsPlugin.pytest_cmdline_main" ref="eric7.Testing.Interfaces.PytestRunner.html#GetPluginVersionsPlugin.pytest_cmdline_main" />
       <keyword name="GetSysPath (Module)" id="GetSysPath (Module)" ref="eric7.Utilities.GetSysPath.html" />
       <keyword name="Git" id="Git" ref="eric7.Plugins.VcsPlugins.vcsGit.git.html#Git" />
       <keyword name="Git (Constructor)" id="Git (Constructor)" ref="eric7.Plugins.VcsPlugins.vcsGit.git.html#Git.__init__" />
@@ -9116,10 +9136,10 @@
       <keyword name="InputDialogWizardDialog" id="InputDialogWizardDialog" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog" />
       <keyword name="InputDialogWizardDialog (Constructor)" id="InputDialogWizardDialog (Constructor)" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.__init__" />
       <keyword name="InputDialogWizardDialog (Module)" id="InputDialogWizardDialog (Module)" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html" />
+      <keyword name="InputDialogWizardDialog.__typeSelectButtonToggled" id="InputDialogWizardDialog.__typeSelectButtonToggled" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.__typeSelectButtonToggled" />
       <keyword name="InputDialogWizardDialog.getCode" id="InputDialogWizardDialog.getCode" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.getCode" />
       <keyword name="InputDialogWizardDialog.on_bTest_clicked" id="InputDialogWizardDialog.on_bTest_clicked" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.on_bTest_clicked" />
       <keyword name="InputDialogWizardDialog.on_buttonBox_clicked" id="InputDialogWizardDialog.on_buttonBox_clicked" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.on_buttonBox_clicked" />
-      <keyword name="InputDialogWizardDialog.on_rItem_toggled" id="InputDialogWizardDialog.on_rItem_toggled" ref="eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html#InputDialogWizardDialog.on_rItem_toggled" />
       <keyword name="InsertBookmarksCommand" id="InsertBookmarksCommand" ref="eric7.WebBrowser.Bookmarks.BookmarksManager.html#InsertBookmarksCommand" />
       <keyword name="InsertBookmarksCommand (Constructor)" id="InsertBookmarksCommand (Constructor)" ref="eric7.WebBrowser.Bookmarks.BookmarksManager.html#InsertBookmarksCommand.__init__" />
       <keyword name="InsertBookmarksCommand.redo" id="InsertBookmarksCommand.redo" ref="eric7.WebBrowser.Bookmarks.BookmarksManager.html#InsertBookmarksCommand.redo" />
@@ -9152,6 +9172,7 @@
       <keyword name="InterfacePage.on_iconBarButton_clicked" id="InterfacePage.on_iconBarButton_clicked" ref="eric7.Preferences.ConfigurationPages.InterfacePage.html#InterfacePage.on_iconBarButton_clicked" />
       <keyword name="InterfacePage.on_resetLayoutButton_clicked" id="InterfacePage.on_resetLayoutButton_clicked" ref="eric7.Preferences.ConfigurationPages.InterfacePage.html#InterfacePage.on_resetLayoutButton_clicked" />
       <keyword name="InterfacePage.save" id="InterfacePage.save" ref="eric7.Preferences.ConfigurationPages.InterfacePage.html#InterfacePage.save" />
+      <keyword name="Interfaces (Package)" id="Interfaces (Package)" ref="index-eric7.Testing.Interfaces.html" />
       <keyword name="InvalidModulePath" id="InvalidModulePath" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.SecurityUtils.html#InvalidModulePath" />
       <keyword name="IrcChannel" id="IrcChannel" ref="eric7.Network.IRC.IrcNetworkManager.html#IrcChannel" />
       <keyword name="IrcChannel (Constructor)" id="IrcChannel (Constructor)" ref="eric7.Network.IRC.IrcNetworkManager.html#IrcChannel.__init__" />
@@ -11322,6 +11343,7 @@
       <keyword name="PipLicensesDialog" id="PipLicensesDialog" ref="eric7.PipInterface.PipLicensesDialog.html#PipLicensesDialog" />
       <keyword name="PipLicensesDialog (Constructor)" id="PipLicensesDialog (Constructor)" ref="eric7.PipInterface.PipLicensesDialog.html#PipLicensesDialog.__init__" />
       <keyword name="PipLicensesDialog (Module)" id="PipLicensesDialog (Module)" ref="eric7.PipInterface.PipLicensesDialog.html" />
+      <keyword name="PipLicensesDialog.__filterPackagesByLicense" id="PipLicensesDialog.__filterPackagesByLicense" ref="eric7.PipInterface.PipLicensesDialog.html#PipLicensesDialog.__filterPackagesByLicense" />
       <keyword name="PipLicensesDialog.__refreshLicenses" id="PipLicensesDialog.__refreshLicenses" ref="eric7.PipInterface.PipLicensesDialog.html#PipLicensesDialog.__refreshLicenses" />
       <keyword name="PipLicensesDialog.__saveAsCSV" id="PipLicensesDialog.__saveAsCSV" ref="eric7.PipInterface.PipLicensesDialog.html#PipLicensesDialog.__saveAsCSV" />
       <keyword name="PipPackageDetailsDialog" id="PipPackageDetailsDialog" ref="eric7.PipInterface.PipPackageDetailsDialog.html#PipPackageDetailsDialog" />
@@ -11923,15 +11945,19 @@
       <keyword name="Project.getProjectAuthorEmail" id="Project.getProjectAuthorEmail" ref="eric7.Project.Project.html#Project.getProjectAuthorEmail" />
       <keyword name="Project.getProjectDescription" id="Project.getProjectDescription" ref="eric7.Project.Project.html#Project.getProjectDescription" />
       <keyword name="Project.getProjectDictionaries" id="Project.getProjectDictionaries" ref="eric7.Project.Project.html#Project.getProjectDictionaries" />
+      <keyword name="Project.getProjectExecPath" id="Project.getProjectExecPath" ref="eric7.Project.Project.html#Project.getProjectExecPath" />
       <keyword name="Project.getProjectFile" id="Project.getProjectFile" ref="eric7.Project.Project.html#Project.getProjectFile" />
       <keyword name="Project.getProjectFiles" id="Project.getProjectFiles" ref="eric7.Project.Project.html#Project.getProjectFiles" />
+      <keyword name="Project.getProjectInterpreter" id="Project.getProjectInterpreter" ref="eric7.Project.Project.html#Project.getProjectInterpreter" />
       <keyword name="Project.getProjectLanguage" id="Project.getProjectLanguage" ref="eric7.Project.Project.html#Project.getProjectLanguage" />
       <keyword name="Project.getProjectManagementDir" id="Project.getProjectManagementDir" ref="eric7.Project.Project.html#Project.getProjectManagementDir" />
       <keyword name="Project.getProjectName" id="Project.getProjectName" ref="eric7.Project.Project.html#Project.getProjectName" />
       <keyword name="Project.getProjectPath" id="Project.getProjectPath" ref="eric7.Project.Project.html#Project.getProjectPath" />
       <keyword name="Project.getProjectSpellLanguage" id="Project.getProjectSpellLanguage" ref="eric7.Project.Project.html#Project.getProjectSpellLanguage" />
+      <keyword name="Project.getProjectTestingFramework" id="Project.getProjectTestingFramework" ref="eric7.Project.Project.html#Project.getProjectTestingFramework" />
       <keyword name="Project.getProjectType" id="Project.getProjectType" ref="eric7.Project.Project.html#Project.getProjectType" />
       <keyword name="Project.getProjectTypes" id="Project.getProjectTypes" ref="eric7.Project.Project.html#Project.getProjectTypes" />
+      <keyword name="Project.getProjectVenv" id="Project.getProjectVenv" ref="eric7.Project.Project.html#Project.getProjectVenv" />
       <keyword name="Project.getProjectVersion" id="Project.getProjectVersion" ref="eric7.Project.Project.html#Project.getProjectVersion" />
       <keyword name="Project.getRelativePath" id="Project.getRelativePath" ref="eric7.Project.Project.html#Project.getRelativePath" />
       <keyword name="Project.getRelativeUniversalPath" id="Project.getRelativeUniversalPath" ref="eric7.Project.Project.html#Project.getRelativeUniversalPath" />
@@ -12384,7 +12410,7 @@
       <keyword name="PropertiesDialog.getPPath" id="PropertiesDialog.getPPath" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.getPPath" />
       <keyword name="PropertiesDialog.getProjectType" id="PropertiesDialog.getProjectType" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.getProjectType" />
       <keyword name="PropertiesDialog.on_dirPicker_textChanged" id="PropertiesDialog.on_dirPicker_textChanged" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_dirPicker_textChanged" />
-      <keyword name="PropertiesDialog.on_languageComboBox_currentIndexChanged" id="PropertiesDialog.on_languageComboBox_currentIndexChanged" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_languageComboBox_currentIndexChanged" />
+      <keyword name="PropertiesDialog.on_languageComboBox_currentTextChanged" id="PropertiesDialog.on_languageComboBox_currentTextChanged" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_languageComboBox_currentTextChanged" />
       <keyword name="PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog" id="PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog" />
       <keyword name="PropertiesDialog.on_mainscriptPicker_pathSelected" id="PropertiesDialog.on_mainscriptPicker_pathSelected" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_mainscriptPicker_pathSelected" />
       <keyword name="PropertiesDialog.on_makeButton_clicked" id="PropertiesDialog.on_makeButton_clicked" ref="eric7.Project.PropertiesDialog.html#PropertiesDialog.on_makeButton_clicked" />
@@ -12462,20 +12488,31 @@
       <keyword name="PyCoverageDialog" id="PyCoverageDialog" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog" />
       <keyword name="PyCoverageDialog (Constructor)" id="PyCoverageDialog (Constructor)" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__init__" />
       <keyword name="PyCoverageDialog (Module)" id="PyCoverageDialog (Module)" ref="eric7.DataViews.PyCoverageDialog.html" />
-      <keyword name="PyCoverageDialog.__annotate" id="PyCoverageDialog.__annotate" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__annotate" />
-      <keyword name="PyCoverageDialog.__annotateAll" id="PyCoverageDialog.__annotateAll" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__annotateAll" />
       <keyword name="PyCoverageDialog.__createResultItem" id="PyCoverageDialog.__createResultItem" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__createResultItem" />
-      <keyword name="PyCoverageDialog.__deleteAnnotated" id="PyCoverageDialog.__deleteAnnotated" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__deleteAnnotated" />
       <keyword name="PyCoverageDialog.__erase" id="PyCoverageDialog.__erase" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__erase" />
       <keyword name="PyCoverageDialog.__finish" id="PyCoverageDialog.__finish" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__finish" />
       <keyword name="PyCoverageDialog.__format_lines" id="PyCoverageDialog.__format_lines" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__format_lines" />
+      <keyword name="PyCoverageDialog.__htmlReport" id="PyCoverageDialog.__htmlReport" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__htmlReport" />
+      <keyword name="PyCoverageDialog.__jsonReport" id="PyCoverageDialog.__jsonReport" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__jsonReport" />
+      <keyword name="PyCoverageDialog.__lcovReport" id="PyCoverageDialog.__lcovReport" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__lcovReport" />
       <keyword name="PyCoverageDialog.__openFile" id="PyCoverageDialog.__openFile" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__openFile" />
+      <keyword name="PyCoverageDialog.__prepareReportGeneration" id="PyCoverageDialog.__prepareReportGeneration" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__prepareReportGeneration" />
       <keyword name="PyCoverageDialog.__showContextMenu" id="PyCoverageDialog.__showContextMenu" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.__showContextMenu" />
       <keyword name="PyCoverageDialog.on_buttonBox_clicked" id="PyCoverageDialog.on_buttonBox_clicked" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.on_buttonBox_clicked" />
       <keyword name="PyCoverageDialog.on_reloadButton_clicked" id="PyCoverageDialog.on_reloadButton_clicked" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.on_reloadButton_clicked" />
       <keyword name="PyCoverageDialog.on_resultList_itemActivated" id="PyCoverageDialog.on_resultList_itemActivated" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.on_resultList_itemActivated" />
       <keyword name="PyCoverageDialog.start" id="PyCoverageDialog.start" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.start" />
       <keyword name="PyCoverageDialog.stringify" id="PyCoverageDialog.stringify" ref="eric7.DataViews.PyCoverageDialog.html#PyCoverageDialog.stringify" />
+      <keyword name="PyCoverageHtmlReportDialog" id="PyCoverageHtmlReportDialog" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html#PyCoverageHtmlReportDialog" />
+      <keyword name="PyCoverageHtmlReportDialog (Constructor)" id="PyCoverageHtmlReportDialog (Constructor)" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html#PyCoverageHtmlReportDialog.__init__" />
+      <keyword name="PyCoverageHtmlReportDialog (Module)" id="PyCoverageHtmlReportDialog (Module)" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html" />
+      <keyword name="PyCoverageHtmlReportDialog.getData" id="PyCoverageHtmlReportDialog.getData" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html#PyCoverageHtmlReportDialog.getData" />
+      <keyword name="PyCoverageHtmlReportDialog.on_outputDirectoryPicker_textChanged" id="PyCoverageHtmlReportDialog.on_outputDirectoryPicker_textChanged" ref="eric7.DataViews.PyCoverageHtmlReportDialog.html#PyCoverageHtmlReportDialog.on_outputDirectoryPicker_textChanged" />
+      <keyword name="PyCoverageJsonReportDialog" id="PyCoverageJsonReportDialog" ref="eric7.DataViews.PyCoverageJsonReportDialog.html#PyCoverageJsonReportDialog" />
+      <keyword name="PyCoverageJsonReportDialog (Constructor)" id="PyCoverageJsonReportDialog (Constructor)" ref="eric7.DataViews.PyCoverageJsonReportDialog.html#PyCoverageJsonReportDialog.__init__" />
+      <keyword name="PyCoverageJsonReportDialog (Module)" id="PyCoverageJsonReportDialog (Module)" ref="eric7.DataViews.PyCoverageJsonReportDialog.html" />
+      <keyword name="PyCoverageJsonReportDialog.getData" id="PyCoverageJsonReportDialog.getData" ref="eric7.DataViews.PyCoverageJsonReportDialog.html#PyCoverageJsonReportDialog.getData" />
+      <keyword name="PyCoverageJsonReportDialog.on_outputFilePicker_textChanged" id="PyCoverageJsonReportDialog.on_outputFilePicker_textChanged" ref="eric7.DataViews.PyCoverageJsonReportDialog.html#PyCoverageJsonReportDialog.on_outputFilePicker_textChanged" />
       <keyword name="PyDocstringGenerator" id="PyDocstringGenerator" ref="eric7.QScintilla.DocstringGenerator.PyDocstringGenerator.html#PyDocstringGenerator" />
       <keyword name="PyDocstringGenerator (Constructor)" id="PyDocstringGenerator (Constructor)" ref="eric7.QScintilla.DocstringGenerator.PyDocstringGenerator.html#PyDocstringGenerator.__init__" />
       <keyword name="PyDocstringGenerator (Module)" id="PyDocstringGenerator (Module)" ref="eric7.QScintilla.DocstringGenerator.PyDocstringGenerator.html" />
@@ -12610,7 +12647,6 @@
       <keyword name="PySvnProjectHelper.initMenu" id="PySvnProjectHelper.initMenu" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper.initMenu" />
       <keyword name="PySvnProjectHelper.initToolbar" id="PySvnProjectHelper.initToolbar" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper.initToolbar" />
       <keyword name="PySvnProjectHelper.removeToolbar" id="PySvnProjectHelper.removeToolbar" ref="eric7.Plugins.VcsPlugins.vcsPySvn.ProjectHelper.html#PySvnProjectHelper.removeToolbar" />
-      <keyword name="PyUnit (Package)" id="PyUnit (Package)" ref="index-eric7.PyUnit.html" />
       <keyword name="PypiSearchResultsParser" id="PypiSearchResultsParser" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser" />
       <keyword name="PypiSearchResultsParser (Constructor)" id="PypiSearchResultsParser (Constructor)" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser.__init__" />
       <keyword name="PypiSearchResultsParser.__getClass" id="PypiSearchResultsParser.__getClass" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser.__getClass" />
@@ -12619,6 +12655,18 @@
       <keyword name="PypiSearchResultsParser.handle_data" id="PypiSearchResultsParser.handle_data" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser.handle_data" />
       <keyword name="PypiSearchResultsParser.handle_endtag" id="PypiSearchResultsParser.handle_endtag" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser.handle_endtag" />
       <keyword name="PypiSearchResultsParser.handle_starttag" id="PypiSearchResultsParser.handle_starttag" ref="eric7.PipInterface.PipPackagesWidget.html#PypiSearchResultsParser.handle_starttag" />
+      <keyword name="PytestExecutor" id="PytestExecutor" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor" />
+      <keyword name="PytestExecutor (Constructor)" id="PytestExecutor (Constructor)" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.__init__" />
+      <keyword name="PytestExecutor (Module)" id="PytestExecutor (Module)" ref="eric7.Testing.Interfaces.PytestExecutor.html" />
+      <keyword name="PytestExecutor.__nodeid2testname" id="PytestExecutor.__nodeid2testname" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.__nodeid2testname" />
+      <keyword name="PytestExecutor.__normalizeModuleName" id="PytestExecutor.__normalizeModuleName" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.__normalizeModuleName" />
+      <keyword name="PytestExecutor.__processData" id="PytestExecutor.__processData" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.__processData" />
+      <keyword name="PytestExecutor.createArguments" id="PytestExecutor.createArguments" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.createArguments" />
+      <keyword name="PytestExecutor.finished" id="PytestExecutor.finished" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.finished" />
+      <keyword name="PytestExecutor.getVersions" id="PytestExecutor.getVersions" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.getVersions" />
+      <keyword name="PytestExecutor.hasCoverage" id="PytestExecutor.hasCoverage" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.hasCoverage" />
+      <keyword name="PytestExecutor.start" id="PytestExecutor.start" ref="eric7.Testing.Interfaces.PytestExecutor.html#PytestExecutor.start" />
+      <keyword name="PytestRunner (Module)" id="PytestRunner (Module)" ref="eric7.Testing.Interfaces.PytestRunner.html" />
       <keyword name="Python (Package)" id="Python (Package)" ref="index-eric7.DebugClients.Python.html" />
       <keyword name="PythonAstViewer" id="PythonAstViewer" ref="eric7.UI.PythonAstViewer.html#PythonAstViewer" />
       <keyword name="PythonAstViewer (Constructor)" id="PythonAstViewer (Constructor)" ref="eric7.UI.PythonAstViewer.html#PythonAstViewer.__init__" />
@@ -12970,16 +13018,6 @@
       <keyword name="QtResolver" id="QtResolver" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver" />
       <keyword name="QtResolver.getVariableList" id="QtResolver.getVariableList" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver.getVariableList" />
       <keyword name="QtResolver.resolve" id="QtResolver.resolve" ref="eric7.DebugClients.Python.DebugVariables.html#QtResolver.resolve" />
-      <keyword name="QtTestResult" id="QtTestResult" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult" />
-      <keyword name="QtTestResult (Constructor)" id="QtTestResult (Constructor)" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.__init__" />
-      <keyword name="QtTestResult.addError" id="QtTestResult.addError" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addError" />
-      <keyword name="QtTestResult.addExpectedFailure" id="QtTestResult.addExpectedFailure" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addExpectedFailure" />
-      <keyword name="QtTestResult.addFailure" id="QtTestResult.addFailure" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addFailure" />
-      <keyword name="QtTestResult.addSkip" id="QtTestResult.addSkip" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addSkip" />
-      <keyword name="QtTestResult.addSubTest" id="QtTestResult.addSubTest" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addSubTest" />
-      <keyword name="QtTestResult.addUnexpectedSuccess" id="QtTestResult.addUnexpectedSuccess" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.addUnexpectedSuccess" />
-      <keyword name="QtTestResult.startTest" id="QtTestResult.startTest" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.startTest" />
-      <keyword name="QtTestResult.stopTest" id="QtTestResult.stopTest" ref="eric7.PyUnit.UnittestDialog.html#QtTestResult.stopTest" />
       <keyword name="Queues" id="Queues" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues" />
       <keyword name="Queues (Constructor)" id="Queues (Constructor)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues.__init__" />
       <keyword name="Queues.__getCommitMessage" id="Queues.__getCommitMessage" ref="eric7.Plugins.VcsPlugins.vcsMercurial.QueuesExtension.queues.html#Queues.__getCommitMessage" />
@@ -15717,6 +15755,111 @@
       <keyword name="TemplatesReader.__readTemplate" id="TemplatesReader.__readTemplate" ref="eric7.EricXML.TemplatesReader.html#TemplatesReader.__readTemplate" />
       <keyword name="TemplatesReader.__readTemplateGroup" id="TemplatesReader.__readTemplateGroup" ref="eric7.EricXML.TemplatesReader.html#TemplatesReader.__readTemplateGroup" />
       <keyword name="TemplatesReader.readXML" id="TemplatesReader.readXML" ref="eric7.EricXML.TemplatesReader.html#TemplatesReader.readXML" />
+      <keyword name="TestConfig" id="TestConfig" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestConfig" />
+      <keyword name="TestExecutorBase" id="TestExecutorBase" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase" />
+      <keyword name="TestExecutorBase (Constructor)" id="TestExecutorBase (Constructor)" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.__init__" />
+      <keyword name="TestExecutorBase (Module)" id="TestExecutorBase (Module)" ref="eric7.Testing.Interfaces.TestExecutorBase.html" />
+      <keyword name="TestExecutorBase._prepareProcess" id="TestExecutorBase._prepareProcess" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase._prepareProcess" />
+      <keyword name="TestExecutorBase.createArguments" id="TestExecutorBase.createArguments" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.createArguments" />
+      <keyword name="TestExecutorBase.finished" id="TestExecutorBase.finished" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.finished" />
+      <keyword name="TestExecutorBase.getVersions" id="TestExecutorBase.getVersions" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.getVersions" />
+      <keyword name="TestExecutorBase.hasCoverage" id="TestExecutorBase.hasCoverage" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.hasCoverage" />
+      <keyword name="TestExecutorBase.isInstalled" id="TestExecutorBase.isInstalled" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.isInstalled" />
+      <keyword name="TestExecutorBase.readAllOutput" id="TestExecutorBase.readAllOutput" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.readAllOutput" />
+      <keyword name="TestExecutorBase.start" id="TestExecutorBase.start" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.start" />
+      <keyword name="TestExecutorBase.stopIfRunning" id="TestExecutorBase.stopIfRunning" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestExecutorBase.stopIfRunning" />
+      <keyword name="TestFrameworkRegistry" id="TestFrameworkRegistry" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html#TestFrameworkRegistry" />
+      <keyword name="TestFrameworkRegistry (Constructor)" id="TestFrameworkRegistry (Constructor)" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html#TestFrameworkRegistry.__init__" />
+      <keyword name="TestFrameworkRegistry (Module)" id="TestFrameworkRegistry (Module)" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html" />
+      <keyword name="TestFrameworkRegistry.createExecutor" id="TestFrameworkRegistry.createExecutor" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html#TestFrameworkRegistry.createExecutor" />
+      <keyword name="TestFrameworkRegistry.getFrameworks" id="TestFrameworkRegistry.getFrameworks" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html#TestFrameworkRegistry.getFrameworks" />
+      <keyword name="TestFrameworkRegistry.register" id="TestFrameworkRegistry.register" ref="eric7.Testing.Interfaces.TestFrameworkRegistry.html#TestFrameworkRegistry.register" />
+      <keyword name="TestResult" id="TestResult" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestResult" />
+      <keyword name="TestResultCategory" id="TestResultCategory" ref="eric7.Testing.Interfaces.TestExecutorBase.html#TestResultCategory" />
+      <keyword name="TestResultsModel" id="TestResultsModel" ref="eric7.Testing.TestResultsTree.html#TestResultsModel" />
+      <keyword name="TestResultsModel (Constructor)" id="TestResultsModel (Constructor)" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.__init__" />
+      <keyword name="TestResultsModel.__summary" id="TestResultsModel.__summary" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.__summary" />
+      <keyword name="TestResultsModel.addTestResults" id="TestResultsModel.addTestResults" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.addTestResults" />
+      <keyword name="TestResultsModel.clear" id="TestResultsModel.clear" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.clear" />
+      <keyword name="TestResultsModel.columnCount" id="TestResultsModel.columnCount" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.columnCount" />
+      <keyword name="TestResultsModel.data" id="TestResultsModel.data" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.data" />
+      <keyword name="TestResultsModel.durationKey" id="TestResultsModel.durationKey" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.durationKey" />
+      <keyword name="TestResultsModel.getFailedTests" id="TestResultsModel.getFailedTests" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.getFailedTests" />
+      <keyword name="TestResultsModel.getTestResults" id="TestResultsModel.getTestResults" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.getTestResults" />
+      <keyword name="TestResultsModel.headerData" id="TestResultsModel.headerData" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.headerData" />
+      <keyword name="TestResultsModel.index" id="TestResultsModel.index" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.index" />
+      <keyword name="TestResultsModel.parent" id="TestResultsModel.parent" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.parent" />
+      <keyword name="TestResultsModel.rowCount" id="TestResultsModel.rowCount" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.rowCount" />
+      <keyword name="TestResultsModel.setTestResults" id="TestResultsModel.setTestResults" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.setTestResults" />
+      <keyword name="TestResultsModel.sort" id="TestResultsModel.sort" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.sort" />
+      <keyword name="TestResultsModel.updateTestResults" id="TestResultsModel.updateTestResults" ref="eric7.Testing.TestResultsTree.html#TestResultsModel.updateTestResults" />
+      <keyword name="TestResultsTree (Module)" id="TestResultsTree (Module)" ref="eric7.Testing.TestResultsTree.html" />
+      <keyword name="TestResultsTreeView" id="TestResultsTreeView" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView" />
+      <keyword name="TestResultsTreeView (Constructor)" id="TestResultsTreeView (Constructor)" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__init__" />
+      <keyword name="TestResultsTreeView.__canonicalIndex" id="TestResultsTreeView.__canonicalIndex" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__canonicalIndex" />
+      <keyword name="TestResultsTreeView.__createBackgroundContextMenu" id="TestResultsTreeView.__createBackgroundContextMenu" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__createBackgroundContextMenu" />
+      <keyword name="TestResultsTreeView.__createContextMenu" id="TestResultsTreeView.__createContextMenu" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__createContextMenu" />
+      <keyword name="TestResultsTreeView.__gotoTestDefinition" id="TestResultsTreeView.__gotoTestDefinition" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__gotoTestDefinition" />
+      <keyword name="TestResultsTreeView.__showContextMenu" id="TestResultsTreeView.__showContextMenu" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.__showContextMenu" />
+      <keyword name="TestResultsTreeView.dataChanged" id="TestResultsTreeView.dataChanged" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.dataChanged" />
+      <keyword name="TestResultsTreeView.reset" id="TestResultsTreeView.reset" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.reset" />
+      <keyword name="TestResultsTreeView.resizeColumns" id="TestResultsTreeView.resizeColumns" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.resizeColumns" />
+      <keyword name="TestResultsTreeView.rowsInserted" id="TestResultsTreeView.rowsInserted" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.rowsInserted" />
+      <keyword name="TestResultsTreeView.spanFirstColumn" id="TestResultsTreeView.spanFirstColumn" ref="eric7.Testing.TestResultsTree.html#TestResultsTreeView.spanFirstColumn" />
+      <keyword name="Testing (Package)" id="Testing (Package)" ref="index-eric7.Testing.html" />
+      <keyword name="TestingWidget" id="TestingWidget" ref="eric7.Testing.TestingWidget.html#TestingWidget" />
+      <keyword name="TestingWidget (Constructor)" id="TestingWidget (Constructor)" ref="eric7.Testing.TestingWidget.html#TestingWidget.__init__" />
+      <keyword name="TestingWidget (Module)" id="TestingWidget (Module)" ref="eric7.Testing.TestingWidget.html" />
+      <keyword name="TestingWidget.__adjustPendingState" id="TestingWidget.__adjustPendingState" ref="eric7.Testing.TestingWidget.html#TestingWidget.__adjustPendingState" />
+      <keyword name="TestingWidget.__coverageData" id="TestingWidget.__coverageData" ref="eric7.Testing.TestingWidget.html#TestingWidget.__coverageData" />
+      <keyword name="TestingWidget.__insertDiscovery" id="TestingWidget.__insertDiscovery" ref="eric7.Testing.TestingWidget.html#TestingWidget.__insertDiscovery" />
+      <keyword name="TestingWidget.__insertHistory" id="TestingWidget.__insertHistory" ref="eric7.Testing.TestingWidget.html#TestingWidget.__insertHistory" />
+      <keyword name="TestingWidget.__insertTestFile" id="TestingWidget.__insertTestFile" ref="eric7.Testing.TestingWidget.html#TestingWidget.__insertTestFile" />
+      <keyword name="TestingWidget.__insertTestName" id="TestingWidget.__insertTestName" ref="eric7.Testing.TestingWidget.html#TestingWidget.__insertTestName" />
+      <keyword name="TestingWidget.__loadRecent" id="TestingWidget.__loadRecent" ref="eric7.Testing.TestingWidget.html#TestingWidget.__loadRecent" />
+      <keyword name="TestingWidget.__openEditor" id="TestingWidget.__openEditor" ref="eric7.Testing.TestingWidget.html#TestingWidget.__openEditor" />
+      <keyword name="TestingWidget.__populateTestFrameworkComboBox" id="TestingWidget.__populateTestFrameworkComboBox" ref="eric7.Testing.TestingWidget.html#TestingWidget.__populateTestFrameworkComboBox" />
+      <keyword name="TestingWidget.__populateVenvComboBox" id="TestingWidget.__populateVenvComboBox" ref="eric7.Testing.TestingWidget.html#TestingWidget.__populateVenvComboBox" />
+      <keyword name="TestingWidget.__processTestResult" id="TestingWidget.__processTestResult" ref="eric7.Testing.TestingWidget.html#TestingWidget.__processTestResult" />
+      <keyword name="TestingWidget.__projectClosed" id="TestingWidget.__projectClosed" ref="eric7.Testing.TestingWidget.html#TestingWidget.__projectClosed" />
+      <keyword name="TestingWidget.__projectOpened" id="TestingWidget.__projectOpened" ref="eric7.Testing.TestingWidget.html#TestingWidget.__projectOpened" />
+      <keyword name="TestingWidget.__resetResults" id="TestingWidget.__resetResults" ref="eric7.Testing.TestingWidget.html#TestingWidget.__resetResults" />
+      <keyword name="TestingWidget.__saveRecent" id="TestingWidget.__saveRecent" ref="eric7.Testing.TestingWidget.html#TestingWidget.__saveRecent" />
+      <keyword name="TestingWidget.__setIdleMode" id="TestingWidget.__setIdleMode" ref="eric7.Testing.TestingWidget.html#TestingWidget.__setIdleMode" />
+      <keyword name="TestingWidget.__setRunningMode" id="TestingWidget.__setRunningMode" ref="eric7.Testing.TestingWidget.html#TestingWidget.__setRunningMode" />
+      <keyword name="TestingWidget.__setStatusLabel" id="TestingWidget.__setStatusLabel" ref="eric7.Testing.TestingWidget.html#TestingWidget.__setStatusLabel" />
+      <keyword name="TestingWidget.__setStoppedMode" id="TestingWidget.__setStoppedMode" ref="eric7.Testing.TestingWidget.html#TestingWidget.__setStoppedMode" />
+      <keyword name="TestingWidget.__showCoverageDialog" id="TestingWidget.__showCoverageDialog" ref="eric7.Testing.TestingWidget.html#TestingWidget.__showCoverageDialog" />
+      <keyword name="TestingWidget.__showLogOutput" id="TestingWidget.__showLogOutput" ref="eric7.Testing.TestingWidget.html#TestingWidget.__showLogOutput" />
+      <keyword name="TestingWidget.__showSource" id="TestingWidget.__showSource" ref="eric7.Testing.TestingWidget.html#TestingWidget.__showSource" />
+      <keyword name="TestingWidget.__stopTests" id="TestingWidget.__stopTests" ref="eric7.Testing.TestingWidget.html#TestingWidget.__stopTests" />
+      <keyword name="TestingWidget.__testProcessFinished" id="TestingWidget.__testProcessFinished" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testProcessFinished" />
+      <keyword name="TestingWidget.__testRunAboutToBeStarted" id="TestingWidget.__testRunAboutToBeStarted" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testRunAboutToBeStarted" />
+      <keyword name="TestingWidget.__testRunFinished" id="TestingWidget.__testRunFinished" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testRunFinished" />
+      <keyword name="TestingWidget.__testStarted" id="TestingWidget.__testStarted" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testStarted" />
+      <keyword name="TestingWidget.__testsCollectError" id="TestingWidget.__testsCollectError" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testsCollectError" />
+      <keyword name="TestingWidget.__testsCollected" id="TestingWidget.__testsCollected" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testsCollected" />
+      <keyword name="TestingWidget.__testsStopped" id="TestingWidget.__testsStopped" ref="eric7.Testing.TestingWidget.html#TestingWidget.__testsStopped" />
+      <keyword name="TestingWidget.__updateButtonBoxButtons" id="TestingWidget.__updateButtonBoxButtons" ref="eric7.Testing.TestingWidget.html#TestingWidget.__updateButtonBoxButtons" />
+      <keyword name="TestingWidget.__updateCoverage" id="TestingWidget.__updateCoverage" ref="eric7.Testing.TestingWidget.html#TestingWidget.__updateCoverage" />
+      <keyword name="TestingWidget.__updateProgress" id="TestingWidget.__updateProgress" ref="eric7.Testing.TestingWidget.html#TestingWidget.__updateProgress" />
+      <keyword name="TestingWidget.clearRecent" id="TestingWidget.clearRecent" ref="eric7.Testing.TestingWidget.html#TestingWidget.clearRecent" />
+      <keyword name="TestingWidget.closeEvent" id="TestingWidget.closeEvent" ref="eric7.Testing.TestingWidget.html#TestingWidget.closeEvent" />
+      <keyword name="TestingWidget.getFailedTests" id="TestingWidget.getFailedTests" ref="eric7.Testing.TestingWidget.html#TestingWidget.getFailedTests" />
+      <keyword name="TestingWidget.getResultsModel" id="TestingWidget.getResultsModel" ref="eric7.Testing.TestingWidget.html#TestingWidget.getResultsModel" />
+      <keyword name="TestingWidget.hasFailedTests" id="TestingWidget.hasFailedTests" ref="eric7.Testing.TestingWidget.html#TestingWidget.hasFailedTests" />
+      <keyword name="TestingWidget.on_buttonBox_clicked" id="TestingWidget.on_buttonBox_clicked" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_buttonBox_clicked" />
+      <keyword name="TestingWidget.on_discoverCheckBox_toggled" id="TestingWidget.on_discoverCheckBox_toggled" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_discoverCheckBox_toggled" />
+      <keyword name="TestingWidget.on_frameworkComboBox_currentIndexChanged" id="TestingWidget.on_frameworkComboBox_currentIndexChanged" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_frameworkComboBox_currentIndexChanged" />
+      <keyword name="TestingWidget.on_testsuitePicker_aboutToShowPathPickerDialog" id="TestingWidget.on_testsuitePicker_aboutToShowPathPickerDialog" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_testsuitePicker_aboutToShowPathPickerDialog" />
+      <keyword name="TestingWidget.on_venvComboBox_currentIndexChanged" id="TestingWidget.on_venvComboBox_currentIndexChanged" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_venvComboBox_currentIndexChanged" />
+      <keyword name="TestingWidget.on_versionsButton_clicked" id="TestingWidget.on_versionsButton_clicked" ref="eric7.Testing.TestingWidget.html#TestingWidget.on_versionsButton_clicked" />
+      <keyword name="TestingWidget.setTestFile" id="TestingWidget.setTestFile" ref="eric7.Testing.TestingWidget.html#TestingWidget.setTestFile" />
+      <keyword name="TestingWidget.startTests" id="TestingWidget.startTests" ref="eric7.Testing.TestingWidget.html#TestingWidget.startTests" />
+      <keyword name="TestingWidgetModes" id="TestingWidgetModes" ref="eric7.Testing.TestingWidget.html#TestingWidgetModes" />
+      <keyword name="TestingWindow" id="TestingWindow" ref="eric7.Testing.TestingWidget.html#TestingWindow" />
+      <keyword name="TestingWindow (Constructor)" id="TestingWindow (Constructor)" ref="eric7.Testing.TestingWidget.html#TestingWindow.__init__" />
+      <keyword name="TestingWindow.eventFilter" id="TestingWindow.eventFilter" ref="eric7.Testing.TestingWidget.html#TestingWindow.eventFilter" />
       <keyword name="TextVisitor" id="TextVisitor" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#TextVisitor" />
       <keyword name="TextVisitor (Constructor)" id="TextVisitor (Constructor)" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#TextVisitor.__init__" />
       <keyword name="TextVisitor.__addNode" id="TextVisitor.__addNode" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Miscellaneous.MiscellaneousChecker.html#TextVisitor.__addNode" />
@@ -15934,8 +16077,8 @@
       <keyword name="TrayStarter.__startSnapshot" id="TrayStarter.__startSnapshot" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startSnapshot" />
       <keyword name="TrayStarter.__startSqlBrowser" id="TrayStarter.__startSqlBrowser" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startSqlBrowser" />
       <keyword name="TrayStarter.__startTRPreviewer" id="TrayStarter.__startTRPreviewer" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startTRPreviewer" />
+      <keyword name="TrayStarter.__startTesting" id="TrayStarter.__startTesting" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startTesting" />
       <keyword name="TrayStarter.__startUIPreviewer" id="TrayStarter.__startUIPreviewer" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startUIPreviewer" />
-      <keyword name="TrayStarter.__startUnittest" id="TrayStarter.__startUnittest" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startUnittest" />
       <keyword name="TrayStarter.__startVirtualenvManager" id="TrayStarter.__startVirtualenvManager" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startVirtualenvManager" />
       <keyword name="TrayStarter.__startWebBrowser" id="TrayStarter.__startWebBrowser" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startWebBrowser" />
       <keyword name="TrayStarter.__startWebBrowserPrivate" id="TrayStarter.__startWebBrowserPrivate" ref="eric7.Tools.TrayStarter.html#TrayStarter.__startWebBrowserPrivate" />
@@ -16094,53 +16237,16 @@
       <keyword name="UicCompilerOptionsDialog.getData" id="UicCompilerOptionsDialog.getData" ref="eric7.Project.UicCompilerOptionsDialog.html#UicCompilerOptionsDialog.getData" />
       <keyword name="UicLoadUi5 (Module)" id="UicLoadUi5 (Module)" ref="eric7.Project.UicLoadUi5.html" />
       <keyword name="UicLoadUi6 (Module)" id="UicLoadUi6 (Module)" ref="eric7.Project.UicLoadUi6.html" />
-      <keyword name="UnittestDialog" id="UnittestDialog" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog" />
-      <keyword name="UnittestDialog (Constructor)" id="UnittestDialog (Constructor)" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__init__" />
-      <keyword name="UnittestDialog (Module)" id="UnittestDialog (Module)" ref="eric7.PyUnit.UnittestDialog.html" />
-      <keyword name="UnittestDialog.__UTDiscovered" id="UnittestDialog.__UTDiscovered" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__UTDiscovered" />
-      <keyword name="UnittestDialog.__UTPrepared" id="UnittestDialog.__UTPrepared" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__UTPrepared" />
-      <keyword name="UnittestDialog.__assembleTestCasesList" id="UnittestDialog.__assembleTestCasesList" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__assembleTestCasesList" />
-      <keyword name="UnittestDialog.__discover" id="UnittestDialog.__discover" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__discover" />
-      <keyword name="UnittestDialog.__findDiscoveryItem" id="UnittestDialog.__findDiscoveryItem" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__findDiscoveryItem" />
-      <keyword name="UnittestDialog.__loadRecent" id="UnittestDialog.__loadRecent" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__loadRecent" />
-      <keyword name="UnittestDialog.__openEditor" id="UnittestDialog.__openEditor" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__openEditor" />
-      <keyword name="UnittestDialog.__populateDiscoveryResults" id="UnittestDialog.__populateDiscoveryResults" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__populateDiscoveryResults" />
-      <keyword name="UnittestDialog.__populateVenvComboBox" id="UnittestDialog.__populateVenvComboBox" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__populateVenvComboBox" />
-      <keyword name="UnittestDialog.__saveRecent" id="UnittestDialog.__saveRecent" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__saveRecent" />
-      <keyword name="UnittestDialog.__selectedTestCases" id="UnittestDialog.__selectedTestCases" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__selectedTestCases" />
-      <keyword name="UnittestDialog.__setProgressColor" id="UnittestDialog.__setProgressColor" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__setProgressColor" />
-      <keyword name="UnittestDialog.__setRunningMode" id="UnittestDialog.__setRunningMode" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__setRunningMode" />
-      <keyword name="UnittestDialog.__setStoppedMode" id="UnittestDialog.__setStoppedMode" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__setStoppedMode" />
-      <keyword name="UnittestDialog.__showSource" id="UnittestDialog.__showSource" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__showSource" />
-      <keyword name="UnittestDialog.__stopTests" id="UnittestDialog.__stopTests" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.__stopTests" />
-      <keyword name="UnittestDialog.clearRecent" id="UnittestDialog.clearRecent" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.clearRecent" />
-      <keyword name="UnittestDialog.closeEvent" id="UnittestDialog.closeEvent" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.closeEvent" />
-      <keyword name="UnittestDialog.hasFailedTests" id="UnittestDialog.hasFailedTests" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.hasFailedTests" />
-      <keyword name="UnittestDialog.insertDiscovery" id="UnittestDialog.insertDiscovery" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.insertDiscovery" />
-      <keyword name="UnittestDialog.insertProg" id="UnittestDialog.insertProg" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.insertProg" />
-      <keyword name="UnittestDialog.insertTestName" id="UnittestDialog.insertTestName" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.insertTestName" />
-      <keyword name="UnittestDialog.keyPressEvent" id="UnittestDialog.keyPressEvent" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.keyPressEvent" />
-      <keyword name="UnittestDialog.on_buttonBox_clicked" id="UnittestDialog.on_buttonBox_clicked" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_buttonBox_clicked" />
-      <keyword name="UnittestDialog.on_discoverCheckBox_toggled" id="UnittestDialog.on_discoverCheckBox_toggled" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_discoverCheckBox_toggled" />
-      <keyword name="UnittestDialog.on_discoveryList_itemChanged" id="UnittestDialog.on_discoveryList_itemChanged" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_discoveryList_itemChanged" />
-      <keyword name="UnittestDialog.on_discoveryList_itemDoubleClicked" id="UnittestDialog.on_discoveryList_itemDoubleClicked" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_discoveryList_itemDoubleClicked" />
-      <keyword name="UnittestDialog.on_errorsListWidget_currentTextChanged" id="UnittestDialog.on_errorsListWidget_currentTextChanged" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_errorsListWidget_currentTextChanged" />
-      <keyword name="UnittestDialog.on_errorsListWidget_itemDoubleClicked" id="UnittestDialog.on_errorsListWidget_itemDoubleClicked" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_errorsListWidget_itemDoubleClicked" />
-      <keyword name="UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog" id="UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_testsuitePicker_aboutToShowPathPickerDialog" />
-      <keyword name="UnittestDialog.on_testsuitePicker_editTextChanged" id="UnittestDialog.on_testsuitePicker_editTextChanged" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_testsuitePicker_editTextChanged" />
-      <keyword name="UnittestDialog.on_testsuitePicker_pathSelected" id="UnittestDialog.on_testsuitePicker_pathSelected" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.on_testsuitePicker_pathSelected" />
-      <keyword name="UnittestDialog.setProjectMode" id="UnittestDialog.setProjectMode" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.setProjectMode" />
-      <keyword name="UnittestDialog.startTests" id="UnittestDialog.startTests" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.startTests" />
-      <keyword name="UnittestDialog.testErrored" id="UnittestDialog.testErrored" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testErrored" />
-      <keyword name="UnittestDialog.testFailed" id="UnittestDialog.testFailed" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testFailed" />
-      <keyword name="UnittestDialog.testFailedExpected" id="UnittestDialog.testFailedExpected" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testFailedExpected" />
-      <keyword name="UnittestDialog.testFinished" id="UnittestDialog.testFinished" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testFinished" />
-      <keyword name="UnittestDialog.testSkipped" id="UnittestDialog.testSkipped" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testSkipped" />
-      <keyword name="UnittestDialog.testStarted" id="UnittestDialog.testStarted" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testStarted" />
-      <keyword name="UnittestDialog.testSucceededUnexpected" id="UnittestDialog.testSucceededUnexpected" ref="eric7.PyUnit.UnittestDialog.html#UnittestDialog.testSucceededUnexpected" />
-      <keyword name="UnittestWindow" id="UnittestWindow" ref="eric7.PyUnit.UnittestDialog.html#UnittestWindow" />
-      <keyword name="UnittestWindow (Constructor)" id="UnittestWindow (Constructor)" ref="eric7.PyUnit.UnittestDialog.html#UnittestWindow.__init__" />
-      <keyword name="UnittestWindow.eventFilter" id="UnittestWindow.eventFilter" ref="eric7.PyUnit.UnittestDialog.html#UnittestWindow.eventFilter" />
+      <keyword name="UnittestExecutor" id="UnittestExecutor" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor" />
+      <keyword name="UnittestExecutor (Constructor)" id="UnittestExecutor (Constructor)" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.__init__" />
+      <keyword name="UnittestExecutor (Module)" id="UnittestExecutor (Module)" ref="eric7.Testing.Interfaces.UnittestExecutor.html" />
+      <keyword name="UnittestExecutor.__processData" id="UnittestExecutor.__processData" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.__processData" />
+      <keyword name="UnittestExecutor.createArguments" id="UnittestExecutor.createArguments" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.createArguments" />
+      <keyword name="UnittestExecutor.finished" id="UnittestExecutor.finished" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.finished" />
+      <keyword name="UnittestExecutor.getVersions" id="UnittestExecutor.getVersions" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.getVersions" />
+      <keyword name="UnittestExecutor.hasCoverage" id="UnittestExecutor.hasCoverage" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.hasCoverage" />
+      <keyword name="UnittestExecutor.start" id="UnittestExecutor.start" ref="eric7.Testing.Interfaces.UnittestExecutor.html#UnittestExecutor.start" />
+      <keyword name="UnittestRunner (Module)" id="UnittestRunner (Module)" ref="eric7.Testing.Interfaces.UnittestRunner.html" />
       <keyword name="UnknownDevicesDialog" id="UnknownDevicesDialog" ref="eric7.MicroPython.UnknownDevicesDialog.html#UnknownDevicesDialog" />
       <keyword name="UnknownDevicesDialog (Constructor)" id="UnknownDevicesDialog (Constructor)" ref="eric7.MicroPython.UnknownDevicesDialog.html#UnknownDevicesDialog.__init__" />
       <keyword name="UnknownDevicesDialog (Module)" id="UnknownDevicesDialog (Module)" ref="eric7.MicroPython.UnknownDevicesDialog.html" />
@@ -16275,8 +16381,8 @@
       <keyword name="UserInterface.__createLayout" id="UserInterface.__createLayout" ref="eric7.UI.UserInterface.html#UserInterface.__createLayout" />
       <keyword name="UserInterface.__createObjects" id="UserInterface.__createObjects" ref="eric7.UI.UserInterface.html#UserInterface.__createObjects" />
       <keyword name="UserInterface.__createSidebarsLayout" id="UserInterface.__createSidebarsLayout" ref="eric7.UI.UserInterface.html#UserInterface.__createSidebarsLayout" />
+      <keyword name="UserInterface.__createTestingDialog" id="UserInterface.__createTestingDialog" ref="eric7.UI.UserInterface.html#UserInterface.__createTestingDialog" />
       <keyword name="UserInterface.__createToolboxesLayout" id="UserInterface.__createToolboxesLayout" ref="eric7.UI.UserInterface.html#UserInterface.__createToolboxesLayout" />
-      <keyword name="UserInterface.__createUnitTestDialog" id="UserInterface.__createUnitTestDialog" ref="eric7.UI.UserInterface.html#UserInterface.__createUnitTestDialog" />
       <keyword name="UserInterface.__customViewer" id="UserInterface.__customViewer" ref="eric7.UI.UserInterface.html#UserInterface.__customViewer" />
       <keyword name="UserInterface.__debuggingDone" id="UserInterface.__debuggingDone" ref="eric7.UI.UserInterface.html#UserInterface.__debuggingDone" />
       <keyword name="UserInterface.__debuggingStarted" id="UserInterface.__debuggingStarted" ref="eric7.UI.UserInterface.html#UserInterface.__debuggingStarted" />
@@ -16336,7 +16442,9 @@
       <keyword name="UserInterface.__reloadAPIs" id="UserInterface.__reloadAPIs" ref="eric7.UI.UserInterface.html#UserInterface.__reloadAPIs" />
       <keyword name="UserInterface.__reportBug" id="UserInterface.__reportBug" ref="eric7.UI.UserInterface.html#UserInterface.__reportBug" />
       <keyword name="UserInterface.__requestFeature" id="UserInterface.__requestFeature" ref="eric7.UI.UserInterface.html#UserInterface.__requestFeature" />
+      <keyword name="UserInterface.__rerunFailedTests" id="UserInterface.__rerunFailedTests" ref="eric7.UI.UserInterface.html#UserInterface.__rerunFailedTests" />
       <keyword name="UserInterface.__restart" id="UserInterface.__restart" ref="eric7.UI.UserInterface.html#UserInterface.__restart" />
+      <keyword name="UserInterface.__restartTest" id="UserInterface.__restartTest" ref="eric7.UI.UserInterface.html#UserInterface.__restartTest" />
       <keyword name="UserInterface.__saveCurrentViewProfile" id="UserInterface.__saveCurrentViewProfile" ref="eric7.UI.UserInterface.html#UserInterface.__saveCurrentViewProfile" />
       <keyword name="UserInterface.__saveSessionToFile" id="UserInterface.__saveSessionToFile" ref="eric7.UI.UserInterface.html#UserInterface.__saveSessionToFile" />
       <keyword name="UserInterface.__setEditProfile" id="UserInterface.__setEditProfile" ref="eric7.UI.UserInterface.html#UserInterface.__setEditProfile" />
@@ -16375,9 +16483,13 @@
       <keyword name="UserInterface.__snapshot" id="UserInterface.__snapshot" ref="eric7.UI.UserInterface.html#UserInterface.__snapshot" />
       <keyword name="UserInterface.__sqlBrowser" id="UserInterface.__sqlBrowser" ref="eric7.UI.UserInterface.html#UserInterface.__sqlBrowser" />
       <keyword name="UserInterface.__sslErrors" id="UserInterface.__sslErrors" ref="eric7.UI.UserInterface.html#UserInterface.__sslErrors" />
+      <keyword name="UserInterface.__startTestProject" id="UserInterface.__startTestProject" ref="eric7.UI.UserInterface.html#UserInterface.__startTestProject" />
+      <keyword name="UserInterface.__startTestScript" id="UserInterface.__startTestScript" ref="eric7.UI.UserInterface.html#UserInterface.__startTestScript" />
+      <keyword name="UserInterface.__startTesting" id="UserInterface.__startTesting" ref="eric7.UI.UserInterface.html#UserInterface.__startTesting" />
       <keyword name="UserInterface.__startToolProcess" id="UserInterface.__startToolProcess" ref="eric7.UI.UserInterface.html#UserInterface.__startToolProcess" />
       <keyword name="UserInterface.__startWebBrowser" id="UserInterface.__startWebBrowser" ref="eric7.UI.UserInterface.html#UserInterface.__startWebBrowser" />
       <keyword name="UserInterface.__switchTab" id="UserInterface.__switchTab" ref="eric7.UI.UserInterface.html#UserInterface.__switchTab" />
+      <keyword name="UserInterface.__testingStopped" id="UserInterface.__testingStopped" ref="eric7.UI.UserInterface.html#UserInterface.__testingStopped" />
       <keyword name="UserInterface.__toggleBottomSidebar" id="UserInterface.__toggleBottomSidebar" ref="eric7.UI.UserInterface.html#UserInterface.__toggleBottomSidebar" />
       <keyword name="UserInterface.__toggleHorizontalToolbox" id="UserInterface.__toggleHorizontalToolbox" ref="eric7.UI.UserInterface.html#UserInterface.__toggleHorizontalToolbox" />
       <keyword name="UserInterface.__toggleLeftSidebar" id="UserInterface.__toggleLeftSidebar" ref="eric7.UI.UserInterface.html#UserInterface.__toggleLeftSidebar" />
@@ -16391,12 +16503,6 @@
       <keyword name="UserInterface.__toolGroupSelected" id="UserInterface.__toolGroupSelected" ref="eric7.UI.UserInterface.html#UserInterface.__toolGroupSelected" />
       <keyword name="UserInterface.__toolGroupsConfiguration" id="UserInterface.__toolGroupsConfiguration" ref="eric7.UI.UserInterface.html#UserInterface.__toolGroupsConfiguration" />
       <keyword name="UserInterface.__toolsConfiguration" id="UserInterface.__toolsConfiguration" ref="eric7.UI.UserInterface.html#UserInterface.__toolsConfiguration" />
-      <keyword name="UserInterface.__unittest" id="UserInterface.__unittest" ref="eric7.UI.UserInterface.html#UserInterface.__unittest" />
-      <keyword name="UserInterface.__unittestProject" id="UserInterface.__unittestProject" ref="eric7.UI.UserInterface.html#UserInterface.__unittestProject" />
-      <keyword name="UserInterface.__unittestRerunFailed" id="UserInterface.__unittestRerunFailed" ref="eric7.UI.UserInterface.html#UserInterface.__unittestRerunFailed" />
-      <keyword name="UserInterface.__unittestRestart" id="UserInterface.__unittestRestart" ref="eric7.UI.UserInterface.html#UserInterface.__unittestRestart" />
-      <keyword name="UserInterface.__unittestScript" id="UserInterface.__unittestScript" ref="eric7.UI.UserInterface.html#UserInterface.__unittestScript" />
-      <keyword name="UserInterface.__unittestStopped" id="UserInterface.__unittestStopped" ref="eric7.UI.UserInterface.html#UserInterface.__unittestStopped" />
       <keyword name="UserInterface.__updateExternalToolsActions" id="UserInterface.__updateExternalToolsActions" ref="eric7.UI.UserInterface.html#UserInterface.__updateExternalToolsActions" />
       <keyword name="UserInterface.__versionToTuple" id="UserInterface.__versionToTuple" ref="eric7.UI.UserInterface.html#UserInterface.__versionToTuple" />
       <keyword name="UserInterface.__webBrowser" id="UserInterface.__webBrowser" ref="eric7.UI.UserInterface.html#UserInterface.__webBrowser" />
@@ -18037,6 +18143,7 @@
       <keyword name="__tomlSyntaxCheck" id="__tomlSyntaxCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.tomlCheckSyntax.html#__tomlSyntaxCheck" />
       <keyword name="__yamlSyntaxCheck" id="__yamlSyntaxCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.yamlCheckSyntax.html#__yamlSyntaxCheck" />
       <keyword name="_add_check" id="_add_check" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#_add_check" />
+      <keyword name="_assembleTestCasesList" id="_assembleTestCasesList" ref="eric7.Testing.Interfaces.UnittestRunner.html#_assembleTestCasesList" />
       <keyword name="_break_around_binary_operators" id="_break_around_binary_operators" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.pycodestyle.html#_break_around_binary_operators" />
       <keyword name="_buildChildrenLists" id="_buildChildrenLists" ref="eric7.Graphics.GraphicsUtilities.html#_buildChildrenLists" />
       <keyword name="_checkString" id="_checkString" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.Security.Checks.injectionSql.html#_checkString" />
@@ -18136,7 +18243,7 @@
       <keyword name="cleanupSource (Module)" id="cleanupSource (Module)" ref="cleanupSource.html" />
       <keyword name="clearPrivateData" id="clearPrivateData" ref="eric7.Plugins.PluginVcsGit.html#clearPrivateData" />
       <keyword name="clearPrivateData" id="clearPrivateData" ref="eric7.Plugins.PluginVcsMercurial.html#clearPrivateData" />
-      <keyword name="clearSavedHistories" id="clearSavedHistories" ref="eric7.PyUnit.UnittestDialog.html#clearSavedHistories" />
+      <keyword name="clearSavedHistories" id="clearSavedHistories" ref="eric7.Testing.TestingWidget.html#clearSavedHistories" />
       <keyword name="closehead (Module)" id="closehead (Module)" ref="eric7.Plugins.VcsPlugins.vcsMercurial.CloseheadExtension.closehead.html" />
       <keyword name="codeStyleBatchCheck" id="codeStyleBatchCheck" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#codeStyleBatchCheck" />
       <keyword name="codeStyleCheck" id="codeStyleCheck" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.CodeStyleChecker.html#codeStyleCheck" />
@@ -18270,10 +18377,10 @@
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_shell.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_snap.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_sqlbrowser.html#createMainWidget" />
+      <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_testing.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_tray.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_trpreviewer.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_uipreviewer.html#createMainWidget" />
-      <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_unittest.html#createMainWidget" />
       <keyword name="createMainWidget" id="createMainWidget" ref="eric7.eric7_virtualenv.html#createMainWidget" />
       <keyword name="createPosixSpawn" id="createPosixSpawn" ref="eric7.DebugClients.Python.MultiProcessDebugExtension.html#createPosixSpawn" />
       <keyword name="createPyWrapper" id="createPyWrapper" ref="install.html#createPyWrapper" />
@@ -18349,10 +18456,10 @@
       <keyword name="eric7_shell (Module)" id="eric7_shell (Module)" ref="eric7.eric7_shell.html" />
       <keyword name="eric7_snap (Module)" id="eric7_snap (Module)" ref="eric7.eric7_snap.html" />
       <keyword name="eric7_sqlbrowser (Module)" id="eric7_sqlbrowser (Module)" ref="eric7.eric7_sqlbrowser.html" />
+      <keyword name="eric7_testing (Module)" id="eric7_testing (Module)" ref="eric7.eric7_testing.html" />
       <keyword name="eric7_tray (Module)" id="eric7_tray (Module)" ref="eric7.eric7_tray.html" />
       <keyword name="eric7_trpreviewer (Module)" id="eric7_trpreviewer (Module)" ref="eric7.eric7_trpreviewer.html" />
       <keyword name="eric7_uipreviewer (Module)" id="eric7_uipreviewer (Module)" ref="eric7.eric7_uipreviewer.html" />
-      <keyword name="eric7_unittest (Module)" id="eric7_unittest (Module)" ref="eric7.eric7_unittest.html" />
       <keyword name="eric7_virtualenv (Module)" id="eric7_virtualenv (Module)" ref="eric7.eric7_virtualenv.html" />
       <keyword name="eric7config (Module)" id="eric7config (Module)" ref="eric7.eric7config.html" />
       <keyword name="eric7dbgstub (Module)" id="eric7dbgstub (Module)" ref="eric7.DebugClients.Python.eric7dbgstub.html" />
@@ -18463,6 +18570,8 @@
       <keyword name="getConfigPath" id="getConfigPath" ref="eric7.Plugins.VcsPlugins.vcsSubversion.SvnUtilities.html#getConfigPath" />
       <keyword name="getCooperation" id="getCooperation" ref="eric7.Preferences.__init__.html#getCooperation" />
       <keyword name="getCorba" id="getCorba" ref="eric7.Preferences.__init__.html#getCorba" />
+      <keyword name="getCoverageFileName" id="getCoverageFileName" ref="eric7.Utilities.__init__.html#getCoverageFileName" />
+      <keyword name="getCoverageFileNames" id="getCoverageFileNames" ref="eric7.Utilities.__init__.html#getCoverageFileNames" />
       <keyword name="getDataFiles" id="getDataFiles" ref="setup.html#getDataFiles" />
       <keyword name="getDebugger" id="getDebugger" ref="eric7.Preferences.__init__.html#getDebugger" />
       <keyword name="getDefaultIconPaths" id="getDefaultIconPaths" ref="eric7.Toolbox.Startup.html#getDefaultIconPaths" />
@@ -18545,6 +18654,8 @@
       <keyword name="getPixmap" id="getPixmap" ref="eric7.UI.PixmapCache.html#getPixmap" />
       <keyword name="getPluginManager" id="getPluginManager" ref="eric7.Preferences.__init__.html#getPluginManager" />
       <keyword name="getPrinter" id="getPrinter" ref="eric7.Preferences.__init__.html#getPrinter" />
+      <keyword name="getProfileFileName" id="getProfileFileName" ref="eric7.Utilities.__init__.html#getProfileFileName" />
+      <keyword name="getProfileFileNames" id="getProfileFileNames" ref="eric7.Utilities.__init__.html#getProfileFileNames" />
       <keyword name="getProject" id="getProject" ref="eric7.Preferences.__init__.html#getProject" />
       <keyword name="getProjectBrowserColour" id="getProjectBrowserColour" ref="eric7.Preferences.__init__.html#getProjectBrowserColour" />
       <keyword name="getProjectBrowserFlags" id="getProjectBrowserFlags" ref="eric7.Preferences.__init__.html#getProjectBrowserFlags" />
@@ -18583,7 +18694,7 @@
       <keyword name="getSystem" id="getSystem" ref="eric7.Preferences.__init__.html#getSystem" />
       <keyword name="getTasks" id="getTasks" ref="eric7.Preferences.__init__.html#getTasks" />
       <keyword name="getTemplates" id="getTemplates" ref="eric7.Preferences.__init__.html#getTemplates" />
-      <keyword name="getTestFileName" id="getTestFileName" ref="eric7.Utilities.__init__.html#getTestFileName" />
+      <keyword name="getTestFileNames" id="getTestFileNames" ref="eric7.Utilities.__init__.html#getTestFileNames" />
       <keyword name="getText" id="getText" ref="eric7.EricWidgets.EricTextInputDialog.html#getText" />
       <keyword name="getTranslatedMessage" id="getTranslatedMessage" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.translations.html#getTranslatedMessage" />
       <keyword name="getTranslationEngine" id="getTranslationEngine" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.__init__.html#getTranslationEngine" />
@@ -18602,6 +18713,7 @@
       <keyword name="getVcsSystemIndicator" id="getVcsSystemIndicator" ref="eric7.Plugins.PluginVcsPySvn.html#getVcsSystemIndicator" />
       <keyword name="getVcsSystemIndicator" id="getVcsSystemIndicator" ref="eric7.Plugins.PluginVcsSubversion.html#getVcsSystemIndicator" />
       <keyword name="getVersion" id="getVersion" ref="setup.html#getVersion" />
+      <keyword name="getVersions" id="getVersions" ref="eric7.Testing.Interfaces.PytestRunner.html#getVersions" />
       <keyword name="getViewManager" id="getViewManager" ref="eric7.Preferences.__init__.html#getViewManager" />
       <keyword name="getVolumeName" id="getVolumeName" ref="eric7.Utilities.__init__.html#getVolumeName" />
       <keyword name="getWebBrowser" id="getWebBrowser" ref="eric7.Preferences.__init__.html#getWebBrowser" />
@@ -18700,6 +18812,7 @@
       <keyword name="isExecutable" id="isExecutable" ref="eric7.Utilities.__init__.html#isExecutable" />
       <keyword name="isGnomeDesktop" id="isGnomeDesktop" ref="eric7.Globals.__init__.html#isGnomeDesktop" />
       <keyword name="isKdeDesktop" id="isKdeDesktop" ref="eric7.Globals.__init__.html#isKdeDesktop" />
+      <keyword name="isLanguageSupported" id="isLanguageSupported" ref="eric7.Testing.__init__.html#isLanguageSupported" />
       <keyword name="isLinuxPlatform" id="isLinuxPlatform" ref="eric7.Globals.__init__.html#isLinuxPlatform" />
       <keyword name="isMacPlatform" id="isMacPlatform" ref="eric7.Globals.__init__.html#isMacPlatform" />
       <keyword name="isNameConstant" id="isNameConstant" ref="eric7.Plugins.CheckerPlugins.CodeStyleChecker.AstUtilities.html#isNameConstant" />
@@ -18766,10 +18879,10 @@
       <keyword name="main" id="main" ref="eric7.eric7_shell.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_snap.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_sqlbrowser.html#main" />
+      <keyword name="main" id="main" ref="eric7.eric7_testing.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_tray.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_trpreviewer.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_uipreviewer.html#main" />
-      <keyword name="main" id="main" ref="eric7.eric7_unittest.html#main" />
       <keyword name="main" id="main" ref="eric7.eric7_virtualenv.html#main" />
       <keyword name="main" id="main" ref="install-debugclients.html#main" />
       <keyword name="main" id="main" ref="install-dependencies.html#main" />
@@ -18924,6 +19037,7 @@
       <keyword name="retryAbort" id="retryAbort" ref="eric7.EricWidgets.EricMessageBox.html#retryAbort" />
       <keyword name="rootPrefix" id="rootPrefix" ref="eric7.CondaInterface.__init__.html#rootPrefix" />
       <keyword name="runcall" id="runcall" ref="eric7.DebugClients.Python.eric7dbgstub.html#runcall" />
+      <keyword name="runtest" id="runtest" ref="eric7.Testing.Interfaces.UnittestRunner.html#runtest" />
       <keyword name="rxExecute" id="rxExecute" ref="eric7.Plugins.WizardPlugins.QRegularExpressionWizard.QRegularExpressionWizardServer.html#rxExecute" />
       <keyword name="rxIndex" id="rxIndex" ref="eric7.Utilities.__init__.html#rxIndex" />
       <keyword name="rxValidate" id="rxValidate" ref="eric7.Plugins.WizardPlugins.QRegularExpressionWizard.QRegularExpressionWizardServer.html#rxValidate" />
@@ -19031,6 +19145,7 @@
       <keyword name="subversion (Module)" id="subversion (Module)" ref="eric7.Plugins.VcsPlugins.vcsSubversion.subversion.html" />
       <keyword name="summarize" id="summarize" ref="eric7.DataViews.CodeMetrics.html#summarize" />
       <keyword name="supportedEngineNames" id="supportedEngineNames" ref="eric7.Plugins.UiExtensionPlugins.Translator.TranslatorEngines.__init__.html#supportedEngineNames" />
+      <keyword name="supportedLanguages" id="supportedLanguages" ref="eric7.Testing.__init__.html#supportedLanguages" />
       <keyword name="syncPreferences" id="syncPreferences" ref="eric7.Preferences.__init__.html#syncPreferences" />
       <keyword name="syntaxAndPyflakesBatchCheck" id="syntaxAndPyflakesBatchCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheck.html#syntaxAndPyflakesBatchCheck" />
       <keyword name="syntaxAndPyflakesCheck" id="syntaxAndPyflakesCheck" ref="eric7.Plugins.CheckerPlugins.SyntaxChecker.SyntaxCheck.html#syntaxAndPyflakesCheck" />
@@ -19159,10 +19274,11 @@
       <file>eric7.DataViews.CodeMetrics.html</file>
       <file>eric7.DataViews.CodeMetricsDialog.html</file>
       <file>eric7.DataViews.PyCoverageDialog.html</file>
+      <file>eric7.DataViews.PyCoverageHtmlReportDialog.html</file>
+      <file>eric7.DataViews.PyCoverageJsonReportDialog.html</file>
       <file>eric7.DataViews.PyProfileDialog.html</file>
       <file>eric7.DebugClients.Python.AsyncFile.html</file>
       <file>eric7.DebugClients.Python.BreakpointWatch.html</file>
-      <file>eric7.DebugClients.Python.DCTestResult.html</file>
       <file>eric7.DebugClients.Python.DebugBase.html</file>
       <file>eric7.DebugClients.Python.DebugClient.html</file>
       <file>eric7.DebugClients.Python.DebugClientBase.html</file>
@@ -19207,7 +19323,6 @@
       <file>eric7.DocumentationTools.IndexGenerator.html</file>
       <file>eric7.DocumentationTools.ModuleDocumentor.html</file>
       <file>eric7.DocumentationTools.QtHelpGenerator.html</file>
-      <file>eric7.DocumentationTools.TemplatesListsStyle.html</file>
       <file>eric7.DocumentationTools.TemplatesListsStyleCSS.html</file>
       <file>eric7.EricCore.EricTreeSortFilterProxyModel.html</file>
       <file>eric7.EricGraphics.EricArrowItem.html</file>
@@ -19220,6 +19335,8 @@
       <file>eric7.EricNetwork.EricGoogleMailHelpers.html</file>
       <file>eric7.EricNetwork.EricJsonClient.html</file>
       <file>eric7.EricNetwork.EricJsonServer.html</file>
+      <file>eric7.EricNetwork.EricJsonStreamReader.html</file>
+      <file>eric7.EricNetwork.EricJsonStreamWriter.html</file>
       <file>eric7.EricNetwork.EricNetworkIcon.html</file>
       <file>eric7.EricNetwork.EricNetworkProxyFactory.html</file>
       <file>eric7.EricNetwork.EricSslCertificateSelectionDialog.html</file>
@@ -19868,7 +19985,6 @@
       <file>eric7.Project.UicLoadUi6.html</file>
       <file>eric7.Project.UserProjectFile.html</file>
       <file>eric7.Project.UserPropertiesDialog.html</file>
-      <file>eric7.PyUnit.UnittestDialog.html</file>
       <file>eric7.QScintilla.APIsManager.html</file>
       <file>eric7.QScintilla.DocstringGenerator.BaseDocstringGenerator.html</file>
       <file>eric7.QScintilla.DocstringGenerator.EricdocGenerator.html</file>
@@ -19982,6 +20098,15 @@
       <file>eric7.Templates.TemplateSingleVariableDialog.html</file>
       <file>eric7.Templates.TemplateViewer.html</file>
       <file>eric7.Templates.TemplatesFile.html</file>
+      <file>eric7.Testing.Interfaces.PytestExecutor.html</file>
+      <file>eric7.Testing.Interfaces.PytestRunner.html</file>
+      <file>eric7.Testing.Interfaces.TestExecutorBase.html</file>
+      <file>eric7.Testing.Interfaces.TestFrameworkRegistry.html</file>
+      <file>eric7.Testing.Interfaces.UnittestExecutor.html</file>
+      <file>eric7.Testing.Interfaces.UnittestRunner.html</file>
+      <file>eric7.Testing.TestResultsTree.html</file>
+      <file>eric7.Testing.TestingWidget.html</file>
+      <file>eric7.Testing.__init__.html</file>
       <file>eric7.Toolbox.SingleApplication.html</file>
       <file>eric7.Toolbox.Startup.html</file>
       <file>eric7.Tools.TRPreviewer.html</file>
@@ -20273,10 +20398,10 @@
       <file>eric7.eric7_shell.html</file>
       <file>eric7.eric7_snap.html</file>
       <file>eric7.eric7_sqlbrowser.html</file>
+      <file>eric7.eric7_testing.html</file>
       <file>eric7.eric7_tray.html</file>
       <file>eric7.eric7_trpreviewer.html</file>
       <file>eric7.eric7_uipreviewer.html</file>
-      <file>eric7.eric7_unittest.html</file>
       <file>eric7.eric7_virtualenv.html</file>
       <file>eric7.eric7config.html</file>
       <file>index-eric7.CondaInterface.html</file>
@@ -20365,7 +20490,6 @@
       <file>index-eric7.Preferences.ConfigurationPages.html</file>
       <file>index-eric7.Preferences.html</file>
       <file>index-eric7.Project.html</file>
-      <file>index-eric7.PyUnit.html</file>
       <file>index-eric7.QScintilla.DocstringGenerator.html</file>
       <file>index-eric7.QScintilla.Exporters.html</file>
       <file>index-eric7.QScintilla.Lexers.html</file>
@@ -20377,6 +20501,8 @@
       <file>index-eric7.SqlBrowser.html</file>
       <file>index-eric7.Tasks.html</file>
       <file>index-eric7.Templates.html</file>
+      <file>index-eric7.Testing.Interfaces.html</file>
+      <file>index-eric7.Testing.html</file>
       <file>index-eric7.Toolbox.html</file>
       <file>index-eric7.Tools.html</file>
       <file>index-eric7.UI.Previewers.html</file>
--- a/eric7/Documentation/Source/eric7.DataViews.PyCoverageDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.DataViews.PyCoverageDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -38,6 +38,14 @@
 <p>
     Class implementing a dialog to display the collected code coverage data.
 </p>
+<h3>Signals</h3>
+<dl>
+
+<dt>openFile(str)</dt>
+<dd>
+emitted to open the given file in an editor
+</dd>
+</dl>
 <h3>Derived from</h3>
 QDialog, Ui_PyCoverageDialog
 <h3>Class Attributes</h3>
@@ -59,22 +67,10 @@
 <td>Constructor</td>
 </tr>
 <tr>
-<td><a href="#PyCoverageDialog.__annotate">__annotate</a></td>
-<td>Private slot to handle the annotate context menu action.</td>
-</tr>
-<tr>
-<td><a href="#PyCoverageDialog.__annotateAll">__annotateAll</a></td>
-<td>Private slot to handle the annotate all context menu action.</td>
-</tr>
-<tr>
 <td><a href="#PyCoverageDialog.__createResultItem">__createResultItem</a></td>
 <td>Private method to create an entry in the result list.</td>
 </tr>
 <tr>
-<td><a href="#PyCoverageDialog.__deleteAnnotated">__deleteAnnotated</a></td>
-<td>Private slot to handle the delete annotated context menu action.</td>
-</tr>
-<tr>
 <td><a href="#PyCoverageDialog.__erase">__erase</a></td>
 <td>Private slot to handle the erase context menu action.</td>
 </tr>
@@ -87,10 +83,26 @@
 <td>Private method to format a list of integers into string by coalescing groups.</td>
 </tr>
 <tr>
+<td><a href="#PyCoverageDialog.__htmlReport">__htmlReport</a></td>
+<td>Private slot to generate a HTML report of the shown data.</td>
+</tr>
+<tr>
+<td><a href="#PyCoverageDialog.__jsonReport">__jsonReport</a></td>
+<td>Private slot to generate a JSON report of the shown data.</td>
+</tr>
+<tr>
+<td><a href="#PyCoverageDialog.__lcovReport">__lcovReport</a></td>
+<td>Private slot to generate a LCOV report of the shown data.</td>
+</tr>
+<tr>
 <td><a href="#PyCoverageDialog.__openFile">__openFile</a></td>
 <td>Private slot to open the selected file.</td>
 </tr>
 <tr>
+<td><a href="#PyCoverageDialog.__prepareReportGeneration">__prepareReportGeneration</a></td>
+<td>Private method to prepare a report generation.</td>
+</tr>
+<tr>
 <td><a href="#PyCoverageDialog.__showContextMenu">__showContextMenu</a></td>
 <td>Private slot to show the context menu of the listview.</td>
 </tr>
@@ -130,33 +142,11 @@
 </p>
 <dl>
 
-<dt><i>parent</i></dt>
+<dt><i>parent</i> (QWidget)</dt>
 <dd>
-parent widget (QWidget)
+parent widget
 </dd>
 </dl>
-<a NAME="PyCoverageDialog.__annotate" ID="PyCoverageDialog.__annotate"></a>
-<h4>PyCoverageDialog.__annotate</h4>
-<b>__annotate</b>(<i></i>)
-
-<p>
-        Private slot to handle the annotate context menu action.
-</p>
-<p>
-        This method produce an annotated coverage file of the
-        selected file.
-</p>
-<a NAME="PyCoverageDialog.__annotateAll" ID="PyCoverageDialog.__annotateAll"></a>
-<h4>PyCoverageDialog.__annotateAll</h4>
-<b>__annotateAll</b>(<i></i>)
-
-<p>
-        Private slot to handle the annotate all context menu action.
-</p>
-<p>
-        This method produce an annotated coverage file of every
-        file listed in the listview.
-</p>
 <a NAME="PyCoverageDialog.__createResultItem" ID="PyCoverageDialog.__createResultItem"></a>
 <h4>PyCoverageDialog.__createResultItem</h4>
 <b>__createResultItem</b>(<i>file, statements, executed, coverage, excluded, missing</i>)
@@ -166,42 +156,31 @@
 </p>
 <dl>
 
-<dt><i>file</i></dt>
+<dt><i>file</i> (str)</dt>
 <dd>
-filename of file (string)
+filename of file
 </dd>
-<dt><i>statements</i></dt>
+<dt><i>statements</i> (int)</dt>
 <dd>
-amount of statements (integer)
+number of statements
 </dd>
-<dt><i>executed</i></dt>
+<dt><i>executed</i> (int)</dt>
 <dd>
-amount of executed statements (integer)
+number of executed statements
 </dd>
-<dt><i>coverage</i></dt>
+<dt><i>coverage</i> (int)</dt>
 <dd>
-percent of coverage (integer)
+percent of coverage
 </dd>
-<dt><i>excluded</i></dt>
+<dt><i>excluded</i> (str)</dt>
 <dd>
-list of excluded lines (string)
+list of excluded lines
 </dd>
-<dt><i>missing</i></dt>
+<dt><i>missing</i> (str)</dt>
 <dd>
-list of lines without coverage (string)
+list of lines without coverage
 </dd>
 </dl>
-<a NAME="PyCoverageDialog.__deleteAnnotated" ID="PyCoverageDialog.__deleteAnnotated"></a>
-<h4>PyCoverageDialog.__deleteAnnotated</h4>
-<b>__deleteAnnotated</b>(<i></i>)
-
-<p>
-        Private slot to handle the delete annotated context menu action.
-</p>
-<p>
-        This method deletes all annotated files. These are files
-        ending with ',cover'.
-</p>
 <a NAME="PyCoverageDialog.__erase" ID="PyCoverageDialog.__erase"></a>
 <h4>PyCoverageDialog.__erase</h4>
 <b>__erase</b>(<i></i>)
@@ -231,7 +210,7 @@
 </p>
 <dl>
 
-<dt><i>lines</i></dt>
+<dt><i>lines</i> (list of int)</dt>
 <dd>
 list of integers
 </dd>
@@ -242,6 +221,33 @@
 string representing the list
 </dd>
 </dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<a NAME="PyCoverageDialog.__htmlReport" ID="PyCoverageDialog.__htmlReport"></a>
+<h4>PyCoverageDialog.__htmlReport</h4>
+<b>__htmlReport</b>(<i></i>)
+
+<p>
+        Private slot to generate a HTML report of the shown data.
+</p>
+<a NAME="PyCoverageDialog.__jsonReport" ID="PyCoverageDialog.__jsonReport"></a>
+<h4>PyCoverageDialog.__jsonReport</h4>
+<b>__jsonReport</b>(<i></i>)
+
+<p>
+        Private slot to generate a JSON report of the shown data.
+</p>
+<a NAME="PyCoverageDialog.__lcovReport" ID="PyCoverageDialog.__lcovReport"></a>
+<h4>PyCoverageDialog.__lcovReport</h4>
+<b>__lcovReport</b>(<i></i>)
+
+<p>
+        Private slot to generate a LCOV report of the shown data.
+</p>
 <a NAME="PyCoverageDialog.__openFile" ID="PyCoverageDialog.__openFile"></a>
 <h4>PyCoverageDialog.__openFile</h4>
 <b>__openFile</b>(<i>itm=None</i>)
@@ -251,9 +257,29 @@
 </p>
 <dl>
 
-<dt><i>itm</i></dt>
+<dt><i>itm</i> (QTreeWidgetItem)</dt>
 <dd>
-reference to the item to be opened (QTreeWidgetItem)
+reference to the item to be opened
+</dd>
+</dl>
+<a NAME="PyCoverageDialog.__prepareReportGeneration" ID="PyCoverageDialog.__prepareReportGeneration"></a>
+<h4>PyCoverageDialog.__prepareReportGeneration</h4>
+<b>__prepareReportGeneration</b>(<i></i>)
+
+<p>
+        Private method to prepare a report generation.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+tuple containing a reference to the Coverage object and the
+            list of files to report
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+tuple of (Coverage, list of str)
 </dd>
 </dl>
 <a NAME="PyCoverageDialog.__showContextMenu" ID="PyCoverageDialog.__showContextMenu"></a>
@@ -265,9 +291,9 @@
 </p>
 <dl>
 
-<dt><i>coord</i></dt>
+<dt><i>coord</i> (QPoint)</dt>
 <dd>
-the position of the mouse pointer (QPoint)
+position of the mouse pointer
 </dd>
 </dl>
 <a NAME="PyCoverageDialog.on_buttonBox_clicked" ID="PyCoverageDialog.on_buttonBox_clicked"></a>
@@ -279,9 +305,9 @@
 </p>
 <dl>
 
-<dt><i>button</i></dt>
+<dt><i>button</i> (QAbstractButton)</dt>
 <dd>
-button that was clicked (QAbstractButton)
+button that was clicked
 </dd>
 </dl>
 <a NAME="PyCoverageDialog.on_reloadButton_clicked" ID="PyCoverageDialog.on_reloadButton_clicked"></a>
@@ -318,14 +344,13 @@
 </p>
 <dl>
 
-<dt><i>cfn</i></dt>
+<dt><i>cfn</i> (str)</dt>
 <dd>
-basename of the coverage file (string)
+basename of the coverage file
 </dd>
-<dt><i>fn</i></dt>
+<dt><i>fn</i> (str or list of str)</dt>
 <dd>
 file or list of files or directory to be checked
-                (string or list of strings)
 </dd>
 </dl>
 <a NAME="PyCoverageDialog.stringify" ID="PyCoverageDialog.stringify"></a>
@@ -338,11 +363,23 @@
 </p>
 <dl>
 
-<dt><i>pair</i></dt>
+<dt><i>pair</i> (tuple of (int, int)</dt>
 <dd>
 pair of integers
 </dd>
 </dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+representation of the pair
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</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.DebugClients.Python.DebugClientBase.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.DebugClients.Python.DebugClientBase.html	Wed Jun 01 13:48:49 2022 +0200
@@ -89,10 +89,6 @@
 <td>Constructor</td>
 </tr>
 <tr>
-<td><a href="#DebugClientBase.__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="#DebugClientBase.__clientCapabilities">__clientCapabilities</a></td>
 <td>Private method to determine the clients capabilities.</td>
 </tr>
@@ -282,38 +278,6 @@
 <p>
         Constructor
 </p>
-<a NAME="DebugClientBase.__assembleTestCasesList" ID="DebugClientBase.__assembleTestCasesList"></a>
-<h4>DebugClientBase.__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="DebugClientBase.__clientCapabilities" ID="DebugClientBase.__clientCapabilities"></a>
 <h4>DebugClientBase.__clientCapabilities</h4>
 <b>__clientCapabilities</b>(<i></i>)
--- a/eric7/Documentation/Source/eric7.DebugClients.Python.DebugClientCapabilities.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.DebugClients.Python.DebugClientCapabilities.html	Wed Jun 01 13:48:49 2022 +0200
@@ -14,7 +14,7 @@
 <h3>Global Attributes</h3>
 
 <table>
-<tr><td>HasAll</td></tr><tr><td>HasCompleter</td></tr><tr><td>HasCoverage</td></tr><tr><td>HasDebugger</td></tr><tr><td>HasInterpreter</td></tr><tr><td>HasProfiler</td></tr><tr><td>HasShell</td></tr><tr><td>HasUnittest</td></tr>
+<tr><td>HasAll</td></tr><tr><td>HasCompleter</td></tr><tr><td>HasCoverage</td></tr><tr><td>HasDebugger</td></tr><tr><td>HasInterpreter</td></tr><tr><td>HasProfiler</td></tr><tr><td>HasShell</td></tr>
 </table>
 <h3>Classes</h3>
 
--- a/eric7/Documentation/Source/eric7.Debugger.DebugClientCapabilities.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Debugger.DebugClientCapabilities.html	Wed Jun 01 13:48:49 2022 +0200
@@ -14,7 +14,7 @@
 <h3>Global Attributes</h3>
 
 <table>
-<tr><td>HasAll</td></tr><tr><td>HasCompleter</td></tr><tr><td>HasCoverage</td></tr><tr><td>HasDebugger</td></tr><tr><td>HasInterpreter</td></tr><tr><td>HasProfiler</td></tr><tr><td>HasShell</td></tr><tr><td>HasUnittest</td></tr>
+<tr><td>HasAll</td></tr><tr><td>HasCompleter</td></tr><tr><td>HasCoverage</td></tr><tr><td>HasDebugger</td></tr><tr><td>HasInterpreter</td></tr><tr><td>HasProfiler</td></tr><tr><td>HasShell</td></tr>
 </table>
 <h3>Classes</h3>
 
--- a/eric7/Documentation/Source/eric7.Debugger.DebugServer.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Debugger.DebugServer.html	Wed Jun 01 13:48:49 2022 +0200
@@ -208,55 +208,6 @@
 emitted after the debug client has
         connected in passive debug mode
 </dd>
-<dt>utDiscovered(testCases, exc_type, exc_value)</dt>
-<dd>
-emitted after the
-        client has performed a test case discovery action
-</dd>
-<dt>utFinished()</dt>
-<dd>
-emitted after the client signalled the end of the
-        unittest
-</dd>
-<dt>utPrepared(nrTests, exc_type, exc_value)</dt>
-<dd>
-emitted after the client
-        has loaded a unittest suite
-</dd>
-<dt>utStartTest(testname, testdocu)</dt>
-<dd>
-emitted after the client has
-        started a test
-</dd>
-<dt>utStopTest()</dt>
-<dd>
-emitted after the client has finished a test
-</dd>
-<dt>utTestErrored(testname, exc_info, id)</dt>
-<dd>
-emitted after the client
-        reported an errored test
-</dd>
-<dt>utTestFailed(testname, exc_info, id)</dt>
-<dd>
-emitted after the client
-        reported a failed test
-</dd>
-<dt>utTestFailedExpected(testname, exc_info, id)</dt>
-<dd>
-emitted after the
-        client reported an expected test failure
-</dd>
-<dt>utTestSkipped(testname, reason, id)</dt>
-<dd>
-emitted after the client
-        reported a skipped test
-</dd>
-<dt>utTestSucceededUnexpected(testname, id)</dt>
-<dd>
-emitted after the client
-        reported an unexpected test success
-</dd>
 </dl>
 <h3>Derived from</h3>
 QTcpServer
@@ -395,46 +346,6 @@
 <td>Private slot to handle the dataAboutToBeChanged signal of the watch expression model.</td>
 </tr>
 <tr>
-<td><a href="#DebugServer.clientUtDiscovered">clientUtDiscovered</a></td>
-<td>Public method to process the client unittest discover info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtFinished">clientUtFinished</a></td>
-<td>Public method to process the client unit test finished info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtPrepared">clientUtPrepared</a></td>
-<td>Public method to process the client unittest prepared info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtStartTest">clientUtStartTest</a></td>
-<td>Public method to process the client start test info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtStopTest">clientUtStopTest</a></td>
-<td>Public method to process the client stop test info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtTestErrored">clientUtTestErrored</a></td>
-<td>Public method to process the client test errored info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtTestFailed">clientUtTestFailed</a></td>
-<td>Public method to process the client test failed info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtTestFailedExpected">clientUtTestFailedExpected</a></td>
-<td>Public method to process the client test failed expected info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtTestSkipped">clientUtTestSkipped</a></td>
-<td>Public method to process the client test skipped info.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.clientUtTestSucceededUnexpected">clientUtTestSucceededUnexpected</a></td>
-<td>Public method to process the client test succeeded unexpected info.</td>
-</tr>
-<tr>
 <td><a href="#DebugServer.getBreakPointModel">getBreakPointModel</a></td>
 <td>Public slot to get a reference to the breakpoint model object.</td>
 </tr>
@@ -603,22 +514,6 @@
 <td>Public method to request the list of threads from the client.</td>
 </tr>
 <tr>
-<td><a href="#DebugServer.remoteUTDiscover">remoteUTDiscover</a></td>
-<td>Public method to perform a test case discovery.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.remoteUTPrepare">remoteUTPrepare</a></td>
-<td>Public method to prepare a new unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.remoteUTRun">remoteUTRun</a></td>
-<td>Public method to start a unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebugServer.remoteUTStop">remoteUTStop</a></td>
-<td>public method to stop a unittest run.</td>
-</tr>
-<tr>
 <td><a href="#DebugServer.setCallTraceEnabled">setCallTraceEnabled</a></td>
 <td>Public method to set the call trace state.</td>
 </tr>
@@ -1321,195 +1216,6 @@
 end index of the rows to be changed
 </dd>
 </dl>
-<a NAME="DebugServer.clientUtDiscovered" ID="DebugServer.clientUtDiscovered"></a>
-<h4>DebugServer.clientUtDiscovered</h4>
-<b>clientUtDiscovered</b>(<i>testCases, exceptionType, exceptionValue</i>)
-
-<p>
-        Public method to process the client unittest discover info.
-</p>
-<dl>
-
-<dt><i>testCases</i> (str)</dt>
-<dd>
-list of detected test cases
-</dd>
-<dt><i>exceptionType</i> (str)</dt>
-<dd>
-exception type
-</dd>
-<dt><i>exceptionValue</i> (str)</dt>
-<dd>
-exception message
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtFinished" ID="DebugServer.clientUtFinished"></a>
-<h4>DebugServer.clientUtFinished</h4>
-<b>clientUtFinished</b>(<i>status</i>)
-
-<p>
-        Public method to process the client unit test finished info.
-</p>
-<dl>
-
-<dt><i>status</i> (int)</dt>
-<dd>
-exit status of the unit test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtPrepared" ID="DebugServer.clientUtPrepared"></a>
-<h4>DebugServer.clientUtPrepared</h4>
-<b>clientUtPrepared</b>(<i>result, exceptionType, exceptionValue</i>)
-
-<p>
-        Public method to process the client unittest prepared info.
-</p>
-<dl>
-
-<dt><i>result</i> (int)</dt>
-<dd>
-number of test cases (0 = error)
-</dd>
-<dt><i>exceptionType</i> (str)</dt>
-<dd>
-exception type
-</dd>
-<dt><i>exceptionValue</i> (str)</dt>
-<dd>
-exception message
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtStartTest" ID="DebugServer.clientUtStartTest"></a>
-<h4>DebugServer.clientUtStartTest</h4>
-<b>clientUtStartTest</b>(<i>testname, doc</i>)
-
-<p>
-        Public method to process the client start test info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>doc</i> (str)</dt>
-<dd>
-short description of the test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtStopTest" ID="DebugServer.clientUtStopTest"></a>
-<h4>DebugServer.clientUtStopTest</h4>
-<b>clientUtStopTest</b>(<i></i>)
-
-<p>
-        Public method to process the client stop test info.
-</p>
-<a NAME="DebugServer.clientUtTestErrored" ID="DebugServer.clientUtTestErrored"></a>
-<h4>DebugServer.clientUtTestErrored</h4>
-<b>clientUtTestErrored</b>(<i>testname, traceback, testId</i>)
-
-<p>
-        Public method to process the client test errored info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>traceback</i> (list of str)</dt>
-<dd>
-lines of traceback info
-</dd>
-<dt><i>testId</i> (str)</dt>
-<dd>
-id of the test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtTestFailed" ID="DebugServer.clientUtTestFailed"></a>
-<h4>DebugServer.clientUtTestFailed</h4>
-<b>clientUtTestFailed</b>(<i>testname, traceback, testId</i>)
-
-<p>
-        Public method to process the client test failed info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>traceback</i> (list of str)</dt>
-<dd>
-lines of traceback info
-</dd>
-<dt><i>testId</i> (str)</dt>
-<dd>
-id of the test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtTestFailedExpected" ID="DebugServer.clientUtTestFailedExpected"></a>
-<h4>DebugServer.clientUtTestFailedExpected</h4>
-<b>clientUtTestFailedExpected</b>(<i>testname, traceback, testId</i>)
-
-<p>
-        Public method to process the client test failed expected info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>traceback</i> (list of str)</dt>
-<dd>
-lines of traceback info
-</dd>
-<dt><i>testId</i> (str)</dt>
-<dd>
-id of the test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtTestSkipped" ID="DebugServer.clientUtTestSkipped"></a>
-<h4>DebugServer.clientUtTestSkipped</h4>
-<b>clientUtTestSkipped</b>(<i>testname, reason, testId</i>)
-
-<p>
-        Public method to process the client test skipped info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>reason</i> (str)</dt>
-<dd>
-reason for skipping the test
-</dd>
-<dt><i>testId</i> (str)</dt>
-<dd>
-id of the test
-</dd>
-</dl>
-<a NAME="DebugServer.clientUtTestSucceededUnexpected" ID="DebugServer.clientUtTestSucceededUnexpected"></a>
-<h4>DebugServer.clientUtTestSucceededUnexpected</h4>
-<b>clientUtTestSucceededUnexpected</b>(<i>testname, testId</i>)
-
-<p>
-        Public method to process the client test succeeded unexpected info.
-</p>
-<dl>
-
-<dt><i>testname</i> (str)</dt>
-<dd>
-name of the test
-</dd>
-<dt><i>testId</i> (str)</dt>
-<dd>
-id of the test
-</dd>
-</dl>
 <a NAME="DebugServer.getBreakPointModel" ID="DebugServer.getBreakPointModel"></a>
 <h4>DebugServer.getBreakPointModel</h4>
 <b>getBreakPointModel</b>(<i></i>)
@@ -2464,142 +2170,6 @@
 ID of the debugger backend
 </dd>
 </dl>
-<a NAME="DebugServer.remoteUTDiscover" ID="DebugServer.remoteUTDiscover"></a>
-<h4>DebugServer.remoteUTDiscover</h4>
-<b>remoteUTDiscover</b>(<i>clientType, forProject, venvName, syspath, workdir, discoveryStart</i>)
-
-<p>
-        Public method to perform a test case discovery.
-</p>
-<dl>
-
-<dt><i>clientType</i> (str)</dt>
-<dd>
-client type to be used
-</dd>
-<dt><i>forProject</i> (bool)</dt>
-<dd>
-flag indicating a project related action
-</dd>
-<dt><i>venvName</i> (str)</dt>
-<dd>
-name of a virtual environment
-</dd>
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-</dl>
-<a NAME="DebugServer.remoteUTPrepare" ID="DebugServer.remoteUTPrepare"></a>
-<h4>DebugServer.remoteUTPrepare</h4>
-<b>remoteUTPrepare</b>(<i>fn, tn, tfn, failed, cov, covname, coverase, clientType="", forProject=False, venvName="", syspath=None, workdir="", discover=False, discoveryStart="", testCases=None, debug=False</i>)
-
-<p>
-        Public method to prepare a new unittest run.
-</p>
-<dl>
-
-<dt><i>fn</i> (str)</dt>
-<dd>
-the filename to load
-</dd>
-<dt><i>tn</i> (str)</dt>
-<dd>
-the testname to load
-</dd>
-<dt><i>tfn</i> (str)</dt>
-<dd>
-the test function name to load tests from
-</dd>
-<dt><i>failed</i> (list of str)</dt>
-<dd>
-list of failed test, if only failed test should be run
-</dd>
-<dt><i>cov</i> (bool)</dt>
-<dd>
-flag indicating collection of coverage data is requested
-</dd>
-<dt><i>covname</i> (str)</dt>
-<dd>
-filename to be used to assemble the coverage caches
-            filename
-</dd>
-<dt><i>coverase</i> (bool)</dt>
-<dd>
-flag indicating erasure of coverage data is requested
-</dd>
-<dt><i>clientType</i> (str)</dt>
-<dd>
-client type to be used
-</dd>
-<dt><i>forProject</i> (bool)</dt>
-<dd>
-flag indicating a project related action
-</dd>
-<dt><i>venvName</i> (str)</dt>
-<dd>
-name of a virtual environment
-</dd>
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discover</i> (bool)</dt>
-<dd>
-flag indicating to discover the tests automatically
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-<dt><i>testCases</i> (list of str)</dt>
-<dd>
-list of test cases to be loaded
-</dd>
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-</dl>
-<a NAME="DebugServer.remoteUTRun" ID="DebugServer.remoteUTRun"></a>
-<h4>DebugServer.remoteUTRun</h4>
-<b>remoteUTRun</b>(<i>debug=False, failfast=False</i>)
-
-<p>
-        Public method to start a unittest run.
-</p>
-<dl>
-
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-<dt><i>failfast</i> (bool)</dt>
-<dd>
-flag indicating to stop at the first error
-</dd>
-</dl>
-<a NAME="DebugServer.remoteUTStop" ID="DebugServer.remoteUTStop"></a>
-<h4>DebugServer.remoteUTStop</h4>
-<b>remoteUTStop</b>(<i></i>)
-
-<p>
-        public method to stop a unittest run.
-</p>
 <a NAME="DebugServer.setCallTraceEnabled" ID="DebugServer.setCallTraceEnabled"></a>
 <h4>DebugServer.setCallTraceEnabled</h4>
 <b>setCallTraceEnabled</b>(<i>debuggerId, on</i>)
--- a/eric7/Documentation/Source/eric7.Debugger.DebuggerInterfaceNone.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Debugger.DebuggerInterfaceNone.html	Wed Jun 01 13:48:49 2022 +0200
@@ -195,22 +195,6 @@
 <td>Public method to request the list of threads from the client.</td>
 </tr>
 <tr>
-<td><a href="#DebuggerInterfaceNone.remoteUTDiscover">remoteUTDiscover</a></td>
-<td>Public method to perform a test case discovery.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfaceNone.remoteUTPrepare">remoteUTPrepare</a></td>
-<td>Public method to prepare a new unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfaceNone.remoteUTRun">remoteUTRun</a></td>
-<td>Public method to start a unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfaceNone.remoteUTStop">remoteUTStop</a></td>
-<td>public method to stop a unittest run.</td>
-</tr>
-<tr>
 <td><a href="#DebuggerInterfaceNone.remoteWatchpoint">remoteWatchpoint</a></td>
 <td>Public method to set or clear a watch expression.</td>
 </tr>
@@ -918,118 +902,6 @@
 ID of the debugger backend
 </dd>
 </dl>
-<a NAME="DebuggerInterfaceNone.remoteUTDiscover" ID="DebuggerInterfaceNone.remoteUTDiscover"></a>
-<h4>DebuggerInterfaceNone.remoteUTDiscover</h4>
-<b>remoteUTDiscover</b>(<i>syspath, workdir, discoveryStart</i>)
-
-<p>
-        Public method to perform a test case discovery.
-</p>
-<dl>
-
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-</dl>
-<a NAME="DebuggerInterfaceNone.remoteUTPrepare" ID="DebuggerInterfaceNone.remoteUTPrepare"></a>
-<h4>DebuggerInterfaceNone.remoteUTPrepare</h4>
-<b>remoteUTPrepare</b>(<i>fn, tn, tfn, failed, cov, covname, coverase, syspath, workdir, discover, discoveryStart, testCases, debug</i>)
-
-<p>
-        Public method to prepare a new unittest run.
-</p>
-<dl>
-
-<dt><i>fn</i> (str)</dt>
-<dd>
-name of file to load
-</dd>
-<dt><i>tn</i> (str)</dt>
-<dd>
-name of test to load
-</dd>
-<dt><i>tfn</i> (str)</dt>
-<dd>
-test function name to load tests from
-</dd>
-<dt><i>failed</i> (list of str)</dt>
-<dd>
-list of failed test, if only failed test should be run
-</dd>
-<dt><i>cov</i> (bool)</dt>
-<dd>
-flag indicating collection of coverage data is requested
-</dd>
-<dt><i>covname</i> (str)</dt>
-<dd>
-name of file to be used to assemble the coverage caches
-            filename
-</dd>
-<dt><i>coverase</i> (bool)</dt>
-<dd>
-flag indicating erasure of coverage data is requested
-</dd>
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discover</i> (bool)</dt>
-<dd>
-flag indicating to discover the tests automatically
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-<dt><i>testCases</i> (list of str)</dt>
-<dd>
-list of test cases to be loaded
-</dd>
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-</dl>
-<a NAME="DebuggerInterfaceNone.remoteUTRun" ID="DebuggerInterfaceNone.remoteUTRun"></a>
-<h4>DebuggerInterfaceNone.remoteUTRun</h4>
-<b>remoteUTRun</b>(<i>debug, failfast</i>)
-
-<p>
-        Public method to start a unittest run.
-</p>
-<dl>
-
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-<dt><i>failfast</i> (bool)</dt>
-<dd>
-flag indicating to stop at the first error
-</dd>
-</dl>
-<a NAME="DebuggerInterfaceNone.remoteUTStop" ID="DebuggerInterfaceNone.remoteUTStop"></a>
-<h4>DebuggerInterfaceNone.remoteUTStop</h4>
-<b>remoteUTStop</b>(<i></i>)
-
-<p>
-        public method to stop a unittest run.
-</p>
 <a NAME="DebuggerInterfaceNone.remoteWatchpoint" ID="DebuggerInterfaceNone.remoteWatchpoint"></a>
 <h4>DebuggerInterfaceNone.remoteWatchpoint</h4>
 <b>remoteWatchpoint</b>(<i>debuggerId, cond, setWatch, temp=False</i>)
--- a/eric7/Documentation/Source/eric7.Debugger.DebuggerInterfacePython.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Debugger.DebuggerInterfacePython.html	Wed Jun 01 13:48:49 2022 +0200
@@ -240,22 +240,6 @@
 <td>Public method to request the list of threads from the client.</td>
 </tr>
 <tr>
-<td><a href="#DebuggerInterfacePython.remoteUTDiscover">remoteUTDiscover</a></td>
-<td>Public method to perform a test case discovery.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfacePython.remoteUTPrepare">remoteUTPrepare</a></td>
-<td>Public method to prepare a new unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfacePython.remoteUTRun">remoteUTRun</a></td>
-<td>Public method to start a unittest run.</td>
-</tr>
-<tr>
-<td><a href="#DebuggerInterfacePython.remoteUTStop">remoteUTStop</a></td>
-<td>Public method to stop a unittest run.</td>
-</tr>
-<tr>
 <td><a href="#DebuggerInterfacePython.remoteWatchpoint">remoteWatchpoint</a></td>
 <td>Public method to set or clear a watch expression.</td>
 </tr>
@@ -1196,118 +1180,6 @@
 ID of the debugger backend
 </dd>
 </dl>
-<a NAME="DebuggerInterfacePython.remoteUTDiscover" ID="DebuggerInterfacePython.remoteUTDiscover"></a>
-<h4>DebuggerInterfacePython.remoteUTDiscover</h4>
-<b>remoteUTDiscover</b>(<i>syspath, workdir, discoveryStart</i>)
-
-<p>
-        Public method to perform a test case discovery.
-</p>
-<dl>
-
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-</dl>
-<a NAME="DebuggerInterfacePython.remoteUTPrepare" ID="DebuggerInterfacePython.remoteUTPrepare"></a>
-<h4>DebuggerInterfacePython.remoteUTPrepare</h4>
-<b>remoteUTPrepare</b>(<i>fn, tn, tfn, failed, cov, covname, coverase, syspath, workdir, discover, discoveryStart, testCases, debug</i>)
-
-<p>
-        Public method to prepare a new unittest run.
-</p>
-<dl>
-
-<dt><i>fn</i> (str)</dt>
-<dd>
-name of file to load
-</dd>
-<dt><i>tn</i> (str)</dt>
-<dd>
-name of test to load
-</dd>
-<dt><i>tfn</i> (str)</dt>
-<dd>
-test function name to load tests from
-</dd>
-<dt><i>failed</i> (list of str)</dt>
-<dd>
-list of failed test, if only failed test should be run
-</dd>
-<dt><i>cov</i> (bool)</dt>
-<dd>
-flag indicating collection of coverage data is requested
-</dd>
-<dt><i>covname</i> (str)</dt>
-<dd>
-name of file to be used to assemble the coverage caches
-            filename
-</dd>
-<dt><i>coverase</i> (bool)</dt>
-<dd>
-flag indicating erasure of coverage data is requested
-</dd>
-<dt><i>syspath</i> (list of str)</dt>
-<dd>
-list of directories to be added to sys.path on the
-            remote side
-</dd>
-<dt><i>workdir</i> (str)</dt>
-<dd>
-path name of the working directory
-</dd>
-<dt><i>discover</i> (bool)</dt>
-<dd>
-flag indicating to discover the tests automatically
-</dd>
-<dt><i>discoveryStart</i> (str)</dt>
-<dd>
-directory to start auto-discovery at
-</dd>
-<dt><i>testCases</i> (list of str)</dt>
-<dd>
-list of test cases to be loaded
-</dd>
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-</dl>
-<a NAME="DebuggerInterfacePython.remoteUTRun" ID="DebuggerInterfacePython.remoteUTRun"></a>
-<h4>DebuggerInterfacePython.remoteUTRun</h4>
-<b>remoteUTRun</b>(<i>debug, failfast</i>)
-
-<p>
-        Public method to start a unittest run.
-</p>
-<dl>
-
-<dt><i>debug</i> (bool)</dt>
-<dd>
-flag indicating to run unittest with debugging
-</dd>
-<dt><i>failfast</i> (bool)</dt>
-<dd>
-flag indicating to stop at the first error
-</dd>
-</dl>
-<a NAME="DebuggerInterfacePython.remoteUTStop" ID="DebuggerInterfacePython.remoteUTStop"></a>
-<h4>DebuggerInterfacePython.remoteUTStop</h4>
-<b>remoteUTStop</b>(<i></i>)
-
-<p>
-        Public method to stop a unittest run.
-</p>
 <a NAME="DebuggerInterfacePython.remoteWatchpoint" ID="DebuggerInterfacePython.remoteWatchpoint"></a>
 <h4>DebuggerInterfacePython.remoteWatchpoint</h4>
 <b>remoteWatchpoint</b>(<i>debuggerId, cond, setWatch, temp=False</i>)
--- a/eric7/Documentation/Source/eric7.EricNetwork.EricJsonClient.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.EricNetwork.EricJsonClient.html	Wed Jun 01 13:48:49 2022 +0200
@@ -96,7 +96,7 @@
 
 <dt><i>host</i> (str)</dt>
 <dd>
-ip address the background service is listening
+IP address the background service is listening
 </dd>
 <dt><i>port</i> (int)</dt>
 <dd>
--- a/eric7/Documentation/Source/eric7.EricNetwork.EricJsonServer.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.EricNetwork.EricJsonServer.html	Wed Jun 01 13:48:49 2022 +0200
@@ -148,7 +148,7 @@
 
 <dt><i>idString</i> (str)</dt>
 <dd>
-id of the connection been disconnected
+id of the connection
 </dd>
 </dl>
 <a NAME="EricJsonServer.connectionNames" ID="EricJsonServer.connectionNames"></a>
--- a/eric7/Documentation/Source/eric7.EricWidgets.EricPlainTextDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.EricWidgets.EricPlainTextDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -62,6 +62,10 @@
 <td><a href="#EricPlainTextDialog.on_copyButton_clicked">on_copyButton_clicked</a></td>
 <td>Private slot to copy the text to the clipboard.</td>
 </tr>
+<tr>
+<td><a href="#EricPlainTextDialog.toPlainText">toPlainText</a></td>
+<td>Public method to get the plain text.</td>
+</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -71,24 +75,28 @@
 
 <a NAME="EricPlainTextDialog.__init__" ID="EricPlainTextDialog.__init__"></a>
 <h4>EricPlainTextDialog (Constructor)</h4>
-<b>EricPlainTextDialog</b>(<i>title="", text="", parent=None</i>)
+<b>EricPlainTextDialog</b>(<i>title="", text="", readOnly=True, parent=None</i>)
 
 <p>
         Constructor
 </p>
 <dl>
 
-<dt><i>title</i> (str)</dt>
+<dt><i>title</i> (str (optional))</dt>
 <dd>
-title of the window
+title of the dialog (defaults to "")
 </dd>
-<dt><i>text</i> (str)</dt>
+<dt><i>text</i> (str (optional))</dt>
 <dd>
-text to be shown
+text to be shown (defaults to "")
 </dd>
-<dt><i>parent</i> (QWidget)</dt>
+<dt><i>readOnly</i> (bool (optional))</dt>
 <dd>
-reference to the parent widget
+flag indicating a read-only dialog (defaults to True)
+</dd>
+<dt><i>parent</i> (QWidget (optional))</dt>
+<dd>
+reference to the parent widget (defaults to None)
 </dd>
 </dl>
 <a NAME="EricPlainTextDialog.on_copyButton_clicked" ID="EricPlainTextDialog.on_copyButton_clicked"></a>
@@ -98,6 +106,25 @@
 <p>
         Private slot to copy the text to the clipboard.
 </p>
+<a NAME="EricPlainTextDialog.toPlainText" ID="EricPlainTextDialog.toPlainText"></a>
+<h4>EricPlainTextDialog.toPlainText</h4>
+<b>toPlainText</b>(<i></i>)
+
+<p>
+        Public method to get the plain text.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+contents of the plain text edit
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</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.Globals.__init__.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Globals.__init__.html	Wed Jun 01 13:48:49 2022 +0200
@@ -14,7 +14,7 @@
 <h3>Global Attributes</h3>
 
 <table>
-<tr><td>configDir</td></tr><tr><td>recentNameBreakpointConditions</td></tr><tr><td>recentNameBreakpointFiles</td></tr><tr><td>recentNameFiles</td></tr><tr><td>recentNameHexFiles</td></tr><tr><td>recentNameHosts</td></tr><tr><td>recentNameMultiProject</td></tr><tr><td>recentNameProject</td></tr><tr><td>recentNameUnittestDiscoverHistory</td></tr><tr><td>recentNameUnittestFileHistory</td></tr><tr><td>recentNameUnittestTestnameHistory</td></tr><tr><td>settingsNameGlobal</td></tr><tr><td>settingsNameOrganization</td></tr><tr><td>settingsNameRecent</td></tr>
+<tr><td>configDir</td></tr><tr><td>recentNameBreakpointConditions</td></tr><tr><td>recentNameBreakpointFiles</td></tr><tr><td>recentNameFiles</td></tr><tr><td>recentNameHexFiles</td></tr><tr><td>recentNameHosts</td></tr><tr><td>recentNameMultiProject</td></tr><tr><td>recentNameProject</td></tr><tr><td>recentNameTestDiscoverHistory</td></tr><tr><td>recentNameTestEnvironment</td></tr><tr><td>recentNameTestFileHistory</td></tr><tr><td>recentNameTestFramework</td></tr><tr><td>recentNameTestNameHistory</td></tr><tr><td>settingsNameGlobal</td></tr><tr><td>settingsNameOrganization</td></tr><tr><td>settingsNameRecent</td></tr>
 </table>
 <h3>Classes</h3>
 
--- a/eric7/Documentation/Source/eric7.PipInterface.PipLicensesDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.PipInterface.PipLicensesDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -59,6 +59,10 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#PipLicensesDialog.__filterPackagesByLicense">__filterPackagesByLicense</a></td>
+<td>Private slot to filter the list of packages by license.</td>
+</tr>
+<tr>
 <td><a href="#PipLicensesDialog.__refreshLicenses">__refreshLicenses</a></td>
 <td>Private slot to refresh the license lists.</td>
 </tr>
@@ -105,6 +109,20 @@
 reference to the parent widget (defaults to None)
 </dd>
 </dl>
+<a NAME="PipLicensesDialog.__filterPackagesByLicense" ID="PipLicensesDialog.__filterPackagesByLicense"></a>
+<h4>PipLicensesDialog.__filterPackagesByLicense</h4>
+<b>__filterPackagesByLicense</b>(<i>license</i>)
+
+<p>
+        Private slot to filter the list of packages by license.
+</p>
+<dl>
+
+<dt><i>license</i> (str)</dt>
+<dd>
+license name
+</dd>
+</dl>
 <a NAME="PipLicensesDialog.__refreshLicenses" ID="PipLicensesDialog.__refreshLicenses"></a>
 <h4>PipLicensesDialog.__refreshLicenses</h4>
 <b>__refreshLicenses</b>(<i></i>)
--- a/eric7/Documentation/Source/eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Plugins.WizardPlugins.InputDialogWizard.InputDialogWizardDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -63,6 +63,10 @@
 <td>Constructor</td>
 </tr>
 <tr>
+<td><a href="#InputDialogWizardDialog.__typeSelectButtonToggled">__typeSelectButtonToggled</a></td>
+<td>Private slot to modify the dialog according to the selected type.</td>
+</tr>
+<tr>
 <td><a href="#InputDialogWizardDialog.getCode">getCode</a></td>
 <td>Public method to get the source code for Qt6.</td>
 </tr>
@@ -74,10 +78,6 @@
 <td><a href="#InputDialogWizardDialog.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="#InputDialogWizardDialog.on_rItem_toggled">on_rItem_toggled</a></td>
-<td>Private slot to perform actions dependant on the item type selection.</td>
-</tr>
 </table>
 <h3>Static Methods</h3>
 
@@ -99,6 +99,24 @@
 parent widget (QWidget)
 </dd>
 </dl>
+<a NAME="InputDialogWizardDialog.__typeSelectButtonToggled" ID="InputDialogWizardDialog.__typeSelectButtonToggled"></a>
+<h4>InputDialogWizardDialog.__typeSelectButtonToggled</h4>
+<b>__typeSelectButtonToggled</b>(<i>checked</i>)
+
+<p>
+        Private slot to modify the dialog according to the selected type.
+</p>
+<p>
+        Note: This is a multiplexed slot. Therefore it just reacts upon a
+        positive check state (i.e. checked == True).
+</p>
+<dl>
+
+<dt><i>checked</i> (bool)</dt>
+<dd>
+flag indicating the checked state
+</dd>
+</dl>
 <a NAME="InputDialogWizardDialog.getCode" ID="InputDialogWizardDialog.getCode"></a>
 <h4>InputDialogWizardDialog.getCode</h4>
 <b>getCode</b>(<i>indLevel, indString</i>)
@@ -144,20 +162,6 @@
 button that was clicked (QAbstractButton)
 </dd>
 </dl>
-<a NAME="InputDialogWizardDialog.on_rItem_toggled" ID="InputDialogWizardDialog.on_rItem_toggled"></a>
-<h4>InputDialogWizardDialog.on_rItem_toggled</h4>
-<b>on_rItem_toggled</b>(<i>checked</i>)
-
-<p>
-        Private slot to perform actions dependant on the item type selection.
-</p>
-<dl>
-
-<dt><i>checked</i></dt>
-<dd>
-flag indicating the checked state (boolean)
-</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.Project.Project.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Project.Project.html	Wed Jun 01 13:48:49 2022 +0200
@@ -741,6 +741,10 @@
 <td>Public method to get the names of the project specific dictionaries.</td>
 </tr>
 <tr>
+<td><a href="#Project.getProjectExecPath">getProjectExecPath</a></td>
+<td>Public method to get the executable search path prefix of the project.</td>
+</tr>
+<tr>
 <td><a href="#Project.getProjectFile">getProjectFile</a></td>
 <td>Public method to get the path of the project file.</td>
 </tr>
@@ -749,6 +753,10 @@
 <td>Public method to get the file entries of the given type.</td>
 </tr>
 <tr>
+<td><a href="#Project.getProjectInterpreter">getProjectInterpreter</a></td>
+<td>Public method to get the path of the interpreter used by the project.</td>
+</tr>
+<tr>
 <td><a href="#Project.getProjectLanguage">getProjectLanguage</a></td>
 <td>Public method to get the project's programming language.</td>
 </tr>
@@ -769,6 +777,10 @@
 <td>Public method to get the project's programming language.</td>
 </tr>
 <tr>
+<td><a href="#Project.getProjectTestingFramework">getProjectTestingFramework</a></td>
+<td>Public method to get the testing framework name of the project.</td>
+</tr>
+<tr>
 <td><a href="#Project.getProjectType">getProjectType</a></td>
 <td>Public method to get the type of the project.</td>
 </tr>
@@ -777,6 +789,10 @@
 <td>Public method to get the list of supported project types.</td>
 </tr>
 <tr>
+<td><a href="#Project.getProjectVenv">getProjectVenv</a></td>
+<td>Public method to get the name of the virtual environment used by the project.</td>
+</tr>
+<tr>
 <td><a href="#Project.getProjectVersion">getProjectVersion</a></td>
 <td>Public mehod to get the version number of the project.</td>
 </tr>
@@ -2557,18 +2573,27 @@
 <p>
         Public method to return the main script filename.
 </p>
+<p>
+        The normalized name is the name of the main script prepended with
+        the project path.
+</p>
 <dl>
 
-<dt><i>normalized</i></dt>
+<dt><i>normalized</i> (bool)</dt>
 <dd>
 flag indicating a normalized filename is wanted
-            (boolean)
 </dd>
 </dl>
 <dl>
 <dt>Return:</dt>
 <dd>
-filename of the projects main script (string)
+filename of the projects main script
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
 </dd>
 </dl>
 <a NAME="Project.getMenu" ID="Project.getMenu"></a>
@@ -2701,6 +2726,25 @@
             project specific word and exclude list
 </dd>
 </dl>
+<a NAME="Project.getProjectExecPath" ID="Project.getProjectExecPath"></a>
+<h4>Project.getProjectExecPath</h4>
+<b>getProjectExecPath</b>(<i></i>)
+
+<p>
+        Public method to get the executable search path prefix of the project.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+executable search path prefix
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
 <a NAME="Project.getProjectFile" ID="Project.getProjectFile"></a>
 <h4>Project.getProjectFile</h4>
 <b>getProjectFile</b>(<i></i>)
@@ -2752,6 +2796,34 @@
 raised when an unsupported file type is given
 </dd>
 </dl>
+<a NAME="Project.getProjectInterpreter" ID="Project.getProjectInterpreter"></a>
+<h4>Project.getProjectInterpreter</h4>
+<b>getProjectInterpreter</b>(<i>resolveGlobal=True</i>)
+
+<p>
+        Public method to get the path of the interpreter used by the project.
+</p>
+<dl>
+
+<dt><i>resolveGlobal</i> (bool)</dt>
+<dd>
+flag indicating to resolve the interpreter using
+            the global interpreter if no project of debugger specific
+            environment was configured
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+path of the project's interpreter
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
 <a NAME="Project.getProjectLanguage" ID="Project.getProjectLanguage"></a>
 <h4>Project.getProjectLanguage</h4>
 <b>getProjectLanguage</b>(<i></i>)
@@ -2820,6 +2892,25 @@
 programming language (string)
 </dd>
 </dl>
+<a NAME="Project.getProjectTestingFramework" ID="Project.getProjectTestingFramework"></a>
+<h4>Project.getProjectTestingFramework</h4>
+<b>getProjectTestingFramework</b>(<i></i>)
+
+<p>
+        Public method to get the testing framework name of the project.
+</p>
+<dl>
+<dt>Return:</dt>
+<dd>
+testing framework name of the project
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
 <a NAME="Project.getProjectType" ID="Project.getProjectType"></a>
 <h4>Project.getProjectType</h4>
 <b>getProjectType</b>(<i></i>)
@@ -2854,6 +2945,34 @@
 reference to the dictionary of project types.
 </dd>
 </dl>
+<a NAME="Project.getProjectVenv" ID="Project.getProjectVenv"></a>
+<h4>Project.getProjectVenv</h4>
+<b>getProjectVenv</b>(<i>resolveDebugger=True</i>)
+
+<p>
+        Public method to get the name of the virtual environment used by the
+        project.
+</p>
+<dl>
+
+<dt><i>resolveDebugger</i> (bool)</dt>
+<dd>
+flag indicating to resolve the virtual
+            environment name via the debugger settings if none was configured
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+name of the project's virtual environment
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
 <a NAME="Project.getProjectVersion" ID="Project.getProjectVersion"></a>
 <h4>Project.getProjectVersion</h4>
 <b>getProjectVersion</b>(<i></i>)
@@ -2926,16 +3045,21 @@
 </p>
 <dl>
 
-<dt><i>normalized</i></dt>
+<dt><i>normalized</i> (bool)</dt>
 <dd>
 flag indicating a normalized filename is wanted
-            (boolean)
 </dd>
 </dl>
 <dl>
 <dt>Return:</dt>
 <dd>
-list of the projects scripts (list of string)
+list of the projects scripts
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+list of str
 </dd>
 </dl>
 <a NAME="Project.getStatusMonitorAutoUpdate" ID="Project.getStatusMonitorAutoUpdate"></a>
--- a/eric7/Documentation/Source/eric7.Project.PropertiesDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Project.PropertiesDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -71,7 +71,7 @@
 <td>Private slot to handle a change of the project directory.</td>
 </tr>
 <tr>
-<td><a href="#PropertiesDialog.on_languageComboBox_currentIndexChanged">on_languageComboBox_currentIndexChanged</a></td>
+<td><a href="#PropertiesDialog.on_languageComboBox_currentTextChanged">on_languageComboBox_currentTextChanged</a></td>
 <td>Private slot handling the selection of a programming language.</td>
 </tr>
 <tr>
@@ -175,18 +175,18 @@
 name of the project directory (string)
 </dd>
 </dl>
-<a NAME="PropertiesDialog.on_languageComboBox_currentIndexChanged" ID="PropertiesDialog.on_languageComboBox_currentIndexChanged"></a>
-<h4>PropertiesDialog.on_languageComboBox_currentIndexChanged</h4>
-<b>on_languageComboBox_currentIndexChanged</b>(<i>index</i>)
+<a NAME="PropertiesDialog.on_languageComboBox_currentTextChanged" ID="PropertiesDialog.on_languageComboBox_currentTextChanged"></a>
+<h4>PropertiesDialog.on_languageComboBox_currentTextChanged</h4>
+<b>on_languageComboBox_currentTextChanged</b>(<i>language</i>)
 
 <p>
         Private slot handling the selection of a programming language.
 </p>
 <dl>
 
-<dt><i>index</i> (int)</dt>
+<dt><i>language</i> (str)</dt>
 <dd>
-index of the current item
+text of the current item
 </dd>
 </dl>
 <a NAME="PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog" ID="PropertiesDialog.on_mainscriptPicker_aboutToShowPathPickerDialog"></a>
--- a/eric7/Documentation/Source/eric7.QScintilla.Editor.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.QScintilla.Editor.html	Wed Jun 01 13:48:49 2022 +0200
@@ -2492,7 +2492,13 @@
 <dl>
 <dt>Return:</dt>
 <dd>
-file name of the coverage file (string)
+file name of the coverage file
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
 </dd>
 </dl>
 <a NAME="Editor.__getEditorConfig" ID="Editor.__getEditorConfig"></a>
@@ -4423,7 +4429,7 @@
 </p>
 <a NAME="Editor.codeCoverageShowAnnotations" ID="Editor.codeCoverageShowAnnotations"></a>
 <h4>Editor.codeCoverageShowAnnotations</h4>
-<b>codeCoverageShowAnnotations</b>(<i>silent=False</i>)
+<b>codeCoverageShowAnnotations</b>(<i>silent=False, coverageFile=None</i>)
 
 <p>
         Public method to handle the show code coverage annotations context
@@ -4431,9 +4437,15 @@
 </p>
 <dl>
 
-<dt><i>silent</i></dt>
-<dd>
-flag indicating to not show any dialog (boolean)
+<dt><i>silent</i> (bool (optional))</dt>
+<dd>
+flag indicating to not show any dialog (defaults to
+            False)
+</dd>
+<dt><i>coverageFile</i> (str (optional))</dt>
+<dd>
+path of the file containing the code coverage data
+            (defaults to None)
 </dd>
 </dl>
 <a NAME="Editor.collapseFoldWithChildren" ID="Editor.collapseFoldWithChildren"></a>
--- a/eric7/Documentation/Source/eric7.Tools.TrayStarter.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Tools.TrayStarter.html	Wed Jun 01 13:48:49 2022 +0200
@@ -175,14 +175,14 @@
 <td>Private slot to start the eric translations previewer.</td>
 </tr>
 <tr>
+<td><a href="#TrayStarter.__startTesting">__startTesting</a></td>
+<td>Private slot to start the eric testing dialog.</td>
+</tr>
+<tr>
 <td><a href="#TrayStarter.__startUIPreviewer">__startUIPreviewer</a></td>
 <td>Private slot to start the eric UI previewer.</td>
 </tr>
 <tr>
-<td><a href="#TrayStarter.__startUnittest">__startUnittest</a></td>
-<td>Private slot to start the eric unittest dialog.</td>
-</tr>
-<tr>
 <td><a href="#TrayStarter.__startVirtualenvManager">__startVirtualenvManager</a></td>
 <td>Private slot to start the eric virtual environments manager window.</td>
 </tr>
@@ -453,6 +453,13 @@
 <p>
         Private slot to start the eric translations previewer.
 </p>
+<a NAME="TrayStarter.__startTesting" ID="TrayStarter.__startTesting"></a>
+<h4>TrayStarter.__startTesting</h4>
+<b>__startTesting</b>(<i></i>)
+
+<p>
+        Private slot to start the eric testing dialog.
+</p>
 <a NAME="TrayStarter.__startUIPreviewer" ID="TrayStarter.__startUIPreviewer"></a>
 <h4>TrayStarter.__startUIPreviewer</h4>
 <b>__startUIPreviewer</b>(<i></i>)
@@ -460,13 +467,6 @@
 <p>
         Private slot to start the eric UI previewer.
 </p>
-<a NAME="TrayStarter.__startUnittest" ID="TrayStarter.__startUnittest"></a>
-<h4>TrayStarter.__startUnittest</h4>
-<b>__startUnittest</b>(<i></i>)
-
-<p>
-        Private slot to start the eric unittest dialog.
-</p>
 <a NAME="TrayStarter.__startVirtualenvManager" ID="TrayStarter.__startVirtualenvManager"></a>
 <h4>TrayStarter.__startVirtualenvManager</h4>
 <b>__startVirtualenvManager</b>(<i></i>)
--- a/eric7/Documentation/Source/eric7.UI.Browser.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.UI.Browser.html	Wed Jun 01 13:48:49 2022 +0200
@@ -99,6 +99,11 @@
 <dd>
 emitted to open a SVG file (str)
 </dd>
+<dt>testFile(filename)</dt>
+<dd>
+emitted to open a Python file for a
+        unit test (str)
+</dd>
 <dt>trpreview(filenames)</dt>
 <dd>
 emitted to preview Qt-Linguist (*.qm)
@@ -114,11 +119,6 @@
 <dd>
 emitted to open an eric UML file (str)
 </dd>
-<dt>unittestOpen(filename)</dt>
-<dd>
-emitted to open a Python file for a
-        unit test (str)
-</dd>
 </dl>
 <h3>Derived from</h3>
 QTreeView
@@ -277,8 +277,8 @@
 <td>Public slot to handle the programChange signal.</td>
 </tr>
 <tr>
-<td><a href="#Browser.handleUnittest">handleUnittest</a></td>
-<td>Public slot to handle the unittest popup menu entry.</td>
+<td><a href="#Browser.handleTesting">handleTesting</a></td>
+<td>Public slot to handle the testing popup menu entry.</td>
 </tr>
 <tr>
 <td><a href="#Browser.keyboardSearch">keyboardSearch</a></td>
@@ -683,12 +683,12 @@
 file name (string)
 </dd>
 </dl>
-<a NAME="Browser.handleUnittest" ID="Browser.handleUnittest"></a>
-<h4>Browser.handleUnittest</h4>
-<b>handleUnittest</b>(<i></i>)
+<a NAME="Browser.handleTesting" ID="Browser.handleTesting"></a>
+<h4>Browser.handleTesting</h4>
+<b>handleTesting</b>(<i></i>)
 
 <p>
-        Public slot to handle the unittest popup menu entry.
+        Public slot to handle the testing popup menu entry.
 </p>
 <a NAME="Browser.keyboardSearch" ID="Browser.keyboardSearch"></a>
 <h4>Browser.keyboardSearch</h4>
--- a/eric7/Documentation/Source/eric7.UI.ClearPrivateDataDialog.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.UI.ClearPrivateDataDialog.html	Wed Jun 01 13:48:49 2022 +0200
@@ -95,7 +95,7 @@
 <dd>
 flags indicating which data to clear
             (recent files, recent projects, recent multi projects,
-             debug histories, shell histories, unittest histories,
+             debug histories, shell histories, test histories,
              VCS histories, private data of plugins)
 </dd>
 </dl>
--- a/eric7/Documentation/Source/eric7.UI.UserInterface.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.UI.UserInterface.html	Wed Jun 01 13:48:49 2022 +0200
@@ -385,14 +385,14 @@
 <td>Private method to create the Sidebars layout.</td>
 </tr>
 <tr>
+<td><a href="#UserInterface.__createTestingDialog">__createTestingDialog</a></td>
+<td>Private slot to generate the testing dialog on demand.</td>
+</tr>
+<tr>
 <td><a href="#UserInterface.__createToolboxesLayout">__createToolboxesLayout</a></td>
 <td>Private method to create the Toolboxes layout.</td>
 </tr>
 <tr>
-<td><a href="#UserInterface.__createUnitTestDialog">__createUnitTestDialog</a></td>
-<td>Private slot to generate the unit test dialog on demand.</td>
-</tr>
-<tr>
 <td><a href="#UserInterface.__customViewer">__customViewer</a></td>
 <td>Private slot to start a custom viewer.</td>
 </tr>
@@ -629,10 +629,18 @@
 <td>Private slot to handle the Feature Request dialog.</td>
 </tr>
 <tr>
+<td><a href="#UserInterface.__rerunFailedTests">__rerunFailedTests</a></td>
+<td>Private slot to display the testing dialog and rerun all failed tests of the last run.</td>
+</tr>
+<tr>
 <td><a href="#UserInterface.__restart">__restart</a></td>
 <td>Private method to restart the application.</td>
 </tr>
 <tr>
+<td><a href="#UserInterface.__restartTest">__restartTest</a></td>
+<td>Private slot to display the testing dialog and rerun the last test run.</td>
+</tr>
+<tr>
 <td><a href="#UserInterface.__saveCurrentViewProfile">__saveCurrentViewProfile</a></td>
 <td>Private slot to save the window geometries of the active profile.</td>
 </tr>
@@ -785,6 +793,18 @@
 <td>Private slot to handle SSL errors.</td>
 </tr>
 <tr>
+<td><a href="#UserInterface.__startTestProject">__startTestProject</a></td>
+<td>Private slot for displaying the testing dialog and run the test for the current project.</td>
+</tr>
+<tr>
+<td><a href="#UserInterface.__startTestScript">__startTestScript</a></td>
+<td>Private slot for displaying the testing dialog and run the current script.</td>
+</tr>
+<tr>
+<td><a href="#UserInterface.__startTesting">__startTesting</a></td>
+<td>Private slot for displaying the testing dialog.</td>
+</tr>
+<tr>
 <td><a href="#UserInterface.__startToolProcess">__startToolProcess</a></td>
 <td>Private slot to start an external tool process.</td>
 </tr>
@@ -797,6 +817,10 @@
 <td>Private slot used to switch between the current and the previous current tab.</td>
 </tr>
 <tr>
+<td><a href="#UserInterface.__testingStopped">__testingStopped</a></td>
+<td>Private slot to handle the end of a test run.</td>
+</tr>
+<tr>
 <td><a href="#UserInterface.__toggleBottomSidebar">__toggleBottomSidebar</a></td>
 <td>Private slot to handle the toggle of the bottom sidebar window.</td>
 </tr>
@@ -849,30 +873,6 @@
 <td>Private slot to handle the tools configuration menu entry.</td>
 </tr>
 <tr>
-<td><a href="#UserInterface.__unittest">__unittest</a></td>
-<td>Private slot for displaying the unittest dialog.</td>
-</tr>
-<tr>
-<td><a href="#UserInterface.__unittestProject">__unittestProject</a></td>
-<td>Private slot for displaying the unittest dialog and run the current project.</td>
-</tr>
-<tr>
-<td><a href="#UserInterface.__unittestRerunFailed">__unittestRerunFailed</a></td>
-<td>Private slot to display the unittest dialog and rerun all failed tests of the last run.</td>
-</tr>
-<tr>
-<td><a href="#UserInterface.__unittestRestart">__unittestRestart</a></td>
-<td>Private slot to display the unittest dialog and rerun the last unit test.</td>
-</tr>
-<tr>
-<td><a href="#UserInterface.__unittestScript">__unittestScript</a></td>
-<td>Private slot for displaying the unittest dialog and run the current script.</td>
-</tr>
-<tr>
-<td><a href="#UserInterface.__unittestStopped">__unittestStopped</a></td>
-<td>Private slot to handle the end of a unit test run.</td>
-</tr>
-<tr>
 <td><a href="#UserInterface.__updateExternalToolsActions">__updateExternalToolsActions</a></td>
 <td>Private method to update the external tools actions for the current tool group.</td>
 </tr>
@@ -1612,6 +1612,13 @@
 <p>
         Private method to create the Sidebars layout.
 </p>
+<a NAME="UserInterface.__createTestingDialog" ID="UserInterface.__createTestingDialog"></a>
+<h4>UserInterface.__createTestingDialog</h4>
+<b>__createTestingDialog</b>(<i></i>)
+
+<p>
+        Private slot to generate the testing dialog on demand.
+</p>
 <a NAME="UserInterface.__createToolboxesLayout" ID="UserInterface.__createToolboxesLayout"></a>
 <h4>UserInterface.__createToolboxesLayout</h4>
 <b>__createToolboxesLayout</b>(<i></i>)
@@ -1619,13 +1626,6 @@
 <p>
         Private method to create the Toolboxes layout.
 </p>
-<a NAME="UserInterface.__createUnitTestDialog" ID="UserInterface.__createUnitTestDialog"></a>
-<h4>UserInterface.__createUnitTestDialog</h4>
-<b>__createUnitTestDialog</b>(<i></i>)
-
-<p>
-        Private slot to generate the unit test dialog on demand.
-</p>
 <a NAME="UserInterface.__customViewer" ID="UserInterface.__customViewer"></a>
 <h4>UserInterface.__customViewer</h4>
 <b>__customViewer</b>(<i>home=None</i>)
@@ -2229,6 +2229,14 @@
 <p>
         Private slot to handle the Feature Request dialog.
 </p>
+<a NAME="UserInterface.__rerunFailedTests" ID="UserInterface.__rerunFailedTests"></a>
+<h4>UserInterface.__rerunFailedTests</h4>
+<b>__rerunFailedTests</b>(<i></i>)
+
+<p>
+        Private slot to display the testing dialog and rerun all failed tests
+        of the last run.
+</p>
 <a NAME="UserInterface.__restart" ID="UserInterface.__restart"></a>
 <h4>UserInterface.__restart</h4>
 <b>__restart</b>(<i>ask=False</i>)
@@ -2243,6 +2251,14 @@
 flag indicating to ask the user for permission
 </dd>
 </dl>
+<a NAME="UserInterface.__restartTest" ID="UserInterface.__restartTest"></a>
+<h4>UserInterface.__restartTest</h4>
+<b>__restartTest</b>(<i></i>)
+
+<p>
+        Private slot to display the testing dialog and rerun the last
+        test run.
+</p>
 <a NAME="UserInterface.__saveCurrentViewProfile" ID="UserInterface.__saveCurrentViewProfile"></a>
 <h4>UserInterface.__saveCurrentViewProfile</h4>
 <b>__saveCurrentViewProfile</b>(<i>save</i>)
@@ -2634,6 +2650,36 @@
 list of SSL errors (list of QSslError)
 </dd>
 </dl>
+<a NAME="UserInterface.__startTestProject" ID="UserInterface.__startTestProject"></a>
+<h4>UserInterface.__startTestProject</h4>
+<b>__startTestProject</b>(<i></i>)
+
+<p>
+        Private slot for displaying the testing dialog and run the test for
+        the current project.
+</p>
+<a NAME="UserInterface.__startTestScript" ID="UserInterface.__startTestScript"></a>
+<h4>UserInterface.__startTestScript</h4>
+<b>__startTestScript</b>(<i>testFile=None</i>)
+
+<p>
+        Private slot for displaying the testing dialog and run the current
+        script.
+</p>
+<dl>
+
+<dt><i>testFile</i> (str)</dt>
+<dd>
+file containing the tests to be run
+</dd>
+</dl>
+<a NAME="UserInterface.__startTesting" ID="UserInterface.__startTesting"></a>
+<h4>UserInterface.__startTesting</h4>
+<b>__startTesting</b>(<i></i>)
+
+<p>
+        Private slot for displaying the testing dialog.
+</p>
 <a NAME="UserInterface.__startToolProcess" ID="UserInterface.__startToolProcess"></a>
 <h4>UserInterface.__startToolProcess</h4>
 <b>__startToolProcess</b>(<i>tool</i>)
@@ -2663,6 +2709,13 @@
         Private slot used to switch between the current and the previous
         current tab.
 </p>
+<a NAME="UserInterface.__testingStopped" ID="UserInterface.__testingStopped"></a>
+<h4>UserInterface.__testingStopped</h4>
+<b>__testingStopped</b>(<i></i>)
+
+<p>
+        Private slot to handle the end of a test run.
+</p>
 <a NAME="UserInterface.__toggleBottomSidebar" ID="UserInterface.__toggleBottomSidebar"></a>
 <h4>UserInterface.__toggleBottomSidebar</h4>
 <b>__toggleBottomSidebar</b>(<i></i>)
@@ -2799,59 +2852,6 @@
 <p>
         Private slot to handle the tools configuration menu entry.
 </p>
-<a NAME="UserInterface.__unittest" ID="UserInterface.__unittest"></a>
-<h4>UserInterface.__unittest</h4>
-<b>__unittest</b>(<i></i>)
-
-<p>
-        Private slot for displaying the unittest dialog.
-</p>
-<a NAME="UserInterface.__unittestProject" ID="UserInterface.__unittestProject"></a>
-<h4>UserInterface.__unittestProject</h4>
-<b>__unittestProject</b>(<i></i>)
-
-<p>
-        Private slot for displaying the unittest dialog and run the current
-        project.
-</p>
-<a NAME="UserInterface.__unittestRerunFailed" ID="UserInterface.__unittestRerunFailed"></a>
-<h4>UserInterface.__unittestRerunFailed</h4>
-<b>__unittestRerunFailed</b>(<i></i>)
-
-<p>
-        Private slot to display the unittest dialog and rerun all failed tests
-        of the last run.
-</p>
-<a NAME="UserInterface.__unittestRestart" ID="UserInterface.__unittestRestart"></a>
-<h4>UserInterface.__unittestRestart</h4>
-<b>__unittestRestart</b>(<i></i>)
-
-<p>
-        Private slot to display the unittest dialog and rerun the last
-        unit test.
-</p>
-<a NAME="UserInterface.__unittestScript" ID="UserInterface.__unittestScript"></a>
-<h4>UserInterface.__unittestScript</h4>
-<b>__unittestScript</b>(<i>prog=None</i>)
-
-<p>
-        Private slot for displaying the unittest dialog and run the current
-        script.
-</p>
-<dl>
-
-<dt><i>prog</i></dt>
-<dd>
-the python program to be opened
-</dd>
-</dl>
-<a NAME="UserInterface.__unittestStopped" ID="UserInterface.__unittestStopped"></a>
-<h4>UserInterface.__unittestStopped</h4>
-<b>__unittestStopped</b>(<i></i>)
-
-<p>
-        Private slot to handle the end of a unit test run.
-</p>
 <a NAME="UserInterface.__updateExternalToolsActions" ID="UserInterface.__updateExternalToolsActions"></a>
 <h4>UserInterface.__updateExternalToolsActions</h4>
 <b>__updateExternalToolsActions</b>(<i></i>)
--- a/eric7/Documentation/Source/eric7.Utilities.__init__.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/eric7.Utilities.__init__.html	Wed Jun 01 13:48:49 2022 +0200
@@ -138,6 +138,14 @@
 <td>Module function to generate a string with various version infos.</td>
 </tr>
 <tr>
+<td><a href="#getCoverageFileName">getCoverageFileName</a></td>
+<td>Function to build a file name for a coverage data file.</td>
+</tr>
+<tr>
+<td><a href="#getCoverageFileNames">getCoverageFileNames</a></td>
+<td>Function to build a list of coverage data file names.</td>
+</tr>
+<tr>
 <td><a href="#getDirs">getDirs</a></td>
 <td>Function returning a list of all directories below path.</td>
 </tr>
@@ -166,6 +174,14 @@
 <td>Function to get the help text for the supported %-codes.</td>
 </tr>
 <tr>
+<td><a href="#getProfileFileName">getProfileFileName</a></td>
+<td>Function to build a file name for a profile data file.</td>
+</tr>
+<tr>
+<td><a href="#getProfileFileNames">getProfileFileNames</a></td>
+<td>Function to build a list of profile data file names.</td>
+</tr>
+<tr>
 <td><a href="#getPythonLibPath">getPythonLibPath</a></td>
 <td>Function to determine the path to Python's library.</td>
 </tr>
@@ -186,8 +202,8 @@
 <td>Module function to get the Python path (sys.path) of a specific interpreter.</td>
 </tr>
 <tr>
-<td><a href="#getTestFileName">getTestFileName</a></td>
-<td>Function to build the filename of a unittest file.</td>
+<td><a href="#getTestFileNames">getTestFileNames</a></td>
+<td>Function to build the potential file names of a test file.</td>
 </tr>
 <tr>
 <td><a href="#getUserName">getUserName</a></td>
@@ -1241,6 +1257,69 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="getCoverageFileName" ID="getCoverageFileName"></a>
+<h2>getCoverageFileName</h2>
+<b>getCoverageFileName</b>(<i>fn, mustExist=True</i>)
+
+<p>
+    Function to build a file name for a coverage data file.
+</p>
+<dl>
+
+<dt><i>fn</i> (str)</dt>
+<dd>
+file name basis to be used for the coverage data file name
+</dd>
+<dt><i>mustExist</i> (bool (optional))</dt>
+<dd>
+flag indicating to check that the file exists (defaults
+        to True)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+coverage data file name
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getCoverageFileNames" ID="getCoverageFileNames"></a>
+<h2>getCoverageFileNames</h2>
+<b>getCoverageFileNames</b>(<i>fn</i>)
+
+<p>
+    Function to build a list of coverage data file names.
+</p>
+<dl>
+
+<dt><i>fn</i> (str)</dt>
+<dd>
+file name basis to be used for the coverage data file
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+list of existing coverage data files
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+list of str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="getDirs" ID="getDirs"></a>
 <h2>getDirs</h2>
 <b>getDirs</b>(<i>path, excludeDirs</i>)
@@ -1408,6 +1487,69 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
+<a NAME="getProfileFileName" ID="getProfileFileName"></a>
+<h2>getProfileFileName</h2>
+<b>getProfileFileName</b>(<i>fn, mustExist=True</i>)
+
+<p>
+    Function to build a file name for a profile data file.
+</p>
+<dl>
+
+<dt><i>fn</i> (str)</dt>
+<dd>
+file name basis to be used for the profile data file name
+</dd>
+<dt><i>mustExist</i> (bool (optional))</dt>
+<dd>
+flag indicating to check that the file exists (defaults
+        to True)
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+profile data file name
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
+<a NAME="getProfileFileNames" ID="getProfileFileNames"></a>
+<h2>getProfileFileNames</h2>
+<b>getProfileFileNames</b>(<i>fn</i>)
+
+<p>
+    Function to build a list of profile data file names.
+</p>
+<dl>
+
+<dt><i>fn</i> (str)</dt>
+<dd>
+file name basis to be used for the profile data file
+</dd>
+</dl>
+<dl>
+<dt>Return:</dt>
+<dd>
+list of existing profile data files
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+list of str
+</dd>
+</dl>
+<div align="right"><a href="#top">Up</a></div>
+<hr />
+<hr />
 <a NAME="getPythonLibPath" ID="getPythonLibPath"></a>
 <h2>getPythonLibPath</h2>
 <b>getPythonLibPath</b>(<i></i>)
@@ -1510,28 +1652,34 @@
 <div align="right"><a href="#top">Up</a></div>
 <hr />
 <hr />
-<a NAME="getTestFileName" ID="getTestFileName"></a>
-<h2>getTestFileName</h2>
-<b>getTestFileName</b>(<i>fn</i>)
+<a NAME="getTestFileNames" ID="getTestFileNames"></a>
+<h2>getTestFileNames</h2>
+<b>getTestFileNames</b>(<i>fn</i>)
 
 <p>
-    Function to build the filename of a unittest file.
+    Function to build the potential file names of a test file.
 </p>
 <p>
-    The filename for the unittest file is built by prepending
-    the string "test" to the filename passed into this function.
+    The file names for the test file is built by prepending the string
+    "test" and "test_" to the file name passed into this function.
 </p>
 <dl>
 
-<dt><i>fn</i></dt>
+<dt><i>fn</i> (str)</dt>
 <dd>
-filename basis to be used for the unittest filename (string)
+file name basis to be used for the test file names
 </dd>
 </dl>
 <dl>
 <dt>Return:</dt>
 <dd>
-filename of the corresponding unittest file (string)
+file names of the corresponding test file
+</dd>
+</dl>
+<dl>
+<dt>Return Type:</dt>
+<dd>
+list of str
 </dd>
 </dl>
 <div align="right"><a href="#top">Up</a></div>
--- a/eric7/Documentation/Source/index-eric7.DataViews.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/index-eric7.DataViews.html	Wed Jun 01 13:48:49 2022 +0200
@@ -28,6 +28,14 @@
 <td>Module implementing a Python code coverage dialog.</td>
 </tr>
 <tr>
+<td><a href="eric7.DataViews.PyCoverageHtmlReportDialog.html">PyCoverageHtmlReportDialog</a></td>
+<td>Module implementing a dialog to enter the parameters for a coverage HTML report.</td>
+</tr>
+<tr>
+<td><a href="eric7.DataViews.PyCoverageJsonReportDialog.html">PyCoverageJsonReportDialog</a></td>
+<td>Module implementing a dialog to enter the parameters for a coverage JSON report.</td>
+</tr>
+<tr>
 <td><a href="eric7.DataViews.PyProfileDialog.html">PyProfileDialog</a></td>
 <td>Module implementing a dialog to display profile data.</td>
 </tr>
--- a/eric7/Documentation/Source/index-eric7.DebugClients.Python.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/index-eric7.DebugClients.Python.html	Wed Jun 01 13:48:49 2022 +0200
@@ -27,10 +27,6 @@
 <td>Module implementing the breakpoint and watch class.</td>
 </tr>
 <tr>
-<td><a href="eric7.DebugClients.Python.DCTestResult.html">DCTestResult</a></td>
-<td>Module implementing a TestResult derivative for the eric debugger.</td>
-</tr>
-<tr>
 <td><a href="eric7.DebugClients.Python.DebugBase.html">DebugBase</a></td>
 <td>Module implementing the debug base class which based originally on bdb.</td>
 </tr>
--- a/eric7/Documentation/Source/index-eric7.EricNetwork.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/index-eric7.EricNetwork.html	Wed Jun 01 13:48:49 2022 +0200
@@ -44,6 +44,14 @@
 <td>Module implementing the JSON based server base class.</td>
 </tr>
 <tr>
+<td><a href="eric7.EricNetwork.EricJsonStreamReader.html">EricJsonStreamReader</a></td>
+<td>Module implementing a JSON based reader class.</td>
+</tr>
+<tr>
+<td><a href="eric7.EricNetwork.EricJsonStreamWriter.html">EricJsonStreamWriter</a></td>
+<td>Module implementing a JSON based writer class.</td>
+</tr>
+<tr>
 <td><a href="eric7.EricNetwork.EricNetworkIcon.html">EricNetworkIcon</a></td>
 <td>Module implementing a statusbar icon tracking the network status.</td>
 </tr>
--- a/eric7/Documentation/Source/index-eric7.html	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Documentation/Source/index-eric7.html	Wed Jun 01 13:48:49 2022 +0200
@@ -127,10 +127,6 @@
 <td>Package implementing the project management module of eric.</td>
 </tr>
 <tr>
-<td><a href="index-eric7.PyUnit.html">PyUnit</a></td>
-<td>Package implementing an interface to the pyunit unittest package.</td>
-</tr>
-<tr>
 <td><a href="index-eric7.QScintilla.html">QScintilla</a></td>
 <td>Package implementing the editor and shell components of the eric IDE.</td>
 </tr>
@@ -155,6 +151,10 @@
 <td>Package containing modules for the templating system.</td>
 </tr>
 <tr>
+<td><a href="index-eric7.Testing.html">Testing</a></td>
+<td>Package implementing testing functionality and interface to various test frameworks.</td>
+</tr>
+<tr>
 <td><a href="index-eric7.Toolbox.html">Toolbox</a></td>
 <td>Package implementing general purpose tools.</td>
 </tr>
@@ -272,6 +272,10 @@
 <td>eric SQL Browser.</td>
 </tr>
 <tr>
+<td><a href="eric7.eric7_testing.html">eric7_testing</a></td>
+<td>eric testing.</td>
+</tr>
+<tr>
 <td><a href="eric7.eric7_tray.html">eric7_tray</a></td>
 <td>eric Tray.</td>
 </tr>
@@ -284,10 +288,6 @@
 <td>eric UI Previewer.</td>
 </tr>
 <tr>
-<td><a href="eric7.eric7_unittest.html">eric7_unittest</a></td>
-<td>eric Unittest.</td>
-</tr>
-<tr>
 <td><a href="eric7.eric7_virtualenv.html">eric7_virtualenv</a></td>
 <td>eric Virtual Environment Manager.</td>
 </tr>
--- a/eric7/EricNetwork/EricJsonClient.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/EricNetwork/EricJsonClient.py	Wed Jun 01 13:48:49 2022 +0200
@@ -24,7 +24,7 @@
         """
         Constructor
         
-        @param host ip address the background service is listening
+        @param host IP address the background service is listening
         @type str
         @param port port of the background service
         @type int
--- a/eric7/EricNetwork/EricJsonServer.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/EricNetwork/EricJsonServer.py	Wed Jun 01 13:48:49 2022 +0200
@@ -60,10 +60,9 @@
 
         self.newConnection.connect(self.handleNewConnection)
         
-        port = self.serverPort()
         ## Note: Need the port if client is started external in debugger.
         print('JSON server ({1}) listening on: {0:d}'   # __IGNORE_WARNING__
-              .format(port, self.__name))
+              .format(self.serverPort(), self.__name))
     
     @pyqtSlot()
     def handleNewConnection(self):
@@ -131,7 +130,7 @@
         """
         Private slot handling received data from the client.
         
-        @param idString id of the connection been disconnected
+        @param idString id of the connection
         @type str
         """
         if idString:
--- a/eric7/EricWidgets/EricPlainTextDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/EricWidgets/EricPlainTextDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -18,16 +18,18 @@
     """
     Class implementing a dialog to show some plain text.
     """
-    def __init__(self, title="", text="", parent=None):
+    def __init__(self, title="", text="", readOnly=True, parent=None):
         """
         Constructor
         
-        @param title title of the window
-        @type str
-        @param text text to be shown
-        @type str
-        @param parent reference to the parent widget
-        @type QWidget
+        @param title title of the dialog (defaults to "")
+        @type str (optional)
+        @param text text to be shown (defaults to "")
+        @type str (optional)
+        @param readOnly flag indicating a read-only dialog (defaults to True)
+        @type bool (optional)
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
         """
         super().__init__(parent)
         self.setupUi(self)
@@ -39,6 +41,7 @@
         
         self.setWindowTitle(title)
         self.textEdit.setPlainText(text)
+        self.textEdit.setReadOnly(readOnly)
     
     @pyqtSlot()
     def on_copyButton_clicked(self):
@@ -48,3 +51,12 @@
         txt = self.textEdit.toPlainText()
         cb = QGuiApplication.clipboard()
         cb.setText(txt)
+    
+    def toPlainText(self):
+        """
+        Public method to get the plain text.
+        
+        @return contents of the plain text edit
+        @rtype str
+        """
+        return self.textEdit.toPlainText()
--- a/eric7/EricWidgets/EricPlainTextDialog.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/EricWidgets/EricPlainTextDialog.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>500</width>
-    <height>400</height>
+    <width>650</width>
+    <height>600</height>
    </rect>
   </property>
   <property name="windowTitle">
--- a/eric7/Globals/__init__.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Globals/__init__.py	Wed Jun 01 13:48:49 2022 +0200
@@ -35,9 +35,11 @@
 recentNameHosts = "Hosts"
 recentNameBreakpointFiles = "BreakPointFiles"
 recentNameBreakpointConditions = "BreakPointConditions"
-recentNameUnittestDiscoverHistory = "UTDiscoverHistory"
-recentNameUnittestFileHistory = "UTFileHistory"
-recentNameUnittestTestnameHistory = "UTTestnameHistory"
+recentNameTestDiscoverHistory = "UTDiscoverHistory"
+recentNameTestFileHistory = "UTFileHistory"
+recentNameTestNameHistory = "UTTestnameHistory"
+recentNameTestFramework = "UTTestFramework"
+recentNameTestEnvironment = "UTEnvironmentName"
 
 configDir = None
 
--- a/eric7/JediInterface/JediServer.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/JediInterface/JediServer.py	Wed Jun 01 13:48:49 2022 +0200
@@ -506,10 +506,11 @@
                 None,
                 self.tr("Rename Variable"),
                 self.tr("Enter the new name for the variable:"),
-                QLineEdit.EchoMode.Normal
+                QLineEdit.EchoMode.Normal,
+                editor.selectedText()
             )
             
-            if ok and newName:
+            if ok and newName and self.__vm.checkAllDirty():
                 filename = editor.getFileName()
                 line, index = editor.getCursorPosition()
                 source = editor.text()
@@ -546,7 +547,7 @@
                 QLineEdit.EchoMode.Normal
             )
             
-            if ok and newName:
+            if ok and newName and editor.checkDirty():
                 filename = editor.getFileName()
                 sLine, sIndex, eLine, eIndex = editor.getSelection()
                 source = editor.text()
@@ -580,22 +581,23 @@
             if not idString:
                 return
             
-            filename = editor.getFileName()
-            line, index = editor.getCursorPosition()
-            source = editor.text()
-            
-            self.__ensureActive(idString)
-            
-            euuid = str(uuid.uuid4())
-            self.__editors[euuid] = editor
-            
-            self.sendJson("inlineVariable", {
-                "FileName": filename,
-                "Source": source,
-                "Line": line + 1,
-                "Index": index,
-                "Uuid": euuid,
-            }, idString=idString)
+            if editor.checkDirty():
+                filename = editor.getFileName()
+                line, index = editor.getCursorPosition()
+                source = editor.text()
+                
+                self.__ensureActive(idString)
+                
+                euuid = str(uuid.uuid4())
+                self.__editors[euuid] = editor
+                
+                self.sendJson("inlineVariable", {
+                    "FileName": filename,
+                    "Source": source,
+                    "Line": line + 1,
+                    "Index": index,
+                    "Uuid": euuid,
+                }, idString=idString)
     
     @pyqtSlot()
     def refactoringExtractFunction(self):
@@ -615,7 +617,7 @@
                 QLineEdit.EchoMode.Normal
             )
             
-            if ok and newName:
+            if ok and newName and editor.checkDirty():
                 filename = editor.getFileName()
                 sLine, sIndex, eLine, eIndex = editor.getSelection()
                 source = editor.text()
@@ -852,25 +854,11 @@
         if "PATH" in clientEnv:
             clientEnv["PATH"] = self.__ui.getOriginalPathString()
         
-        if (projectLanguage.startswith("Python") or
-                projectLanguage == "MicroPython"):
-            # new code using virtual environments
-            venvManager = ericApp().getObject("VirtualEnvManager")
-            
-            # get virtual environment from project first
-            venvName = self.__ericProject.getDebugProperty("VIRTUALENV")
-            if not venvName:
-                # get it from debugger settings next
-                if projectLanguage in ("Python3", "MicroPython", "Cython"):
-                    venvName = Preferences.getDebugger("Python3VirtualEnv")
-                    if not venvName:
-                        venvName, _ = venvManager.getDefaultEnvironment()
-                else:
-                    venvName = ""
-            if venvName:
-                interpreter = venvManager.getVirtualenvInterpreter(
-                    venvName)
-                execPath = venvManager.getVirtualenvExecPath(venvName)
+        if projectLanguage in ("Python3", "MicroPython", "Cython"):
+            interpreter = self.__ericProject.getProjectInterpreter(
+                resolveGlobal=False)
+            if interpreter:
+                execPath = self.__ericProject.getProjectExecPath()
                 
                 # build a suitable environment
                 if execPath:
--- a/eric7/MicroPython/MicroPythonDevices.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/MicroPython/MicroPythonDevices.py	Wed Jun 01 13:48:49 2022 +0200
@@ -72,6 +72,7 @@
             (0x1209, 0x4DF2),       # Oak Dev Tech CAST AWAY RP2040
             (0x1209, 0x5BF0),       # Foosn Fomu
             (0x1209, 0x7150),       # Electronic Cats Hunter Cat NFC
+            (0x1209, 0x7382),       # Invector Labs AB iLabs Challenger 840
             (0x1209, 0x805A),       # Electronic Cats BastBLE
             (0x1209, 0xA182),       # Solder Party RP2040 Stamp
             (0x1209, 0xBAB0),       # Electronic Cats Bast WiFi
@@ -81,6 +82,7 @@
             (0x1209, 0xBAB6),       # Electronic Cats Escornabot Makech
             (0x1209, 0xBAB8),       # Electronic Cats NFC Copy Cat
             (0x1209, 0xC051),       # Betrusted Simmel
+            (0x1209, 0xD10D),       # Diodes Delight Piunora
             (0x1209, 0xE3E3),       # StackRduino M0 PRO
             (0x1209, 0xF500),       # Silicognition LLC M4-Shim
             (0x16D0, 0x08C6),       # Pimoroni Keybow 2040
@@ -98,6 +100,7 @@
             (0x1B4F, 0x0026),       # SparkFun Pro Micro RP2040
             (0x1B4F, 0x0027),       # SparkFun STM32 MicroMod Processor
             (0x1B4F, 0x0028),       # SparkFun Thing Plus - STM32
+            (0x1B4F, 0x002E),       # PJRC/Sparkfun Teensy MicroMod
             (0x1B4F, 0x5289),       # SparkFun SFE_nRF52840_Mini
             (0x1B4F, 0x8D22),       # SparkFun SAMD21 Mini Breakout
             (0x1B4F, 0x8D23),       # SparkFun SAMD21 Dev Breakout
@@ -115,6 +118,8 @@
             (0x2341, 0x805A),       # Arduino Arduino_Nano_33_BLE
             (0x2341, 0x824D),       # Arduino Zero
             (0x2786, 0x9207),       # Switch Sc. BLE-SS dev board Multi Sensor
+            (0x2786, 0x920D),       # Switch Sc. SSCI ISP1807 Dev Board
+            (0x2786, 0x920F),       # Switch Sc. SSCI ISP1807 Micro Board
             (0x2886, 0x002F),       # Seeed Seeeduino XIAO
             (0x2886, 0x0042),       # Seeed Seeeduino XIAO RP2040
             (0x2886, 0x0045),       # Seeed XIAO nRF52840 Sense
@@ -135,17 +140,31 @@
             (0x2E8A, 0x100A),       # Pimoroni Plasma 2040
             (0x2E8A, 0x100B),       # Invector Labs Challenger RP2040 LTE
             (0x2E8A, 0x100D),       # Invector Labs Challenger NB RP2040 WiFi
+            (0x2E8A, 0x100E),       # Raspberry Pi Zero
             (0x2E8A, 0x100F),       # Cytron Maker Nano RP2040
             (0x2E8A, 0x1012),       # Raspberry Pi Compute Module 4 IO Board
             (0x2E8A, 0x1013),       # Raspberry Pi 4B
             (0x2E8A, 0x1014),       # Raspberry Pi Compute Module 4
             (0x2E8A, 0x1015),       # Raspberry Pi Zero 2W
             (0x2E8A, 0x1016),       # Pimoroni Tiny 2040 (2MB)
-            (0x2E8A, 0xF015),       # Raspberry Pi Zero
+            (0x2E8A, 0x1019),       # Pimoroni Motor 2040
+            (0x2E8A, 0x101A),       # Pimoroni Servo 2040
+            (0x2E8A, 0x101B),       # Pimoroni Badger 2040
+            (0x2E8A, 0x101E),       # Raspberry Pi Zero W
+            (0x2E8A, 0x101F),       # Waveshare Electronics RP2040-Zero
+            (0x2E8A, 0x1026),       # ELECFREAKS Pico:ed
+            (0x2E8A, 0x1027),       # WIZnet W5100S-EVB-Pico
             (0x303A, 0x7001),       # Espressif ESP32-S2-HMI-DevKit-1
             (0x303A, 0x7003),       # Espressif ESP32-S3-DevKitC-1
+            (0x303A, 0x7003),       # Espressif ESP32-S3-DevKitC-1-N8
+            (0x303A, 0x7003),       # Espressif ESP32-S3-DevKitC-1-N8R2
+            (0x303A, 0x7003),       # Espressif ESP32-S3-DevKitC-1-N8R8
             (0x303A, 0x7003),       # Espressif ESP32-S3-DevKitC-1-nopsram
             (0x303A, 0x7005),       # Espressif ESP32-S3-Box-2.5
+            (0x303A, 0x7007),       # Espressif ESP32-S3-DevKitM-1-N8
+            (0x303A, 0x7009),       # Espressif ESP32-S2-DevKitC-1-N4
+            (0x303A, 0x7009),       # Espressif ESP32-S2-DevKitC-1-N4R2
+            (0x303A, 0x700B),       # Espressif ESP32-S3-USB-OTG-N8
             (0x303A, 0x8002),       # UnexpectedMaker TinyS2
             (0x303A, 0x8007),       # LILYGO TTGO T8 ESP32-S2
             (0x303A, 0x800D),       # Gravitech Cucumber RS
@@ -160,6 +179,13 @@
             (0x303A, 0x80B7),       # MORPHEANS MORPHESP-240
             (0x303A, 0x80C3),       # Lolin S2 Mini
             (0x303A, 0x80C6),       # Lolin S2 Pico
+            (0x303A, 0x80D1),       # UnexpectedMaker TinyS3
+            (0x303A, 0x80D4),       # UnexpectedMaker ProS3
+            (0x303A, 0x80D7),       # UnexpectedMaker FeatherS3
+            (0x303A, 0x80D9),       # FutureKeys HexKy_S2
+            (0x303A, 0x80E8),       # HiiBot IoTs2
+            (0x303A, 0x80EA),       # LILYGO TTGO T8 ESP32-S2-WROOM
+            (0x303A, 0x80ED),       # LILYGO TTGO T8 ESP32-S2
             (0x30A4, 0x0002),       # Blues Inc. Swan R5
             (0x3171, 0x0101),       # 8086.net Commander
             (0x31E2, 0x2001),       # BDMICRO LLC VINA-D21
--- a/eric7/MicroPython/UF2FlashDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/MicroPython/UF2FlashDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -386,6 +386,9 @@
             (0x239A, 0x0111): [
                 "QTPYS2BOOT",     # QT Py ESP32-S2
             ],
+            (0x239A, 0x0113): [
+                "FTHRS3BOOT",     # Feather ESP32-S3 No PSRAM
+            ],
             (0x239A, 0x0115): [
                 "FEATHERBOOT",    # Feather M4 Adalogger
             ],
@@ -459,6 +462,21 @@
             (0x303A, 0x80DA): [
                 "HEXKYBOOT",      # HexKy-S2
             ],
+            (0x303A, 0x80DE): [
+                "LEAFS3BOOT",     # BPI-Leaf-S3
+            ],
+            (0x303A, 0x80E1): [
+                "LEAFS2BOOT",     # BPI-Leaf-S2
+            ],
+            (0x303A, 0x80E4): [
+                "BITS2BOOT",      # BPI-BIT-S2
+            ],
+            (0x303A, 0x80EB): [
+                "TTGOS2BOOT",     # TTGO_T8_S2_WROOM
+            ],
+            (0x303A, 0x80EE): [
+                "TTGOS2BOOT",     # TTGO_T8_S2
+            ],
             (0x3171, 0x0100): [
                 "CMDBOOT",        # COMMANDER
             ],
--- a/eric7/PipInterface/Pip.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/Pip.py	Wed Jun 01 13:48:49 2022 +0200
@@ -203,16 +203,9 @@
         @return interpreter path
         @rtype str
         """
-        if venvName == self.getProjectEnvironmentString():
-            venvName = (
-                ericApp().getObject("Project")
-                .getDebugProperty("VIRTUALENV")
-            )
-            if not venvName:
-                # fall back to interpreter used to run eric7
-                return Globals.getPythonExecutable()
-        
         interpreter = (
+            ericApp().getObject("Project").getProjectInterpreter()
+            if venvName == self.getProjectEnvironmentString() else
             ericApp().getObject("VirtualEnvManager")
             .getVirtualenvInterpreter(venvName)
         )
@@ -1011,6 +1004,9 @@
                     "--from",
                     "mixed",
                     "--with-system",
+                    "--with-authors",
+                    "--with-urls",
+                    "--with-description",
                 ]
                 if localPackages:
                     args.append("--local-only")
--- a/eric7/PipInterface/PipLicensesDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/PipLicensesDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -8,6 +8,7 @@
 """
 
 import os
+import re
 
 from PyQt6.QtCore import pyqtSlot, Qt
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QTreeWidgetItem
@@ -53,6 +54,8 @@
         self.__pip = pip
         self.__environment = environment
         
+        self.__allFilter = self.tr("<All>")
+        
         self.__saveCSVButton = self.buttonBox.addButton(
             self.tr("Save as CSV..."), QDialogButtonBox.ButtonRole.ActionRole)
         self.__saveCSVButton.clicked.connect(self.__saveAsCSV)
@@ -74,6 +77,9 @@
             # That should never happen; play it safe.
             self.environmentLabel.setText(self.tr("No environment specified."))
         
+        self.licenseFilterComboBox.currentTextChanged.connect(
+            self.__filterPackagesByLicense)
+        
         self.__refreshLicenses()
         
     @pyqtSlot()
@@ -84,6 +90,9 @@
         with EricOverrideCursor():
             self.licensesList.clear()
             self.summaryList.clear()
+            self.licenseFilterComboBox.clear()
+            
+            licensesForFilter = set()
             
             # step 1: show the licenses per package
             self.licensesList.setUpdatesEnabled(False)
@@ -118,6 +127,7 @@
                     "{0:4d}".format(lic["Count"]),
                     lic["License"].replace("; ", "\n"),
                 ])
+                licensesForFilter |= set(lic["License"].split("; "))
             
             self.summaryList.sortItems(
                 PipLicensesDialog.SummaryLicenseColumn,
@@ -125,10 +135,36 @@
             for col in range(self.summaryList.columnCount()):
                 self.summaryList.resizeColumnToContents(col)
             self.summaryList.setUpdatesEnabled(True)
+            
+            self.licenseFilterComboBox.addItems(
+                [self.__allFilter] + sorted(licensesForFilter))
         
         enable = bool(self.licensesList.topLevelItemCount())
         self.__saveCSVButton.setEnabled(enable)
     
+    @pyqtSlot(str)
+    def __filterPackagesByLicense(self, licenseName):
+        """
+        Private slot to filter the list of packages by license.
+        
+        @param licenseName license name
+        @type str
+        """
+        pattern = r"\b{0}".format(re.escape(licenseName))
+        if not licenseName.endswith((")", "]", "}")):
+            pattern += r"\b"
+        regexp = re.compile(pattern)
+        for row in range(self.licensesList.topLevelItemCount()):
+            itm = self.licensesList.topLevelItem(row)
+            if licenseName == self.__allFilter:
+                itm.setHidden(False)
+            else:
+                itm.setHidden(
+                    regexp.search(
+                        itm.text(PipLicensesDialog.LicensesLicenseColumn)
+                    ) is None
+                )
+    
     @pyqtSlot()
     def __saveAsCSV(self):
         """
--- a/eric7/PipInterface/PipLicensesDialog.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/PipLicensesDialog.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -21,6 +21,37 @@
     <widget class="QLabel" name="environmentLabel"/>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <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>
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>License Filter:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QComboBox" name="licenseFilterComboBox">
+       <property name="toolTip">
+        <string>Select the license to filter the packages list</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
     <layout class="QHBoxLayout" name="horizontalLayout_4">
      <item>
       <widget class="QCheckBox" name="localCheckBox">
@@ -135,6 +166,7 @@
   </layout>
  </widget>
  <tabstops>
+  <tabstop>licenseFilterComboBox</tabstop>
   <tabstop>localCheckBox</tabstop>
   <tabstop>userCheckBox</tabstop>
   <tabstop>licensesList</tabstop>
--- a/eric7/PipInterface/PipPackagesWidget.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/PipPackagesWidget.py	Wed Jun 01 13:48:49 2022 +0200
@@ -101,6 +101,7 @@
             if tagClass in (
                 "package-snippet__name", "package-snippet__description",
                 "package-snippet__version", "package-snippet__released",
+                "package-snippet__created",
             ):
                 self.__activeClass = tagClass
             else:
@@ -656,7 +657,7 @@
         @param checked state of the checkbox
         @type bool
         """
-        self.on_packagesList_itemClicked(self.packagesList.currentItem(),
+        self.on_packagesList_itemPressed(self.packagesList.currentItem(),
                                          self.packagesList.currentColumn())
     
     @pyqtSlot(bool)
@@ -668,7 +669,7 @@
         @param checked state of the checkbox
         @type bool
         """
-        self.on_packagesList_itemClicked(self.packagesList.currentItem(),
+        self.on_packagesList_itemPressed(self.packagesList.currentItem(),
                                          self.packagesList.currentColumn())
     
     @pyqtSlot()
@@ -984,11 +985,16 @@
                 ])
             except KeyError:
                 description = ""
+            date = (
+                result["released"]
+                if "released" in result else
+                result["created"]
+            )
             itm = QTreeWidgetItem(
                 self.searchResultList, [
                     result['name'].strip(),
                     result['version'],
-                    result["released"].strip(),
+                    date.strip(),
                     description,
                 ])
             itm.setData(0, self.SearchVersionRole, result['version'])
--- a/eric7/PipInterface/PipVulnerabilityChecker.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/PipVulnerabilityChecker.py	Wed Jun 01 13:48:49 2022 +0200
@@ -217,9 +217,11 @@
         EricMessageBox.critical(
             None,
             self.tr("Fetching Vulnerability Database"),
-            self.tr("""<p>The vulnerability database <b>{0}</b> could not"""
-                    """ be loaded from <b>{1}</b>.</p><p>The vulnerability"""
-                    """ check is not available.</p>""")
+            self.tr(
+                """<p>The vulnerability database <b>{0}</b> could not"""
+                """ be loaded from <b>{1}</b>.</p><p>The vulnerability"""
+                """ check is not available.</p>"""
+            ).format(dbName, Preferences.getPip("VulnerabilityDbMirror"))
         )
         return {}
     
--- a/eric7/PipInterface/piplicenses.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/PipInterface/piplicenses.py	Wed Jun 01 13:48:49 2022 +0200
@@ -69,7 +69,7 @@
 
 
 __pkgname__ = 'pip-licenses'
-__version__ = '3.5.3'
+__version__ = '3.5.4'
 __author__ = 'raimon'
 __license__ = 'MIT'
 __summary__ = ('Dump the software license list of '
@@ -147,7 +147,7 @@
                                                        f))))
          for f in file_names]
         for test_file in patterns:
-            if os.path.exists(test_file):
+            if os.path.exists(test_file) and not os.path.isdir(test_file):
                 included_file = test_file
                 with open(test_file, encoding='utf-8',
                           errors='backslashreplace') as included_file_handle:
--- a/eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/CheckerPlugins/SyntaxChecker/tomlCheckSyntax.py	Wed Jun 01 13:48:49 2022 +0200
@@ -173,19 +173,21 @@
     @rtype dict
     """
     try:
-        import toml
+        import tomlkit
+        from tomlkit.exceptions import ParseError
     except ImportError:
-        error = "toml not available. Install it via the PyPI interface."
+        error = "tomlkit not available. Install it via the PyPI interface."
         return [{'error': (file, 0, 0, '', error)}]
     
     codestring = normalizeCode(codestring)
     
     try:
-        toml.loads(codestring)
-    except toml.TomlDecodeError as exc:
-        line = exc.lineno
-        column = exc.colno
-        error = exc.msg
+        tomlkit.parse(codestring)
+    except ParseError as exc:
+        line = exc.line
+        column = exc.col
+        error = str(exc).split(" at ", 1)[0].strip()
+        # get error message without location
         
         cline = min(len(codestring.splitlines()), int(line)) - 1
         code = codestring.splitlines()[cline]
--- a/eric7/Plugins/PluginVcsMercurial.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/PluginVcsMercurial.py	Wed Jun 01 13:48:49 2022 +0200
@@ -176,6 +176,7 @@
         "MqStatusDialogGeometry": QByteArray(),
         "MqStatusDialogSplitterState": QByteArray(),
         "RepositoryUrlHistory": [],
+        "MercurialExecutablePath": "",
     }
     
     def __init__(self, ui):
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.py	Wed Jun 01 13:48:49 2022 +0200
@@ -12,6 +12,7 @@
 from PyQt6.QtCore import pyqtSlot
 
 from EricWidgets.EricApplication import ericApp
+from EricWidgets.EricPathPicker import EricPathPickerModes
 
 from Preferences.ConfigurationPages.ConfigurationPageBase import (
     ConfigurationPageBase
@@ -39,12 +40,25 @@
         
         self.__plugin = plugin
         
+        self.hgPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
+        if Globals.isWindowsPlatform():
+            self.hgPicker.setFilters(self.tr(
+                "Executable Files (*.exe);;"
+                "All Files (*)"
+            ))
+        else:
+            self.hgPicker.setFilters(self.tr("All Files (*)"))
+        
         self.encodingComboBox.addItems(sorted(supportedCodecs))
         self.encodingModeComboBox.addItems(["strict", "ignore", "replace"])
         
         self.installButton.setEnabled(not self.__mercurialInstalled())
         
         # set initial values
+        # executable override
+        self.hgPicker.setText(
+            self.__plugin.getPreferences("MercurialExecutablePath"))
+        
         # global options
         index = self.encodingComboBox.findText(
             self.__plugin.getPreferences("Encoding"))
@@ -83,6 +97,9 @@
         """
         Public slot to save the Mercurial configuration.
         """
+        # executable override
+        self.__plugin.setPreferences(
+            "MercurialExecutablePath", self.hgPicker.text())
         # global options
         self.__plugin.setPreferences(
             "Encoding", self.encodingComboBox.currentText())
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/ConfigurationPage/MercurialPage.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -7,10 +7,10 @@
     <x>0</x>
     <y>0</y>
     <width>609</width>
-    <height>911</height>
+    <height>935</height>
    </rect>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
     <widget class="QLabel" name="headerLabel">
      <property name="text">
@@ -32,6 +32,44 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Mercurial Executable</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <widget class="QLabel" name="label_2">
+        <property name="text">
+         <string>Enter the path of the Mercurial executable (hg or hg.exe) to override the automatism.</string>
+        </property>
+        <property name="wordWrap">
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="EricPathPicker" name="hgPicker" native="true">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="focusPolicy">
+         <enum>Qt::StrongFocus</enum>
+        </property>
+        <property name="toolTip">
+         <string/>
+        </property>
+        <property name="whatsThis">
+         <string/>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <widget class="QGroupBox" name="groupBox_8">
      <property name="title">
       <string>Global Options</string>
@@ -350,7 +388,16 @@
    </item>
   </layout>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>EricPathPicker</class>
+   <extends>QWidget</extends>
+   <header>EricWidgets/EricPathPicker.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <tabstops>
+  <tabstop>hgPicker</tabstop>
   <tabstop>encodingComboBox</tabstop>
   <tabstop>encodingModeComboBox</tabstop>
   <tabstop>hiddenChangesetsCheckBox</tabstop>
@@ -364,6 +411,7 @@
   <tabstop>backupCheckBox</tabstop>
   <tabstop>cleanupPatternEdit</tabstop>
   <tabstop>configButton</tabstop>
+  <tabstop>installButton</tabstop>
  </tabstops>
  <resources/>
  <connections/>
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/HgLogBrowserDialog.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -41,9 +41,18 @@
      </item>
      <item>
       <widget class="QComboBox" name="modeComboBox">
+       <property name="minimumSize">
+        <size>
+         <width>100</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="toolTip">
         <string>Select the mode (find or filter)</string>
        </property>
+       <property name="sizeAdjustPolicy">
+        <enum>QComboBox::AdjustToContents</enum>
+       </property>
       </widget>
      </item>
      <item>
@@ -115,6 +124,12 @@
      </item>
      <item>
       <widget class="QComboBox" name="branchCombo">
+       <property name="minimumSize">
+        <size>
+         <width>100</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="toolTip">
         <string>Select the branch to filter on</string>
        </property>
@@ -138,9 +153,18 @@
      </item>
      <item>
       <widget class="QComboBox" name="fieldCombo">
+       <property name="minimumSize">
+        <size>
+         <width>100</width>
+         <height>0</height>
+        </size>
+       </property>
        <property name="toolTip">
         <string>Select the field to filter on</string>
        </property>
+       <property name="sizeAdjustPolicy">
+        <enum>QComboBox::AdjustToContents</enum>
+       </property>
       </widget>
      </item>
      <item>
--- a/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/VcsPlugins/vcsMercurial/HgUtilities.py	Wed Jun 01 13:48:49 2022 +0200
@@ -24,19 +24,22 @@
     @return path of the Mercurial executable
     @rtype str
     """
-    exe = ""
-    program = "hg"
-    if isWindowsPlatform():
-        program += ".exe"
-        dirName = os.path.dirname(sys.executable)
-        if os.path.exists(os.path.join(dirName, program)):
-            exe = os.path.join(dirName, program)
-        elif os.path.exists(os.path.join(dirName, "Scripts", program)):
-            exe = os.path.join(dirName, "Scripts", program)
-    else:
-        dirName = os.path.dirname(sys.executable)
-        if os.path.exists(os.path.join(dirName, program)):
-            exe = os.path.join(dirName, program)
+    from Plugins.PluginVcsMercurial import VcsMercurialPlugin
+    
+    exe = VcsMercurialPlugin.getPreferences("MercurialExecutablePath")
+    if not exe:
+        program = "hg"
+        if isWindowsPlatform():
+            program += ".exe"
+            dirName = os.path.dirname(sys.executable)
+            if os.path.exists(os.path.join(dirName, program)):
+                exe = os.path.join(dirName, program)
+            elif os.path.exists(os.path.join(dirName, "Scripts", program)):
+                exe = os.path.join(dirName, "Scripts", program)
+        else:
+            dirName = os.path.dirname(sys.executable)
+            if os.path.exists(os.path.join(dirName, program)):
+                exe = os.path.join(dirName, program)
     
     if not exe:
         exe = program
--- a/eric7/Plugins/WizardPlugins/EricMessageBoxWizard/EricMessageBoxWizardDialog.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/WizardPlugins/EricMessageBoxWizard/EricMessageBoxWizardDialog.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>535</width>
-    <height>681</height>
+    <width>600</width>
+    <height>851</height>
    </rect>
   </property>
   <property name="windowTitle">
--- a/eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.py	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.py	Wed Jun 01 13:48:49 2022 +0200
@@ -32,7 +32,7 @@
         super().__init__(parent)
         self.setupUi(self)
         
-        # set the validators for the double line edots
+        # set the validators for the double line edits
         self.eDoubleDefault.setValidator(
             QDoubleValidator(-2147483647, 2147483647, 99, self.eDoubleDefault))
         self.eDoubleFrom.setValidator(
@@ -40,21 +40,46 @@
         self.eDoubleTo.setValidator(
             QDoubleValidator(-2147483647, 2147483647, 99, self.eDoubleTo))
         
+        self.rText.toggled.connect(self.__typeSelectButtonToggled)
+        self.rMultiLineText.toggled.connect(self.__typeSelectButtonToggled)
+        self.rInteger.toggled.connect(self.__typeSelectButtonToggled)
+        self.rDouble.toggled.connect(self.__typeSelectButtonToggled)
+        self.rItem.toggled.connect(self.__typeSelectButtonToggled)
+        
         self.bTest = self.buttonBox.addButton(
             self.tr("Test"), QDialogButtonBox.ButtonRole.ActionRole)
         
+        # simulate a dialog type selection
+        self.__typeSelectButtonToggled(True)
+        
         msh = self.minimumSizeHint()
         self.resize(max(self.width(), msh.width()), msh.height())
-        
+    
     @pyqtSlot(bool)
-    def on_rItem_toggled(self, checked):
+    def __typeSelectButtonToggled(self, checked):
+        """
+        Private slot to modify the dialog according to the selected type.
+        
+        Note: This is a multiplexed slot. Therefore it just reacts upon a
+        positive check state (i.e. checked == True).
+        
+        @param checked flag indicating the checked state
+        @type bool
         """
-        Private slot to perform actions dependant on the item type selection.
-        
-        @param checked flag indicating the checked state (boolean)
-        """
-        self.bTest.setEnabled(not checked)
-        
+        self.bTest.setEnabled(True)
+        if checked:
+            if self.rText.isChecked():
+                self.specificsStack.setCurrentWidget(self.textPage)
+            elif self.rMultiLineText.isChecked():
+                self.specificsStack.setCurrentWidget(self.multiLineTextPage)
+            elif self.rInteger.isChecked():
+                self.specificsStack.setCurrentWidget(self.integerPage)
+            elif self.rDouble.isChecked():
+                self.specificsStack.setCurrentWidget(self.doublePage)
+            elif self.rItem.isChecked():
+                self.specificsStack.setCurrentWidget(self.itemPage)
+                self.bTest.setEnabled(False)
+    
     def on_buttonBox_clicked(self, button):
         """
         Private slot called by a button of the button box clicked.
@@ -82,6 +107,12 @@
                 self.eLabel.text(),
                 echomode,
                 self.eTextDefault.text())
+        elif self.rMultiLineText.isChecked():
+            QInputDialog.getMultiLineText(
+                None,
+                self.eCaption.text(),
+                self.eLabel.text(),
+                self.eMultiTextDefault.toPlainText())
         elif self.rInteger.isChecked():
             QInputDialog.getInt(
                 None,
@@ -154,8 +185,31 @@
             else:
                 code += 'QLineEdit.EchoMode.Password'
             if self.eTextDefault.text():
-                code += ',{0}{1}self.tr("{2}")'.format(
-                    os.linesep, istring, self.eTextDefault.text())
+                if self.cTranslateTextDefault.isChecked():
+                    code += ',{0}{1}self.tr("{2}")'.format(
+                        os.linesep, istring, self.eTextDefault.text())
+                else:
+                    code += ',{0}{1}"{2}"'.format(
+                        os.linesep, istring, self.eTextDefault.text())
+            code += '{0}){0}'.format(estring)
+        elif self.rMultiLineText.isChecked():
+            code += 'getMultiLineText({0}{1}'.format(os.linesep, istring)
+            code += '{0},{1}{2}'.format(parent, os.linesep, istring)
+            code += 'self.tr("{0}"),{1}{2}'.format(
+                self.eCaption.text(), os.linesep, istring)
+            code += 'self.tr("{0}")'.format(self.eLabel.text())
+            if self.eMultiTextDefault.toPlainText():
+                defTxt = "\\n".join(
+                    self.eMultiTextDefault.toPlainText().splitlines()
+                )
+                if self.cTranslateMultiTextDefault.isChecked():
+                    code += ',{0}{1}self.tr("{2}")'.format(
+                        os.linesep, istring,
+                        defTxt)
+                else:
+                    code += ',{0}{1}"{2}"'.format(
+                        os.linesep, istring,
+                        defTxt)
             code += '{0}){0}'.format(estring)
         elif self.rInteger.isChecked():
             code += 'getInt({0}{1}'.format(os.linesep, istring)
--- a/eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.ui	Mon May 02 15:53:05 2022 +0200
+++ b/eric7/Plugins/WizardPlugins/InputDialogWizard/InputDialogWizardDialog.ui	Wed Jun 01 13:48:49 2022 +0200
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>501</width>
-    <height>684</height>
+    <width>550</width>
+    <height>602</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -34,6 +34,13 @@
        </widget>
       </item>
       <item>
+       <widget class="QRadioButton" name="rMultiLineText">
+        <property name="text">
+         <string>Multiline Text</string>
+        </property>
+       </widget>
+      </item>
+      <item>
        <widget class="QRadioButton" name="rInteger">
         <property name="text">
          <string>Integer</string>
@@ -148,260 +155,414 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox_2">
-     <property name="title">
-      <string>Text</string>
-     </property>
-     <layout class="QVBoxLayout">
-      <item>
-       <widget class="QGroupBox" name="groupBox_3">
-        <property name="title">
-         <string>Echo Mode</string>
-        </property>
-        <layout class="QHBoxLayout">
-         <item>
-          <widget class="QRadioButton" name="rEchoNormal">
-           <property name="text">
-            <string>Normal</string>
-           </property>
-           <property name="checked">
-            <bool>true</bool>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QRadioButton" name="rEchoNoEcho">
-           <property name="text">
-            <string>No Echo</string>
-           </property>
-          </widget>
-         </item>
-         <item>
-          <widget class="QRadioButton" name="rEchoPassword">
-           <property name="text">
-            <string>Password</string>
-           </property>
-          </widget>
-         </item>
-        </layout>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLabel" name="TextLabel3">
-        <property name="text">
-         <string>Default</string>
-        </property>
-       </widget>
-      </item>
-      <item>
-       <widget class="QLineEdit" name="eTextDefault"/>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox_4">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="title">
-      <string>Integer</string>
+    <widget class="QStackedWidget" name="specificsStack">
+     <property name="currentIndex">
+      <number>0</number>
      </property>
-     <layout class="QGridLayout">
-      <item row="1" column="3">
-       <widget class="QSpinBox" name="sIntStep">
-        <property name="minimum">
-         <number>-2147483647</number>
-        </property>
-        <property name="maximum">
-         <number>2147483647</number>
-        </property>
-        <property name="value">
-         <number>1</number>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="2">
-       <widget class="QSpinBox" name="sIntTo">
-        <property name="minimum">
-         <number>-2147483647</number>
-        </property>
-        <property name="maximum">
-         <number>2147483647</number>
-        </property>
-        <property name="value">
-         <number>2147483647</number>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QSpinBox" name="sIntFrom">
-        <property name="minimum">
-         <number>-2147483647</number>
-        </property>
-        <property name="maximum">
-         <number>2147483647</number>
-        </property>
-        <property name="value">
-         <number>-2147483647</number>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QSpinBox" name="sIntDefault">
-        <property name="minimum">
-         <number>-2147483647</number>
-        </property>
-        <property name="maximum">
-         <number>2147483647</number>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="3">
-       <widget class="QLabel" name="TextLabel4_4">
-        <property name="text">
-         <string>Step</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QLabel" name="TextLabel4_3">
-        <property name="text">
-         <string>To</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="TextLabel4_2">
-        <property name="text">
-         <string>From</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QLabel" name="TextLabel4">
-        <property name="text">
-         <string>Default</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox_5">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="title">
-      <string>Double</string>
-     </property>
-     <layout class="QGridLayout">
-      <item row="1" column="3">
-       <widget class="QSpinBox" name="sDoubleDecimals">
-        <property name="minimum">
-         <number>-2147483647</number>
-        </property>
-        <property name="maximum">
-         <number>2147483647</number>
-        </property>
-        <property name="value">
-         <number>1</number>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="2">
-       <widget class="QLineEdit" name="eDoubleTo">
-        <property name="text">
-         <string>2147483647</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QLineEdit" name="eDoubleFrom">
-        <property name="text">
-         <string>-2147483647</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLineEdit" name="eDoubleDefault">
-        <property name="text">
-         <string>0</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QLabel" name="TextLabel5">
-        <property name="text">
-         <string>Default</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="TextLabel6">
-        <property name="text">
-         <string>From</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="2">
-       <widget class="QLabel" name="TextLabel7">
-        <property name="text">
-         <string>To</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="3">
-       <widget class="QLabel" name="TextLabel8">
-        <property name="text">
-         <string>Decimals</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="groupBox_6">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
-     <property name="title">
-      <string>Item</string>
-     </property>
-     <layout class="QGridLayout">
-      <item row="1" column="2">
-       <widget class="QCheckBox" name="cEditable">
-        <property name="text">
-         <string>Editable</string>
-        </property>
-        <property name="checked">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QSpinBox" name="sCurrentItem"/>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLineEdit" name="eVariable"/>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="TextLabel10">
-        <property name="text">
-         <string>Current Item</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="0">
-       <widget class="QLabel" name="TextLabel9">
-        <property name="text">
-         <string>String List Variable</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
+     <widget class="QWidget" name="textPage">
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QGroupBox" name="groupBox_2">
+         <property name="title">
+          <string>Text</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_2">
+          <item>
+           <widget class="QGroupBox" name="groupBox_3">
+            <property name="title">
+             <string>Echo Mode</string>
+            </property>
+            <layout class="QHBoxLayout">
+             <item>
+              <widget class="QRadioButton" name="rEchoNormal">
+               <property name="text">
+                <string>Normal</string>
+               </property>
+               <property name="checked">
+                <bool>true</bool>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QRadioButton" name="rEchoNoEcho">
+               <property name="text">
+                <string>No Echo</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <widget class="QRadioButton" name="rEchoPassword">
+               <property name="text">
+                <string>Password</string>
+               </property>
+              </widget>
+             </item>
+            </layout>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLabel" name="TextLabel3">
+            <property name="text">
+             <string>Default</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QLineEdit" name="eTextDefault"/>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="cTranslateTextDefault">
+            <property name="text">
+             <string>Translate Default</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="multiLineTextPage">
+      <layout class="QVBoxLayout" name="verticalLayout_8">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QGroupBox" name="groupBox_7">
+         <property name="title">
+          <string>Multiline Text</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_7">
+          <item>
+           <widget class="QLabel" name="TextLabel3_2">
+            <property name="text">
+             <string>Default</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QPlainTextEdit" name="eMultiTextDefault">
+            <property name="tabChangesFocus">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QCheckBox" name="cTranslateMultiTextDefault">
+            <property name="text">
+             <string>Translate Default</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="integerPage">
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QGroupBox" name="groupBox_4">
+         <property name="title">
+          <string>Integer</string>
+         </property>
+         <layout class="QGridLayout">
+          <item row="1" column="3">
+           <widget class="QSpinBox" name="sIntStep">
+            <property name="minimum">
+             <number>-2147483647</number>
+            </property>
+            <property name="maximum">
+             <number>2147483647</number>
+            </property>
+            <property name="value">
+             <number>1</number>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="2">
+           <widget class="QSpinBox" name="sIntTo">
+            <property name="minimum">
+             <number>-2147483647</number>
+            </property>
+            <property name="maximum">
+             <number>2147483647</number>
+            </property>
+            <property name="value">
+             <number>2147483647</number>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QSpinBox" name="sIntFrom">
+            <property name="minimum">
+             <number>-2147483647</number>
+            </property>
+            <property name="maximum">
+             <number>2147483647</number>
+            </property>
+            <property name="value">
+             <number>-2147483647</number>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QSpinBox" name="sIntDefault">
+            <property name="minimum">
+             <number>-2147483647</number>
+            </property>
+            <property name="maximum">
+             <number>2147483647</number>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="3">
+           <widget class="QLabel" name="TextLabel4_4">
+            <property name="text">
+             <string>Step</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QLabel" name="TextLabel4_3">
+            <property name="text">
+             <string>To</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLabel" name="TextLabel4_2">
+            <property name="text">
+             <string>From</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="TextLabel4">
+            <property name="text">
+             <string>Default</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>95</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="doublePage">
+      <layout class="QVBoxLayout" name="verticalLayout_5">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>
+       <property name="bottomMargin">
+        <number>0</number>
+       </property>
+       <item>
+        <widget class="QGroupBox" name="groupBox_5">
+         <property name="title">
+          <string>Double</string>
+         </property>
+         <layout class="QGridLayout">
+          <item row="1" column="3">
+           <widget class="QSpinBox" name="sDoubleDecimals">
+            <property name="minimum">
+             <number>-2147483647</number>
+            </property>
+            <property name="maximum">
+             <number>2147483647</number>
+            </property>
+            <property name="value">
+             <number>1</number>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="2">
+           <widget class="QLineEdit" name="eDoubleTo">
+            <property name="text">
+             <string>2147483647</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="1">
+           <widget class="QLineEdit" name="eDoubleFrom">
+            <property name="text">
+             <string>-2147483647</string>
+            </property>
+           </widget>
+          </item>
+          <item row="1" column="0">
+           <widget class="QLineEdit" name="eDoubleDefault">
+            <property name="text">
+             <string>0</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="TextLabel5">
+            <property name="text">
+             <string>Default</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="1">
+           <widget class="QLabel" name="TextLabel6">
+            <property name="text">
+             <string>From</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="2">
+           <widget class="QLabel" name="TextLabel7">
+            <property name="text">
+             <string>To</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="3">
+           <widget class="QLabel" name="TextLabel8">
+            <property name="text">
+             <string>Decimals</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>95</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="itemPage">
+      <layout class="QVBoxLayout" name="verticalLayout_6">
+       <property name="leftMargin">
+        <number>0</number>
+       </property>
+       <property name="topMargin">
+        <number>0</number>
+       </property>
+       <property name="rightMargin">
+        <number>0</number>
+       </property>