From bca61126ba5482c162502e1fd8d88625964a0916 Mon Sep 17 00:00:00 2001 From: Jan Wille Date: Sun, 16 Feb 2025 23:02:12 +0100 Subject: [PATCH] Add more CLI tests (#152) --- junitparser/cli.py | 55 ++++++++--------- tests/data/pytest_error.xml | 8 +++ tests/data/pytest_success.xml | 6 ++ tests/test_cli.py | 107 ++++++++++++++++++++++++++++++++-- 4 files changed, 138 insertions(+), 38 deletions(-) create mode 100644 tests/data/pytest_error.xml create mode 100644 tests/data/pytest_success.xml diff --git a/junitparser/cli.py b/junitparser/cli.py index da5f7d2..0695a93 100644 --- a/junitparser/cli.py +++ b/junitparser/cli.py @@ -6,8 +6,8 @@ from . import JUnitXml, version -def merge(paths, output, suite_name): - """Merge XML report.""" +def merge(paths, output, suite_name=""): + """Merge XML reports.""" result = JUnitXml() for path in paths: result += JUnitXml.fromfile(path) @@ -44,18 +44,23 @@ def _parser(prog_name=None): # pragma: no cover command_parser = parser.add_subparsers(dest="command", help="command") command_parser.required = True - # command: merge - merge_parser = command_parser.add_parser( - "merge", help="Merge JUnit XML format reports with junitparser." - ) - merge_parser.add_argument( + # an abstract object that defines common arguments used by multiple commands + abstract_parser = ArgumentParser(add_help=False) + abstract_parser.add_argument( "--glob", help="Treat original XML path(s) as glob(s).", dest="paths_are_globs", action="store_true", default=False, ) - merge_parser.add_argument("paths", nargs="+", help="Original XML path(s).") + abstract_parser.add_argument("paths", help="Original XML path(s).", nargs="+") + + # command: merge + merge_parser = command_parser.add_parser( + "merge", + help="Merge JUnit XML format reports with junitparser.", + parents=[abstract_parser], + ) merge_parser.add_argument( "output", help='Merged XML Path, setting to "-" will output to the console' ) @@ -65,19 +70,10 @@ def _parser(prog_name=None): # pragma: no cover ) # command: verify - merge_parser = command_parser.add_parser( + verify_parser = command_parser.add_parser( # noqa: F841 "verify", help="Return a non-zero exit code if one of the testcases failed or errored.", - ) - merge_parser.add_argument( - "--glob", - help="Treat original XML path(s) as glob(s).", - dest="paths_are_globs", - action="store_true", - default=False, - ) - merge_parser.add_argument( - "paths", nargs="+", help="XML path(s) of reports to verify." + parents=[abstract_parser], ) return parser @@ -85,19 +81,14 @@ def _parser(prog_name=None): # pragma: no cover def main(args=None, prog_name=None): """CLI's main runner.""" - args = args or _parser(prog_name=prog_name).parse_args() + args = _parser(prog_name=prog_name).parse_args(args) + paths = ( + chain.from_iterable(iglob(path) for path in args.paths) + if args.paths_are_globs + else args.paths + ) if args.command == "merge": - return merge( - chain.from_iterable(iglob(path) for path in args.paths) - if args.paths_are_globs - else args.paths, - args.output, - args.suite_name, - ) + return merge(paths, args.output, args.suite_name) if args.command == "verify": - return verify( - chain.from_iterable(iglob(path) for path in args.paths) - if args.paths_are_globs - else args.paths - ) + return verify(paths) return 255 diff --git a/tests/data/pytest_error.xml b/tests/data/pytest_error.xml new file mode 100644 index 0000000..a3b9eef --- /dev/null +++ b/tests/data/pytest_error.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/data/pytest_success.xml b/tests/data/pytest_success.xml new file mode 100644 index 0000000..8e15e4d --- /dev/null +++ b/tests/data/pytest_success.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/tests/test_cli.py b/tests/test_cli.py index 3b2553d..89e8f91 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1,12 +1,107 @@ -import os +from pathlib import Path import pytest -from junitparser.cli import verify +from junitparser import cli +from junitparser import version + +DATA_DIR = Path(__file__).parent / "data" @pytest.mark.parametrize( "file, expected_exitcode", - [("data/jenkins.xml", 1), ("data/no_fails.xml", 0), ("data/normal.xml", 1)], + [("jenkins.xml", 1), ("no_fails.xml", 0), ("normal.xml", 1)], ) -def test_verify(file, expected_exitcode): - path = os.path.join(os.path.dirname(__file__), file) - assert verify([path]) == expected_exitcode +def test_verify(file: str, expected_exitcode: int): + path = DATA_DIR / file + assert cli.verify([path]) == expected_exitcode + + +def test_merge(tmp_path: Path): + files = [DATA_DIR / "jenkins.xml", DATA_DIR / "pytest_success.xml"] + suites = ["JUnitXmlReporter", "JUnitXmlReporter.constructor", "pytest"] + outfile = tmp_path / "merged.xml" + cli.merge(files, str(outfile)) + xml = outfile.read_text() + for s in suites: + assert f'name="{s}"' in xml + + +def test_merge_output_to_terminal(capsys: pytest.CaptureFixture): + ret = cli.main(["merge", str(DATA_DIR / "normal.xml"), "-"]) + assert ret == 0 + captured = capsys.readouterr() + assert captured.out.startswith("