diff -r 411df92e881f -r 3b34efa2857c src/eric7/Testing/Interfaces/PytestExecutor.py --- a/src/eric7/Testing/Interfaces/PytestExecutor.py Sun Dec 03 14:54:00 2023 +0100 +++ b/src/eric7/Testing/Interfaces/PytestExecutor.py Mon Jan 01 11:10:45 2024 +0100 @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# Copyright (c) 2022 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> +# Copyright (c) 2022 - 2024 Detlev Offenbach <detlev@die-offenbachs.de> # """ @@ -73,8 +73,7 @@ def hasCoverage(self, interpreter): """ - Public method to get the test framework version and version information - of its installed plugins. + Public method to check, if the collection of coverage data is available. @param interpreter interpreter to be used for the test @type str @@ -167,7 +166,7 @@ else: args.append("--cache-clear") - if config.collectCoverage: + if not config.discoverOnly and config.collectCoverage: args.extend(["--cov=.", "--cov-report="]) if not config.eraseCoverage: args.append("--cov-append") @@ -180,7 +179,12 @@ args.append("-k") args.append(config.testNamePattern) - if config.testFilename: + if config.discoverOnly: + args.append("--collect-only") + + if config.testCases: + args.extend(config.testCases) + elif config.testFilename: if config.testName: args.append( "{0}::{1}".format( @@ -192,6 +196,25 @@ return args + def discover(self, config, pythonpath): + """ + Public method to start the test discovery process. + + @param config configuration for the test discovery + @type TestConfig + @param pythonpath list of directories to be added to the Python path + @type list of str + """ + self.reader = EricJsonReader(name="Pytest Reader", parent=self) + self.reader.dataReceived.connect(self.__processData) + + self.__config = config + + pythonpath.insert(0, os.path.abspath(config.discoveryStart)) + self.__rootdir = config.discoveryStart + + super().discover(config, pythonpath) + def start(self, config, pythonpath): """ Public method to start the testing process. @@ -220,6 +243,36 @@ super().start(config, pythonpath) + def startDebug(self, config, pythonpath, debugger): + """ + Public method to start the test run with debugger support. + + @param config configuration for the test execution + @type TestConfig + @param pythonpath list of directories to be added to the Python path + @type list of str + @param debugger refference to the debugger interface + @type DebugUI + """ + self.reader = EricJsonReader(name="Pytest Reader", parent=self) + self.reader.dataReceived.connect(self.__processData) + + self.__config = config + + if config.discoveryStart: + pythonpath.insert(0, os.path.abspath(config.discoveryStart)) + elif config.testFilename: + pythonpath.insert(0, os.path.abspath(os.path.dirname(config.testFilename))) + + if config.discover: + self.__rootdir = config.discoveryStart + elif config.testFilename: + self.__rootdir = os.path.dirname(config.testFilename) + else: + self.__rootdir = "" + + super().startDebug(config, pythonpath, debugger) + def finished(self): """ Public method handling the unit test process been finished. @@ -237,6 +290,8 @@ output = self.readAllOutput() self.testFinished.emit([], output) + super().finished() + @pyqtSlot(object) def __processData(self, data): """ @@ -257,7 +312,16 @@ # tests collected elif data["event"] == "collected": self.collected.emit( - [(data["nodeid"], self.__nodeid2testname(data["nodeid"]), "")] + [ + ( + data["nodeid"], + self.__nodeid2testname(data["nodeid"]), + "", + os.path.join(self.__rootdir, data["filename"]), + data["linenumber"], + self.__nodeid2testpath(data["nodeid"]), + ) + ] ) # test started @@ -360,3 +424,17 @@ name = name.replace("::", ".") testname, name = "{0}.{1}".format(module, name).rsplit(".", 1) return "{0} ({1})".format(name, testname) + + def __nodeid2testpath(self, nodeid): + """ + Private method to convert a nodeid to a test path list. + + @param nodeid nodeid to be converted + @type str + @return test path list + @rtype list of str + """ + module, name = nodeid.split("::", 1) + module = self.__normalizeModuleName(module) + name = "{0}.{1}".format(module, name.replace("::", ".")) + return name.split(".")