NLProxy / nlproxy /cli /tests.py
Luiserb's picture
first commit
2129c29
Raw
History Blame Contribute Delete
3.27 kB
"""
NLProxy SDK test runner CLI.
This command runs the SDK test suite using pytest and supports class-level
and flow/marker-based filtering so tests can be executed in a scalable,
reproducible way.
Examples:
python -m nlproxy tests
python -m nlproxy tests --class TestPromptShield
python -m nlproxy tests --flow unit
python -m nlproxy tests --flow integration --pytest-args="-v --maxfail=1"
The runner defaults to `tests.py` in the project root and delegates to the
Python interpreter environment that executes the CLI.
"""
from __future__ import annotations
import argparse
import shlex
import subprocess
import sys
from typing import List, Optional
def create_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="nlproxy tests",
description="Run NLProxy SDK tests with optional class or flow filtering.",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python -m nlproxy tests
python -m nlproxy tests --class TestPromptShield
python -m nlproxy tests --flow unit
python -m nlproxy tests --flow integration --pytest-args='-v --maxfail=1'
""",
)
parser.add_argument(
"-c",
"--class",
dest="test_class",
help="Run only a single test class or filter expression from tests.py",
)
parser.add_argument(
"-f",
"--flow",
dest="flow",
help="Run tests by pytest marker/flow name (e.g. unit, integration, performance, asyncio)",
)
parser.add_argument(
"--path",
type=str,
default="tests.py",
help="Path to the test module or directory to execute",
)
parser.add_argument(
"--pytest-args",
type=str,
default="",
help="Additional pytest arguments to pass through",
)
parser.add_argument(
"-q",
"--quiet",
action="store_true",
help="Suppress output from the test runner when possible",
)
return parser
def build_pytest_args(args: argparse.Namespace) -> List[str]:
pytest_args: List[str] = [sys.executable, "-m", "pytest", args.path]
if args.test_class:
pytest_args.extend(["-k", args.test_class])
if args.flow:
pytest_args.extend(["-m", args.flow])
if args.pytest_args:
pytest_args.extend(shlex.split(args.pytest_args))
if args.quiet:
pytest_args.append("-q")
return pytest_args
def cmd_tests(args: argparse.Namespace) -> int:
pytest_args = build_pytest_args(args)
print(f"Running tests: {' '.join(pytest_args)}")
result = subprocess.run(pytest_args, env=sys.environ.copy())
return result.returncode
def main(argv: Optional[List[str]] = None) -> int:
parser = create_parser()
args = parser.parse_args(argv)
try:
return cmd_tests(args)
except KeyboardInterrupt:
print("Test execution interrupted by user.", file=sys.stderr)
return 130
except FileNotFoundError as exc:
print(f"Test runner failed: {exc}", file=sys.stderr)
return 1
except Exception as exc:
print(f"Unexpected error while running tests: {exc}", file=sys.stderr)
return 1
if __name__ == "__main__":
raise SystemExit(main())