--- a/src/eric7/Testing/Interfaces/UnittestRunner.py Sun Dec 03 14:54:00 2023 +0100 +++ b/src/eric7/Testing/Interfaces/UnittestRunner.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> # """ @@ -8,6 +8,7 @@ """ import importlib +import importlib.util import json import os import sys @@ -246,21 +247,23 @@ ) -def _assembleTestCasesList(suite): +def _assembleTestCasesList(suite, start): """ Protected function to assemble a list of test cases included in a test suite. @param suite test suite to be inspected @type unittest.TestSuite - @return list of tuples containing the test case ID, the string - representation and the short description - @rtype list of tuples of (str, str) + @param start name of directory discovery was started at + @type str + @return list of tuples containing the test case ID, the string representation, + a short description and the path of the test file name + @rtype list of tuples of (str, str, str, str) """ testCases = [] for test in suite: if isinstance(test, unittest.TestSuite): - testCases.extend(_assembleTestCasesList(test)) + testCases.extend(_assembleTestCasesList(test, start)) else: testId = test.id() if ( @@ -268,16 +271,22 @@ and "LoadTestsFailure" not in testId and "_FailedTest" not in testId ): - testCases.append((testId, str(test), test.shortDescription())) + filename = os.path.join( + start, test.__module__.replace(".", os.sep) + ".py" + ) + testCases.append((testId, str(test), test.shortDescription(), filename)) return testCases -def runtest(argv): +def runtest(argv, discoverOnly=False): """ - Function to run the tests. + Function to run and/or discover the tests. @param argv list of command line parameters. @type list of str + @param discoverOnly flag indicating to just discover the available test cases + (defaults to False) + @type bool (optional) """ from eric7.EricNetwork.EricJsonStreamWriter import EricJsonWriter @@ -330,12 +339,11 @@ failed = [] if discover: testFileName = testName = "" + testCases = argv[:] else: testFileName, testName = argv[:2] del argv[:2] - testCases = argv[:] - if testFileName: sys.path.insert(1, os.path.dirname(os.path.abspath(testFileName))) elif discoveryStart: @@ -362,12 +370,15 @@ ) ), ) - from coverage import Coverage # __IGNORE_WARNING_I10__ + try: + from coverage import Coverage # __IGNORE_WARNING_I10__ - cover = Coverage(data_file=covDataFile) - if coverageErase: - cover.erase() - cover.start() + cover = Coverage(data_file=covDataFile) + if coverageErase: + cover.erase() + cover.start() + except ImportError: + cover = None else: cover = None @@ -411,31 +422,32 @@ collectedTests = { "event": "collected", "tests": [ - {"id": id, "name": name, "description": desc} - for id, name, desc in _assembleTestCasesList(test) + {"id": id, "name": name, "description": desc, "filename": filename} + for id, name, desc, filename in _assembleTestCasesList(test, discoveryStart) ], } writer.write(collectedTests) - testResult = EricTestResult(writer, failfast) - startTestRun = getattr(testResult, "startTestRun", None) - if startTestRun is not None: - startTestRun() - try: - test.run(testResult) - finally: - if cover: - cover.stop() - cover.save() - writer.write( - { - "event": "coverage", - "file": covDataFile, - } - ) - stopTestRun = getattr(testResult, "stopTestRun", None) - if stopTestRun is not None: - stopTestRun() + if not discoverOnly: + testResult = EricTestResult(writer, failfast) + startTestRun = getattr(testResult, "startTestRun", None) + if startTestRun is not None: + startTestRun() + try: + test.run(testResult) + finally: + if cover: + cover.stop() + cover.save() + writer.write( + { + "event": "coverage", + "file": covDataFile, + } + ) + stopTestRun = getattr(testResult, "stopTestRun", None) + if stopTestRun is not None: + stopTestRun() writer.close() sys.exit(0) @@ -458,10 +470,22 @@ print(json.dumps(versions)) sys.exit(0) + elif command == "has_coverage": + if importlib.util.find_spec("coverage") is None: + # not available + sys.exit(1) + else: + # available + sys.exit(0) + elif command == "runtest": runtest(sys.argv[2:]) sys.exit(0) + elif command == "discovery": + runtest(sys.argv[2:], discoverOnly=True) + sys.exit(0) + sys.exit(42) #