fix: propagate exit code (#108)
* fix(pytest): propagate exit code * feat: derive exit code for unittest
This commit is contained in:
committed by
Itai Bohadana
parent
7d7cacb91a
commit
b720009f3e
+1
-1
@@ -17,4 +17,4 @@ with add_to_path():
|
||||
from neotest_python import main
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
|
||||
@@ -50,20 +50,18 @@ parser.add_argument(
|
||||
parser.add_argument("args", nargs="*")
|
||||
|
||||
|
||||
def main(argv: List[str]):
|
||||
def main(argv: List[str]) -> int:
|
||||
if "--pytest-collect" in argv:
|
||||
argv.remove("--pytest-collect")
|
||||
from .pytest_ import collect
|
||||
|
||||
collect(argv)
|
||||
return
|
||||
return collect(argv)
|
||||
|
||||
if "--pytest-extract-test-name-template" in argv:
|
||||
argv.remove("--pytest-extract-test-name-template")
|
||||
from .pytest_ import extract_test_name_template
|
||||
|
||||
extract_test_name_template(argv)
|
||||
return
|
||||
return extract_test_name_template(argv)
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
adapter = get_adapter(TestRunner(args.runner), args.emit_parameterized_ids)
|
||||
@@ -74,7 +72,9 @@ def main(argv: List[str]):
|
||||
stream_file.write(json.dumps({"id": pos_id, "result": result}) + "\n")
|
||||
stream_file.flush()
|
||||
|
||||
results = adapter.run(args.args, stream)
|
||||
results, exit_code = adapter.run(args.args, stream)
|
||||
|
||||
with open(args.results_file, "w") as results_file:
|
||||
json.dump(results, results_file)
|
||||
|
||||
return exit_code
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import abc
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, Callable, Dict, List, Optional
|
||||
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
class NeotestResultStatus(str, Enum):
|
||||
@@ -43,6 +43,6 @@ class NeotestAdapter(abc.ABC):
|
||||
}
|
||||
|
||||
@abc.abstractmethod
|
||||
def run(self, args: List[str], stream: Callable):
|
||||
def run(self, args: List[str], stream: Callable) -> Tuple[Dict, int]:
|
||||
del args, stream
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -55,7 +55,7 @@ class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
|
||||
relative_dotted = relative_stem.replace(os.sep, ".")
|
||||
return [*args, ".".join([relative_dotted, *child_ids])]
|
||||
|
||||
def run(self, args: List[str], _) -> Dict:
|
||||
def run(self, args: List[str], _) -> Tuple[Dict, int]:
|
||||
errs: Dict[str, Tuple[Exception, Any, TracebackType]] = {}
|
||||
results = {}
|
||||
|
||||
@@ -146,5 +146,6 @@ class DjangoNeotestAdapter(CaseUtilsMixin, NeotestAdapter):
|
||||
runner = DjangoUnittestRunner(
|
||||
**vars(parser.parse_args(argv[1:-1])) # parse plugin config args
|
||||
)
|
||||
runner.run_tests(test_labels=[argv[-1]]) # pass test label
|
||||
return results
|
||||
failures = runner.run_tests(test_labels=[argv[-1]]) # pass test label
|
||||
exit_code = 0 if failures == 0 else 1
|
||||
return results, exit_code
|
||||
|
||||
@@ -4,7 +4,7 @@ from typing import Callable, Dict, List, Optional, Union
|
||||
from . import params_getter
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
from typing import Callable, Dict, Generator, List, Optional, Union
|
||||
from typing import Callable, Dict, Generator, List, Optional, Tuple, Union
|
||||
|
||||
import pytest
|
||||
from _pytest._code.code import ExceptionRepr
|
||||
@@ -24,18 +24,18 @@ class PytestNeotestAdapter(NeotestAdapter):
|
||||
self,
|
||||
args: List[str],
|
||||
stream: Callable[[str, NeotestResult], None],
|
||||
) -> Dict[str, NeotestResult]:
|
||||
) -> Tuple[Dict[str, NeotestResult], int]:
|
||||
result_collector = NeotestResultCollector(
|
||||
self, stream=stream, emit_parameterized_ids=self.emit_parameterized_ids
|
||||
)
|
||||
pytest.main(
|
||||
exit_code = pytest.main(
|
||||
args=args,
|
||||
plugins=[
|
||||
result_collector,
|
||||
NeotestDebugpyPlugin(),
|
||||
],
|
||||
)
|
||||
return result_collector.results
|
||||
return result_collector.results, int(exit_code)
|
||||
|
||||
|
||||
class NeotestResultCollector:
|
||||
|
||||
@@ -45,7 +45,7 @@ class UnittestNeotestAdapter(NeotestAdapter):
|
||||
return [*args, ".".join([relative_dotted, *child_ids])]
|
||||
|
||||
# TODO: Stream results
|
||||
def run(self, args: List[str], _) -> Dict:
|
||||
def run(self, args: List[str], _) -> Tuple[Dict, int]:
|
||||
results = {}
|
||||
|
||||
errs: Dict[str, Tuple[Exception, Any, TracebackType]] = {}
|
||||
@@ -96,11 +96,11 @@ class UnittestNeotestAdapter(NeotestAdapter):
|
||||
|
||||
# Prepend an executable name which is just used in output
|
||||
argv = ["neotest-python"] + self.convert_args(args[-1], args[:-1])
|
||||
unittest.main(
|
||||
program = unittest.main(
|
||||
module=None,
|
||||
argv=argv,
|
||||
testRunner=NeotestUnittestRunner(resultclass=NeotestTextTestResult),
|
||||
exit=False,
|
||||
)
|
||||
|
||||
return results
|
||||
exit_code = 0 if program.result.wasSuccessful() else 1
|
||||
return results, exit_code
|
||||
|
||||
Reference in New Issue
Block a user